Skip to content

fix(reachability): seed PHP 8 attribute-routed handlers as entry points - #138

Merged
gadievron merged 2 commits into
masterfrom
fix/php-attribute-route-seeding
Jul 14, 2026
Merged

fix(reachability): seed PHP 8 attribute-routed handlers as entry points#138
gadievron merged 2 commits into
masterfrom
fix/php-attribute-route-seeding

Conversation

@gadievron

Copy link
Copy Markdown
Collaborator

A Symfony/API-Platform handler marked with a routing attribute (#[Route],
#[Get], #[Post], ...) on a class NOT named *Controller escaped the name/path
route heuristic, so it was never seeded and its whole handler subtree was
pruned from reachability (a real HTTP entry point, silently unreachable).

Capture PHP 8 attributes in the php extractor and classify a method carrying a
routing attribute as a route_handler independent of class name. Also recognize
Symfony request-bag reads ($request->query->get(...) etc.) as user input,
anchored to a $request/$req receiver so it does not fire on an ORM
->query->all() or a response ->headers->get().

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com


Found by a deep reachability/call-graph validation of the parser corpus: the 2026 release fixed this bug class at some parser sites but left this sibling. Ships with a RED->GREEN regression test driving the real parser/detector pipeline (not a mock). One of a 9-PR series of independent, region-disjoint fixes; verified together (full suite green, no collisions).

🤖 Generated with Claude Code

@gadievron
gadievron force-pushed the fix/php-attribute-route-seeding branch from 949916f to f237d43 Compare July 10, 2026 16:30
gadievron added a commit that referenced this pull request Jul 10, 2026
…eeded

The TypeScript analyzer emitted function records with no 'decorators' field, so
the reachability detector's decorator check (@Get/@Post/@controller in
ENTRY_POINT_DECORATORS) could never fire for JS/TS. A NestJS/Angular handler
identified only by a decorator (e.g. @get() findAll() { ... }) seeded zero entry
points and its whole subtree was pruned from reachability — a false negative.

Extract decorator source texts (method decorators plus the enclosing class's, so
@controller is captured) via ts-morph getDecorators(), at ALL three class-member
record sites: the class-declaration method loop, the class-expression method
loop, and _emitAssignedFunction (an assigned method). Standalone-function record
sites are left untouched because TS decorators cannot apply to them. The js
reachable pipeline reads analyzer_output functions directly, so no normalization
change is needed.

JS sibling of the PHP #[Route] attribute-seeding fix (#138).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gadievron added a commit that referenced this pull request Jul 10, 2026
…eeded

The TypeScript analyzer emitted function records with no 'decorators' field, so
the reachability detector's decorator check (@Get/@Post/@controller in
ENTRY_POINT_DECORATORS) could never fire for JS/TS. A NestJS/Angular handler
identified only by a decorator (e.g. @get() findAll() { ... }) seeded zero entry
points and its whole subtree was pruned from reachability — a false negative.

Extract decorator source texts (method decorators plus the enclosing class's, so
@controller is captured) via ts-morph getDecorators(), at ALL three class-member
record sites: the class-declaration method loop, the class-expression method
loop, and _emitAssignedFunction (an assigned method). Standalone-function record
sites are left untouched because TS decorators cannot apply to them. The js
reachable pipeline reads analyzer_output functions directly, so no normalization
change is needed.

JS sibling of the PHP #[Route] attribute-seeding fix (#138).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A Symfony/API-Platform handler marked with a routing attribute (#[Route],
#[Get], #[Post], ...) on a class NOT named *Controller escaped the name/path
route heuristic, so it was never seeded and its handler subtree was pruned from
reachability — a real HTTP entry point, silently unreachable.

- Capture PHP 8 attributes in the extractor and thread them into BOTH the
  call-graph record AND analyzer_output.json (unit_generator), because the
  per-parser reachable pipeline (parsers/php/test_pipeline.py) reads
  analyzer_output and normalizes units through a field whitelist that dropped
  decorators — so attribute detection silently no-opped on that path.
- Classify a method carrying a routing attribute as route_handler independent of
  class name (Check-1c); match the attribute anywhere in the attribute list,
  case-insensitively (namespaced / grouped / lowercase forms).
- Recognize Symfony request reads ($request->query->get(...), $request->get(...),
  $this->request->...) as user input, anchored to a request receiver so it does
  not fire on an ORM ->query->all() or a response ->headers->get().

Adds an end-to-end test that drives the full php reachable pipeline (not just the
raw detector), which fails without the analyzer_output + whitelist changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gadievron
gadievron force-pushed the fix/php-attribute-route-seeding branch from f237d43 to 5593289 Compare July 10, 2026 17:30
@gadievron
gadievron marked this pull request as ready for review July 10, 2026 18:17
# Conflicts:
#	libs/openant-core/tests/parsers/php/test_php_extractor.py
@gadievron
gadievron merged commit 959b20c into master Jul 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant