fix(php): stop group-form use function/const from claiming class names (#26) - #30
Merged
Conversation
…ass names (#26) `_resolve_php_type_references` builds its per-file class-name map from `use` statements and correctly refuses `use function` / `use const` — but only when the keyword sits on the CLAUSE. tree-sitter-php (0.24.1) puts it on the DECLARATION for the group form, and the pass only ever iterated clause children, so `use function Vendor\Sdk\{Render};` registered `Render` as a claimed class name. Any `inherits` / `implements` / `mixes_in` / `imports` / `references` to that short name in the same file was then treated as an explicit import and re-pointed onto an FQN-labeled external stub — a stub naming a function or a constant, not a class. #19 already extracted the parser into `_php_use_declaration_facts`, which reads the declaration-level keyword and reports the right `use_kind`; the `imports`-edge capture consumes it that way today. This pass was the only caller passing `apply_declaration_kind=False`, purely to keep #19's metadata-only constraint byte-exact. Drop the argument and delete the flag, so one code path serves both consumers and cannot drift again. Strictly subtractive: it can only remove a class-name claim, which makes the affected reference fall back to the namespace-relative FQN or to the legacy unique-label rewire — the same place the unbraced spelling has always left it. Worth landing before #21's decisive-refusal work, where a wrongly claimed short name would become a wrongly decisive refusal. Pre-existing defect, not a regression from #19. Tests go through the public `extract()` seam with the plain form as the side-by-side control in the same test: group-vs-plain for `use function` and for `use const` (both spellings must land on the same bare stub, and no `Vendor\Sdk\*` class stub may be minted), every member of a multi-member group rejected, and an over-subtraction guard — a keyword-less group `use App\Cms\{Page};` still claims its member and resolves past a decoy `App\Models\Page`, which gets no edge. 3 of the 4 were red before this change; the guard was green both sides. Suite: 4061 passed / 36 skipped (baseline 4057 / 36 plus 4 new). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 5, 2026
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.
Fixes #26 (discovered during #19; sequenced before #21 so a wrongly claimed short name can't become a wrongly decisive refusal).
What
Group-form
use function A\{f, g};anduse const A\{K};put the keyword on the declaration node, not the clause, so those names wrongly entered_resolve_php_type_references's class-name map (pre-existing at102ae79). The shared parser #19 landed already computed the correct kind behind anapply_declaration_kind=Falsecompatibility flag; this removes the flag and its call site, leaving one code path that always honors the declaration-level keyword. Strictly subtractive.Test evidence
use App\Cms\{Page};still claims the class name, decoy gets no edge) passed on both sides by design.grep -rn apply_declaration_kindacross the repo returns nothing.Note for #21/#22
After this fix a group-imported
function/constshort name reaches the repoint loop's namespace-relative arm and ends as a bare stub — so it arrives at the futurePhpNameResolverwith no class claim._php_use_clause_contextand_php_use_declaration_factsnow agree onuse_kindfor every spelling.🤖 Generated with Claude Code