Repository navigation
Conversation
The PHP grammar nests `#[A, B]` as attribute_list > attribute_group > attribute, which the decorator walk never descended, so no PHP attribute usage became a `decorates` reference. Both extraction paths now emit them: the wasm extractor and the native kernel's PHP walker, which is the default for PHP and previously dropped attributes by design. Namespaced names (`ORM\Entity`, `\Symfony\...\Route`) resolve by their last segment. SIBLINGS: decorator container never descended -- C# attribute_list is skipped the same way on both paths (csharp.rs:709); left as is, out of scope and parity-pinned. GUARD: kernel-php-parity.test.ts asserts the decorates refs and kernel/wasm equality. Co-authored-by: jorge robles <jorge.diego.robles@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Routes come from PHP 8 #[Route] attributes, config/routes.yaml and the compiled router in var/cache, each a route node with a references edge to its action; service definitions link to their class. Detection covers symfony/framework-bundle, symfony/symfony and Shopware 6 (shopware/core). Changes against the closed colbymchenry#611: - #[Route] is read from the PHP AST (attribute_list > attribute_group > attribute), not a regex over the source: the `(?:\s*\n\s*)*` pattern before `class` backtracked exponentially (3.3 s at 16 blank lines). A path-less class-level #[Route] no longer swallows the first method route, stacked routes are all kept, multi-line attributes keep their defaults, and commented-out attributes stay out without changing the PHP comment stripper for every project. - Controller resolution looks the class up by name through the index and prefers the written namespace, instead of scanning every class per reference; claimsReference only claims names with a `\`. - No duplicate class nodes for entities, repositories, subscribers and commands; the attribute decorates edges cover those classes. - YAML: a resource import is not a route; polyfills are excluded by prefix; only var/cache and .symfony count as the compiled container. - defaults/requirements arrays keep their own pairs and unquoted scalars. EXTRACTION_VERSION 29: a new framework extractor changes what an index holds. Co-authored-by: jorge robles <jorge.diego.robles@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From a review of the branch:
- A compiled Route's HTTP methods are its seventh argument; the sixth is
the schemes, so `['https']` became an `HTTPS` route and a route with
methods but no schemes was dropped. An empty list means ANY.
- `#[Route('')]` under a class prefix is that prefix, not a missing path.
- A written FQCN resolves only to the class in that namespace; another
namespace's class of the same short name is left unlinked.
- The extra PHP syntax trees are deleted after reading, so repeated syncs
do not hold wasm memory.
Fixtures with methods in the schemes slot now use Symfony's argument order.
SIBLINGS: unfreed getParser() trees -- src/graph/branch-guards.ts and
src/extraction/syntax-tokens.ts, the other callers outside the
extractor, already delete theirs.
GUARD: symfony-resolver.test.ts covers each case and was red before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 30, 2026
Closed
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #611. A fresh take against today's
main, as @colbymchenry suggested when closing #611 (close comment). It carries @jorgerobles's Symfony resolver (credited withCo-authored-byon the commits that port his code) plus the AST-based route work from jorgerobles#1, and resolves every point raised when #611 was closed.What it adds
#[Route]attributes, read from the PHP AST: class-level prefixes, stacked routes on one action, multi-line attributes,methods:,name:,defaults:,requirements:,host:,schemes:, andRequest::METHOD_GET-style constants.config/routes.yaml(path,controller,methods,prefix; aresource:import is not a route).var/cache/<env>/…).services.yaml/ compiled-container service links to its class.decoratesedges on classes, methods and functions (#[AsCommand],#[ORM\Entity],#[AsEventListener], …) for every PHP project, so attribute classes show who uses them.symfony/framework-bundle,symfony/symfony,shopware/core(Shopware 6 shops and plugins are Symfony apps withoutbin/console), orbin/console+config/.The close comment, point by point
(?:\s*\n\s*)*beforeclassbacktracks exponentially. The regex is gone; routes are read from theattribute_list → attribute_group → attributenodes of each class and method declaration. On the old pattern,#[Route('/x')]followed by 16 whitespace-only lines took 3.3 s and 18 lines took 17.5 s.symfony-resolver.test.ts > pathological inputfeeds 20,000 such lines plus 2,000 unclosed nested[and requires the extraction to finish in under 1 s.resolve()now looks the class up through the name index (getNodesByName(shortName)), takes only the class in the namespace the FQCN names (another namespace's class of the same short name stays unlinked), and asks only for the method by name in that file (getNodesInFileNamed), limited to the class's line range. The unit test's context throws ifgetNodesByKindis called; an integration test with twoBlogControllers in different namespaces pins the FQCN choice.claimsReferenceis narrowed to names containing\, andresolve()answers only route and service references.codegraph-kernel/src/php.rs(the default PHP path) dropped attributes by design, and the wasm extractor never descended intoattribute_list. Both now emit the samedecoratesrefs;kernel-php-parity.test.tschecks kernel/wasm equality and the expected refs, and the end-to-end test passes on both paths (CODEGRAPH_KERNEL=0and default).#[change instrip-comments.tsaffects every PHP project. Dropped. Route extraction reads the AST, so commented-out attributes are skipped without touching the comment stripper.Also fixed from the review of #611
#[Route(defaults: …)](Shopware's_routeScope) no longer swallows the first method route.#[Route]on one action becomes a route.symfony/polyfill-*is excluded by prefix.var/cache/…and.symfony/…count as the compiled container, not anysrc/Cache/…Container.php.Routeargument (the sixth is the schemes), and an empty list meansANY.#[Route('')]under a class prefix is that prefix.defaults:/requirements:arrays keep their own pairs when both are present, and unquoted scalars ('page' => 1,=> true) are kept. Fixtures that used YAML-style{ key: value }(not valid PHP) now use PHP arrays.Notes for review
#[andRoute. The kernel's tables don't carry attribute arguments, so reading them from the kernel would mean widening the kernel ABI. I kept that out of this PR.EXTRACTION_VERSIONbumped to 29 (new framework extractor and new PHP edges), so existing indexes get the re-index hint.services.xml, common in Shopware) are not parsed.Testing
__tests__/symfony-resolver.test.ts(unit, 48 tests) and__tests__/symfony-integration.test.ts(end to end, 10 tests).__tests__/kernel-php-parity.test.ts, with the kernel built (npm run build:kernel).npm testwith the kernel built: 9,815 passed, 46 skipped. The only failure,ui-server-api.test.ts > the engine's own busiest symbol(a 100 ms timing bar, 114–128 ms here), runs only on a machine with a local.codegraph/index of this repository and does not touch PHP or Symfony code.npx tsc --noEmit: clean.Credits
Co-authored-by.🤖 Generated with Claude Code and onedot-devkit