Skip to content

feat(php): capture use FQN/alias/kind metadata on imports edges (#19) - #29

Merged
filipechagas merged 2 commits into
v8from
feat/php-use-import-capture-19
Aug 5, 2026
Merged

feat(php): capture use FQN/alias/kind metadata on imports edges (#19)#29
filipechagas merged 2 commits into
v8from
feat/php-use-import-capture-19

Conversation

@filipechagas

Copy link
Copy Markdown
Collaborator

Fixes #19 (spec #18, ticket 1/5 — foundation for the #16 fix).

What

PHP imports edges now carry use_kind / alias / target_fqn metadata, mirroring _import_csharp. The already-correct use-parser from _resolve_php_type_references was extracted into shared helpers (_php_use_clause_fact, _php_use_clause_context, _php_use_declaration_facts) consumed by both the resolution pass and the capture path, replacing _import_php's lossy raw.split("\\")[-1]. Strictly metadata-only: no resolver behavior change, _PHP_CONFIG.import_types untouched, edge targets unchanged.

No-behavior-change evidence

  • Full extract() output with metadata stripped, before vs after, over a corpus covering plain / aliased / group / aliased-group / function / const / group-function / leading-backslash use, trait use, inheritance, and member calls: 59 nodes / 86 edges, byte-identical.
  • The v8 merge (d40d006) was triple-verified: both parent-diff directions byte-identical, plus an independent patch-reconstruction of extract.py matching by sha256.

Discovered, filed separately

#26 — group-form use function A\{f, g}; / use const put the keyword on the declaration, not the clause, so those names enter the class-name map today (pre-existing, reproduced at 102ae79). Deliberately preserved bit-for-bit here via apply_declaration_kind=False; the new metadata reports the correct kind. #26 must land before #21, since a wrongly claimed short name would become a wrongly decisive refusal.

Notes for #21/#22

  • use_kind vocabulary is class/function/const with alias as a separate key (unlike C#'s using_kind == "alias") — gate on use_kind == "class".
  • _resolve_php_type_references re-points imports edges but leaves metadata untouched, so metadata.target_fqn is the reliable read, not the target node's label.

Test evidence

🤖 Generated with Claude Code

PHP `imports` edges carried no metadata: `_import_php` kept only
`raw.split("\\")[-1]`, so the FQN, the alias and the `function`/`const`
kind of every `use` statement were discarded at capture time. That is the
fact base #16's decisive-refusal resolver needs, and it already existed —
correctly parsed, group-use and aliases included — but only as a
function-local map inside `_resolve_php_type_references`.

Extract that parser (`_record_use_clause` plus the
`namespace_use_declaration` walk) into three shared helpers in
resolution.py and have both consumers call them. `_import_php` is
dispatched per `namespace_use_clause` and never sees the declaration, so
`_php_use_clause_context` recovers the group-use prefix and the
declaration-level `function`/`const` keyword from the parent node; the
edge then carries `target_fqn`, `alias` and `use_kind`, mirroring
`_import_csharp`.

Strictly metadata-only. The edge target stays keyed on the imported short
name, `_PHP_CONFIG.import_types` stays `namespace_use_clause` (so a trait
`use` inside a class body — a `use_declaration` — is still not an import),
and `_resolve_php_type_references` keeps its exact behavior: it passes
`apply_declaration_kind=False` because it has only ever honored a
clause-level `function`/`const` keyword, never the declaration-level one a
group `use function A\{f, g};` carries. Verified beyond the suite by
diffing full extract() output (metadata stripped) over a PHP corpus
covering every `use` form plus the existing fixtures — byte-identical
before and after.

Tests go through the public extract() seam: plain, aliased, group and
aliased-group use, leading-backslash normalization, and edge targets
unchanged. The `use function` / `use const` exclusion is asserted where it
is observable — a same-file `use Vendor\Sdk\Base;` control re-points its
supertype reference onto the FQN stub while the `use function` /
`use const` names must not, so they stay on the bare stub.

Suite: 4032 passed / 36 skipped (baseline 4024 / 36 plus 8 new).
…ture-19

* origin/v8:
  fix(extract): scope member-call resolvers to the sources they own (#10)
  fix(php): recognize PHP 8.2 DNF property and promoted-param types (#9)
  fix(php): refuse the same-file bare-name edge for union/intersection receivers (#9)
  fix(php): emit indirect_call for first-class callables (#15)
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.

PHP use-import map 1/5: capture use FQN/alias metadata on imports edges

1 participant