Skip to content

fix(zig,php parsers): attribute generic-container & anonymous-class methods correctly#127

Open
gadievron wants to merge 2 commits into
staging/parser-fix-stackfrom
pr/zig-php-generic-anon
Open

fix(zig,php parsers): attribute generic-container & anonymous-class methods correctly#127
gadievron wants to merge 2 commits into
staging/parser-fix-stackfrom
pr/zig-php-generic-anon

Conversation

@gadievron

Copy link
Copy Markdown
Collaborator

Zig + PHP: attribute generic-container & anonymous-class methods correctly

Fixes the class-key collapse bug family in the Zig and PHP parsers (cross-parser siblings of the Go generic-receiver fix).


⚠️ MERGE TARGET — this PR targets staging/parser-fix-stack, NOT master (humans and agents)

This change is part of the parser-fix stack and must merge into the integration branch staging/parser-fix-stack, which already contains every prerequisite it needs. It reaches master later, together with the rest of the stack — not on its own.

Do NOT retarget this at master. master is missing all three prerequisites below — the two parser rewrites AND the grammar pin:

Depends-on: #110   (Zig parser: fix 6 finder bugs — realigns the parser to current tree-sitter-zig node names)
Depends-on: #111   (PHP parser: fix 8 finder bugs — reworks _extract_functions_from_tree)
Depends-on: the tree-sitter-zig>=1.1.2 grammar pin — carried by the stack; absent from master's requirements.txt

On master the fix is inert and its regression tests fail (Zig) / methods aren't extracted (PHP) — see "Why" below. Because the stack carries all three prerequisites, on staging/parser-fix-stack this PR is exactly 4 files and fully green (73 tests pass).

Why the order matters (verify it yourself)

master's Zig parser matches stale tree-sitter node names (VarDecl, container_decl, FnProto); the installed tree-sitter-zig (>=1.1.2) emits variable_declaration / struct_declaration / function_declaration. #110 realigns the parser to the new names. Until then, Zig struct/method extraction is dead, and this fix (written against the new names) cannot work:

git show origin/master:libs/openant-core/parsers/zig/function_extractor.py | grep -c 'struct_declaration'
# -> 0   (the node names this fix depends on don't exist on master; #110 adds them)

PHP similarly needs #111's reworked _extract_functions_from_tree traversal.

Self-guard: the Zig regression test skips with this exact explanation when run on a base that lacks the prerequisite, so an agent/human running the suite on the wrong base sees why instead of a cryptic failure (it does not silently pass — it reports SKIPPED with the reason).


Summary

  • Zig (parsers/zig/function_extractor.py): methods inside the generic-container idiom fn List(comptime T: type) type { return struct { fn push() ... }; } were emitted as bare top-level functions (class_name=None) and distinct containers' same-named methods collided. Fix: _returns_type() + thread the container fn name as struct context → List.push.
  • PHP (parsers/php/function_extractor.py): methods inside new class {} anonymous classes had class_name=None and collided across distinct anon classes (silent overwrite / data loss). Fix: an anonymous_class branch synthesizing a stable class@anonymous:<line>:<col> identity (line+col so multiple anon classes on one line stay distinct).

Tests

5 new (qualified-name + collision regressions, incl. same-line anon classes). On the prerequisite base (staging/parser-fix-stack) the full zig+php suites are green — 73 passed. Independent + judge reviewed.

Related

Companion Go PR (fix(go-parser): key generic-type methods on base type) fixes the same bug family for the Go parser. It is independent — Go uses the stdlib go/ast (stable node types), so it lands on master on its own with no dependency in either direction.

gadievron and others added 2 commits June 17, 2026 15:53
…ethods correctly

Zig: methods inside the generic-container idiom 'fn List(comptime T: type) type {
return struct {...} }' were emitted as bare top-level functions (class_name None)
and distinct containers' same-named methods collided. Add _returns_type() and
thread the container fn name as struct context so they qualify as List.method.

PHP: methods inside 'new class {}' anonymous classes had class_name None and
collided across distinct anon classes (data loss via overwrite). Add an
anonymous_class branch synthesizing a stable class@anonymous:<line>:<col> identity
(line+col so multiple anon classes on one line stay distinct).

Tests: 5 new across both parsers (qualified-name + collision regressions, incl.
same-line). zig+php suites: 73 passed. Independent + judge verified, no regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ession tests

Make the cross-PR dependency self-documenting so a human reviewer OR an agent running
the suite on the wrong base sees WHY, not a cryptic failure:

- zig test: skipif-guard that probes the PREREQUISITE behavior (a named struct's
  method extracting — provided by the tree-sitter-zig>=1.1.2 grammar-alignment PRs,
  not by this fix). On a stale-grammar base the tests skip with an explanatory message
  instead of failing. Non-circular: the probe uses a named struct, the tests cover the
  distinct generic-container case.
- php test: module-docstring note stating the dependency on the reworked
  _extract_functions_from_tree traversal.

This change is NOT landable on raw upstream master; see Depends-on: PR-87/PR-110/322920e
in the PR description.

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

Copy link
Copy Markdown
Collaborator Author

Heads-up for reviewers/agents: two follow-up fix PRs are stacked on this branch (pr/zig-php-generic-anon) and should merge after #127 (or be rebased onto master once this lands):

Both are draft until #127 merges.

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