How code-review-graph Handles PHP and Laravel Framework-Specific Parsing

The code-review-graph repository processes PHP using Tree-sitter grammar and enriches Laravel applications with framework-specific edges by resolving Composer PSR-4 mappings, parsing Blade templates, and extracting route-to-controller relationships.

The code-review-graph tool provides comprehensive PHP and Laravel framework-specific parsing capabilities that transform raw source code into navigable knowledge graphs. By combining Tree-sitter AST traversal with Composer autoloading logic and Laravel-specific heuristics, the parser captures everything from basic class dependencies to complex Eloquent model relationships.

Core PHP Parsing Architecture

The foundation of PHP support resides in the CodeParser class within code_review_graph/parser.py. When processing PHP files, the parser loads a Tree-sitter grammar registered under the "php" key and walks the syntax tree to extract namespaces, imports, class definitions, and method calls.

Composer PSR-4 Autoloading Resolution

To bridge the gap between PHP namespaces and file system paths, the implementation uses dedicated Composer helpers. The _read_php_composer_psr4 function (defined at line 551) reads the repository's composer.json and extracts the "autoload" and "autoload-dev" PSR-4 mappings, caching these for repeated lookups.

The _resolve_php_composer_module function (line 12684) consumes these cached mappings to translate fully-qualified class names into concrete file paths. This enables the parser to resolve use App\Models\User statements to their actual source files even when the namespace prefix maps to a subdirectory.

Namespace and Import Extraction

The parser captures file-level namespace context through _php_namespace_name (line 10549), which extracts the declared namespace declaration. For import statements, _php_import_bindings (line 10558) builds a mapping from short class names to fully-qualified names by analyzing use declarations at the top of each file.

When resolving class references—including imported aliases and relative names—the system delegates to _php_resolve_class_reference (line 10616). This ensures that a reference to new User() correctly resolves to App\Models\User based on the file's explicit imports and declared namespace.

Laravel Framework Extensions

Beyond standard PHP analysis, code-review-graph activates Laravel-specific processing when encountering .blade.php files or Laravel-specific AST patterns. This specialized layer adds framework semantics to the generic PHP walk.

Blade Template Recognition

Laravel's Blade templating engine receives dedicated handling through the _extract_php_laravel_edges entry point (line 10403). This function recursively walks the PHP AST and delegates to framework-specific walkers that understand Laravel's architectural patterns.

The _walk_php_laravel_sequence function (line 10410) follows statement sequences that may contain route definitions or controller method calls, while _walk_php_laravel_node processes individual AST nodes to identify classes, methods, and framework-specific function calls.

Route-to-Controller Resolution

For HTTP routing analysis, the parser identifies Route::get, Route::post, and similar static method calls through _php_route_handler (line 10667). This function creates CALLS edges connecting the route definition node to the target controller method, enabling the knowledge graph to represent the application's HTTP request dispatch flow.

Eloquent Model Relationship Mapping

The system detects Eloquent model inheritance via _php_class_extends_eloquent_model (line 10637), which identifies classes extending Model and analyzes relationship methods such as hasMany, belongsTo, and hasOne. These generate HAS_ONE or HAS_MANY edges in the graph, linking related model classes to represent the application's database relationship structure.

Laravel-Specific Method Call Resolution

For general Laravel method calls—including Controller::method invocations and facades—the parser uses _php_laravel_caller (line 10767) to resolve targets and create appropriate graph edges that reflect the framework's magic method resolution.

Security and Repository Boundaries

When resolving Composer mappings, code-review-graph enforces strict repository boundaries through _php_repository_boundary (line 13084). This safety mechanism discards any mappings that point outside the repository root and ignores symlinked or absolute paths that would escape the codebase, preventing path traversal vulnerabilities and false positives from system-wide Composer dependencies.

Practical Implementation Examples

Resolving a Composer-mapped class:

from code_review_graph.parser import CodeParser

parser = CodeParser(repo_path)  # repo_path points to a Laravel project

edges = parser.parse_file(repo_path / "app/Models/User.php")

# edges now contain IMPORTS_FROM for any `use` statements and,

# if the file defines a model extending Eloquent, HAS_ONE/HAS_MANY edges to related models

Extracting Laravel routes:

parser = CodeParser(repo_path)
edges = parser.parse_file(repo_path / "routes/web.php")

# The graph includes CALLS edges such as:

# Route::get('/users', 'UserController@index') → edge to UserController::index method

The comprehensive test suite in tests/test_php_laravel.py validates PSR-4 resolution accuracy and Laravel-specific edge extraction behaviors.

Summary

  • code-review-graph uses Tree-sitter with a dedicated PHP grammar in code_review_graph/parser.py for syntactic analysis
  • Composer PSR-4 mappings are cached and resolved via _read_php_composer_psr4 (line 551) and _resolve_php_composer_module (line 12684)
  • PHP imports and namespaces are tracked through _php_import_bindings (line 10558) and _php_namespace_name (line 10549)
  • Laravel analysis activates for .blade.php files via _extract_php_laravel_edges (line 10403)
  • Route handlers create CALLS edges using _php_route_handler (line 10667)
  • Eloquent relationships generate HAS_ONE and HAS_MANY edges via _php_class_extends_eloquent_model (line 10637)
  • Repository security is enforced by _php_repository_boundary (line 13084) to prevent path traversal

Frequently Asked Questions

How does code-review-graph resolve PHP class names to file paths?

The parser reads the composer.json PSR-4 autoloading configuration using _read_php_composer_psr4, caches these mappings, and resolves fully-qualified class names to file paths through _resolve_php_composer_module. This allows accurate resolution of imported classes regardless of namespace prefix depth.

What Laravel-specific relationships does the graph capture?

The parser creates CALLS edges for route-to-controller mappings through _php_route_handler, HAS_ONE and HAS_MANY edges for Eloquent model relationships via _php_class_extends_eloquent_model, and handles Blade template dependencies through the _extract_php_laravel_edges pipeline.

How does the parser handle PHP use statements and imports?

The _php_import_bindings function extracts use declarations to build a short-name to fully-qualified-name mapping, while _php_resolve_class_reference resolves class references—including imported aliases and relative names—to their canonical fully-qualified names based on file context.

What security measures prevent the parser from accessing files outside the repository?

The _php_repository_boundary function (line 13084) validates all resolved paths against the repository root, discarding mappings that point outside the codebase and ignoring symlinks or absolute paths that would escape the repository boundary, ensuring safe analysis of untrusted codebases.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →