Add skills documentation and misc updates
Add form value persistence across cache revalidation re-renders 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\RSpade\CodeQuality\Rules\JavaScript;
|
||||
use App\RSpade\CodeQuality\Rules\CodeQualityRule_Abstract;
|
||||
use App\RSpade\CodeQuality\RuntimeChecks\YoureDoingItWrongException;
|
||||
use App\RSpade\Core\Cache\RsxCache;
|
||||
use App\RSpade\Core\Manifest\Manifest;
|
||||
|
||||
/**
|
||||
* Check Component implementations for common AI agent mistakes
|
||||
@@ -47,8 +48,26 @@ class JqhtmlComponentImplementation_CodeQualityRule extends CodeQualityRule_Abst
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if not a Component subclass
|
||||
if (!isset($metadata['extends']) || $metadata['extends'] !== 'Component') {
|
||||
// Skip if no class defined
|
||||
if (!isset($metadata['class'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is a Component subclass (directly or indirectly)
|
||||
$is_component_subclass = false;
|
||||
if (isset($metadata['extends']) && $metadata['extends'] === 'Component') {
|
||||
$is_component_subclass = true;
|
||||
} elseif (isset($metadata['extends'])) {
|
||||
// Check inheritance chain via manifest
|
||||
try {
|
||||
$is_component_subclass = Manifest::js_is_subclass_of($metadata['class'], 'Component');
|
||||
} catch (\Exception $e) {
|
||||
// Manifest not ready or class not found - skip
|
||||
$is_component_subclass = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_component_subclass) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,6 +78,16 @@ class JqhtmlComponentImplementation_CodeQualityRule extends CodeQualityRule_Abst
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for on_destroy method using manifest metadata (the correct method is on_stop)
|
||||
if (!empty($metadata['public_instance_methods'])) {
|
||||
foreach ($metadata['public_instance_methods'] as $method_name => $method_info) {
|
||||
if ($method_name === 'on_destroy') {
|
||||
$line = $method_info['line'] ?? 1;
|
||||
$this->throw_on_destroy_error($file_path, $line, $metadata['class']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$lines = explode("\n", $contents);
|
||||
|
||||
// Check for render() method and incorrect lifecycle methods
|
||||
@@ -151,11 +180,48 @@ class JqhtmlComponentImplementation_CodeQualityRule extends CodeQualityRule_Abst
|
||||
$error_message .= "- on_create(): Called when component is created\n";
|
||||
$error_message .= "- on_load(): Called to load async data\n";
|
||||
$error_message .= "- on_ready(): Called when component is ready in DOM\n";
|
||||
$error_message .= "- on_destroy(): Called when component is destroyed\n\n";
|
||||
$error_message .= "- on_stop(): Called when component is destroyed\n\n";
|
||||
$error_message .= "FIX:\n";
|
||||
$error_message .= "Rename '{$method_name}()' to 'on_{$method_name}()'\n";
|
||||
$error_message .= "==========================================";
|
||||
|
||||
throw new YoureDoingItWrongException($error_message);
|
||||
}
|
||||
|
||||
private function throw_on_destroy_error(string $file_path, int $line_number, string $class_name): void
|
||||
{
|
||||
$error_message = "==========================================\n";
|
||||
$error_message .= "FATAL: Jqhtml component uses incorrect lifecycle method name\n";
|
||||
$error_message .= "==========================================\n\n";
|
||||
$error_message .= "File: {$file_path}\n";
|
||||
$error_message .= "Line: {$line_number}\n";
|
||||
$error_message .= "Class: {$class_name}\n\n";
|
||||
$error_message .= "The method 'on_destroy()' does not exist in jqhtml components.\n\n";
|
||||
$error_message .= "PROBLEM:\n";
|
||||
$error_message .= "The correct lifecycle method for cleanup is 'on_stop()', not 'on_destroy()'.\n";
|
||||
$error_message .= "This is a common mistake from other frameworks.\n\n";
|
||||
$error_message .= "INCORRECT:\n";
|
||||
$error_message .= " class {$class_name} extends Component {\n";
|
||||
$error_message .= " on_destroy() {\n";
|
||||
$error_message .= " // cleanup code\n";
|
||||
$error_message .= " }\n";
|
||||
$error_message .= " }\n\n";
|
||||
$error_message .= "CORRECT:\n";
|
||||
$error_message .= " class {$class_name} extends Component {\n";
|
||||
$error_message .= " on_stop() {\n";
|
||||
$error_message .= " // cleanup code\n";
|
||||
$error_message .= " }\n";
|
||||
$error_message .= " }\n\n";
|
||||
$error_message .= "LIFECYCLE METHODS:\n";
|
||||
$error_message .= "- on_create(): Called when component is created (sync)\n";
|
||||
$error_message .= "- on_render(): Called after template renders (sync)\n";
|
||||
$error_message .= "- on_load(): Called to load async data\n";
|
||||
$error_message .= "- on_ready(): Called when component is ready in DOM\n";
|
||||
$error_message .= "- on_stop(): Called when component is destroyed (sync)\n\n";
|
||||
$error_message .= "FIX:\n";
|
||||
$error_message .= "Rename 'on_destroy()' to 'on_stop()'\n";
|
||||
$error_message .= "==========================================";
|
||||
|
||||
throw new YoureDoingItWrongException($error_message);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user