$method_info) { if (in_array($method_name, self::LIFECYCLE_METHODS, true)) { // This lifecycle method is not static - violation! // Find the line number by searching for the method definition $line_number = $this->find_method_line($contents, $method_name); $code_line = $this->extract_code_line($contents, $line_number); $this->add_violation( $file_path, $line_number, "RSX lifecycle method '{$method_name}' must be declared as static", $code_line, $this->get_remediation($method_name, $class_name, $code_line), 'high' ); } } } } /** * Find the line number where a method is defined */ private function find_method_line(string $contents, string $method_name): int { $lines = explode("\n", $contents); foreach ($lines as $line_num => $line) { // Look for method definition (with or without async) if (preg_match('/\b(async\s+)?' . preg_quote($method_name, '/') . '\s*\(/', $line)) { return $line_num + 1; } } return 1; // Default to line 1 if not found } /** * Extract code line for a given line number */ private function extract_code_line(string $contents, int $line_number): string { $lines = explode("\n", $contents); if (isset($lines[$line_number - 1])) { return trim($lines[$line_number - 1]); } return ''; } /** * Get remediation instructions for non-static lifecycle method */ private function get_remediation(string $method, ?string $class_name, string $current_line): string { $is_async = strpos($current_line, 'async') !== false; $static_version = $is_async ? "static async {$method}()" : "static {$method}()"; $class_info = $class_name ? " in class {$class_name}" : ""; $phase_description = $this->get_phase_description($method); return "FRAMEWORK CONVENTION: RSX lifecycle method '{$method}'{$class_info} must be static. PROBLEM: The method is currently defined as an instance method, but the RSX framework calls these methods statically during application initialization. SOLUTION: Change the method declaration to: {$static_version} CURRENT (INCORRECT): {$current_line} CORRECTED: {$static_version} { // Your initialization code here } WHY THIS MATTERS: - The RSX framework calls lifecycle methods statically on classes - Instance methods cannot be called without instantiating the class - The framework does not instantiate classes during initialization - Using instance methods will cause the initialization to fail silently LIFECYCLE PHASE: This method runs during: {$phase_description} ALL RSX LIFECYCLE METHODS (must be static): - _on_framework_core_define() - Framework core modules define phase - _on_framework_modules_define() - Framework extension modules define - _on_framework_core_init() - Framework core initialization - on_app_modules_define() - Application modules define phase - on_app_define() - Application-wide define phase - _on_framework_modules_init() - Framework modules initialization - on_app_modules_init() - Application modules initialization - on_app_init() - Application initialization - on_app_ready() - Application ready (DOM loaded, components initialized) Methods prefixed with underscore (_) are internal framework methods. Application code should typically only use the non-underscore methods."; } /** * Get description of when this lifecycle phase runs */ private function get_phase_description(string $method): string { $descriptions = [ '_on_framework_core_define' => 'Framework core module definition (internal)', '_on_framework_modules_define' => 'Framework extension module definition (internal)', '_on_framework_core_init' => 'Framework core initialization (internal)', 'on_app_modules_define' => 'Application module definition phase', 'on_app_define' => 'Application-wide definition phase', '_on_framework_modules_init' => 'Framework module initialization (internal)', 'on_app_modules_init' => 'Application module initialization', 'on_app_init' => 'Application initialization', 'on_app_ready' => 'Application ready - DOM loaded, components initialized', ]; return $descriptions[$method] ?? 'Unknown phase'; } }