feat(laravel): add Laravel framework path detection and entry point scoring

- Add Laravel route/controller/job/listener/middleware/provider/policy/model
  path patterns with appropriate multipliers (1.5–3.0)
- Add 'laravel' entry to FRAMEWORK_AST_PATTERNS for documentation
- Add PHP ENTRY_POINT_PATTERNS: RESTful methods, __invoke, handle, boot, etc.
- Add PHP/Laravel test file detection (Test.php, Spec.php, tests/feature/, tests/unit/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Güneş Bizim 2026-02-25 01:04:49 +03:00
parent 136e83e76d
commit 897d4cbfef
4 changed files with 165 additions and 3 deletions

View file

@ -102,6 +102,21 @@ const ENTRY_POINT_PATTERNS: Record<string, RegExp[]> = {
/^Run$/, // Run methods
/^Start$/, // Start methods
],
// PHP / Laravel
'php': [
/Controller$/, // UserController (class name convention)
/^handle$/, // Job::handle(), Listener::handle()
/^execute$/, // Command::execute()
/^boot$/, // ServiceProvider::boot()
/^register$/, // ServiceProvider::register()
/^__invoke$/, // Invokable controllers/actions
/^(index|show|store|update|destroy|create|edit)$/, // RESTful resource methods
/^(get|post|put|delete|patch)[A-Z]/, // Explicit HTTP method actions
/^run$/, // Command/Job run()
/^fire$/, // Event fire()
/^dispatch$/, // Dispatchable jobs
],
};
// ============================================================================
@ -252,7 +267,12 @@ export function isTestFile(filePath: string): boolean {
p.includes('/tests/') ||
// C# test patterns
p.includes('.tests/') ||
p.includes('tests.cs')
p.includes('tests.cs') ||
// PHP/Laravel test patterns
p.endsWith('test.php') ||
p.endsWith('spec.php') ||
p.includes('/tests/feature/') ||
p.includes('/tests/unit/')
);
}

View file

@ -195,8 +195,65 @@ export function detectFrameworkFromPath(filePath: string): FrameworkHint | null
return { framework: 'c-cpp', entryPointMultiplier: 2.5, reason: 'c-app' };
}
// ========== PHP / LARAVEL FRAMEWORKS ==========
// Laravel routes (highest - these ARE the entry point definitions)
if (p.includes('/routes/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-routes' };
}
// Laravel controllers (very high - receive HTTP requests)
if ((p.includes('/http/controllers/') || p.includes('/controllers/')) && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-controller' };
}
// Laravel controller by file name convention
if (p.endsWith('controller.php')) {
return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-controller-file' };
}
// Laravel console commands
if ((p.includes('/console/commands/') || p.includes('/commands/')) && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-command' };
}
// Laravel jobs (queue entry points)
if (p.includes('/jobs/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-job' };
}
// Laravel listeners (event-driven entry points)
if (p.includes('/listeners/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-listener' };
}
// Laravel middleware
if (p.includes('/http/middleware/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-middleware' };
}
// Laravel service providers
if (p.includes('/providers/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 1.8, reason: 'laravel-provider' };
}
// Laravel policies
if (p.includes('/policies/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.0, reason: 'laravel-policy' };
}
// Laravel models (important but not entry points per se)
if (p.includes('/models/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 1.5, reason: 'laravel-model' };
}
// Generic PHP MVC: files ending with Controller.php
if (p.endsWith('controller.php')) {
return { framework: 'php-mvc', entryPointMultiplier: 2.5, reason: 'php-controller-file' };
}
// ========== GENERIC PATTERNS ==========
// Any language: index files in API folders
if (p.includes('/api/') && (
p.endsWith('/index.ts') || p.endsWith('/index.js') ||
@ -236,6 +293,10 @@ export const FRAMEWORK_AST_PATTERNS = {
// Go patterns (function signatures)
'go-http': ['http.Handler', 'http.HandlerFunc', 'ServeHTTP'],
// PHP/Laravel
'laravel': ['Route::get', 'Route::post', 'Route::put', 'Route::delete',
'Route::resource', 'Route::apiResource', '#[Route('],
// Rust macros
'actix': ['#[get', '#[post', '#[put', '#[delete'],
'axum': ['Router::new'],

View file

@ -102,6 +102,21 @@ const ENTRY_POINT_PATTERNS: Record<string, RegExp[]> = {
/^Run$/, // Run methods
/^Start$/, // Start methods
],
// PHP / Laravel
'php': [
/Controller$/, // UserController (class name convention)
/^handle$/, // Job::handle(), Listener::handle()
/^execute$/, // Command::execute()
/^boot$/, // ServiceProvider::boot()
/^register$/, // ServiceProvider::register()
/^__invoke$/, // Invokable controllers/actions
/^(index|show|store|update|destroy|create|edit)$/, // RESTful resource methods
/^(get|post|put|delete|patch)[A-Z]/, // Explicit HTTP method actions
/^run$/, // Command/Job run()
/^fire$/, // Event fire()
/^dispatch$/, // Dispatchable jobs
],
};
// ============================================================================
@ -252,7 +267,12 @@ export function isTestFile(filePath: string): boolean {
p.includes('/tests/') ||
// C# test patterns
p.includes('.tests/') ||
p.includes('tests.cs')
p.includes('tests.cs') ||
// PHP/Laravel test patterns
p.endsWith('test.php') ||
p.endsWith('spec.php') ||
p.includes('/tests/feature/') ||
p.includes('/tests/unit/')
);
}

View file

@ -195,6 +195,63 @@ export function detectFrameworkFromPath(filePath: string): FrameworkHint | null
return { framework: 'c-cpp', entryPointMultiplier: 2.5, reason: 'c-app' };
}
// ========== PHP / LARAVEL FRAMEWORKS ==========
// Laravel routes (highest - these ARE the entry point definitions)
if (p.includes('/routes/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-routes' };
}
// Laravel controllers (very high - receive HTTP requests)
if ((p.includes('/http/controllers/') || p.includes('/controllers/')) && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-controller' };
}
// Laravel controller by file name convention
if (p.endsWith('controller.php')) {
return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-controller-file' };
}
// Laravel console commands
if ((p.includes('/console/commands/') || p.includes('/commands/')) && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-command' };
}
// Laravel jobs (queue entry points)
if (p.includes('/jobs/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-job' };
}
// Laravel listeners (event-driven entry points)
if (p.includes('/listeners/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-listener' };
}
// Laravel middleware
if (p.includes('/http/middleware/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.5, reason: 'laravel-middleware' };
}
// Laravel service providers
if (p.includes('/providers/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 1.8, reason: 'laravel-provider' };
}
// Laravel policies
if (p.includes('/policies/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 2.0, reason: 'laravel-policy' };
}
// Laravel models (important but not entry points per se)
if (p.includes('/models/') && p.endsWith('.php')) {
return { framework: 'laravel', entryPointMultiplier: 1.5, reason: 'laravel-model' };
}
// Generic PHP MVC: files ending with Controller.php
if (p.endsWith('controller.php')) {
return { framework: 'php-mvc', entryPointMultiplier: 2.5, reason: 'php-controller-file' };
}
// ========== GENERIC PATTERNS ==========
// Any language: index files in API folders
@ -236,6 +293,10 @@ export const FRAMEWORK_AST_PATTERNS = {
// Go patterns (function signatures)
'go-http': ['http.Handler', 'http.HandlerFunc', 'ServeHTTP'],
// PHP/Laravel
'laravel': ['Route::get', 'Route::post', 'Route::put', 'Route::delete',
'Route::resource', 'Route::apiResource', '#[Route('],
// Rust macros
'actix': ['#[get', '#[post', '#[put', '#[delete'],
'axum': ['Router::new'],