Skip to content

fix(parsers): repair Ruby + PHP call-graph resolution#73

Open
gadievron wants to merge 2 commits into
masterfrom
fix/parsers-repair-ruby-php-call-graph-resolution
Open

fix(parsers): repair Ruby + PHP call-graph resolution#73
gadievron wants to merge 2 commits into
masterfrom
fix/parsers-repair-ruby-php-call-graph-resolution

Conversation

@gadievron

Copy link
Copy Markdown
Collaborator

Resolution defects in the Ruby and PHP call-graph builders dropped real edges
and emitted false ones. Each parser is fixed parser-native with its own grammar;
no token was copied between them.

Ruby (parsers/ruby/call_graph_builder.py):

  • Module-function resolution: add a methods_by_module index + thread caller
    module_name. Module self/sibling and Module.method calls now resolve; a bare
    call from outside any module no longer leaks an edge to a module function (the
    same-file and unique-name fallbacks now require both class_name and module_name
    unset).
  • super: visit the bare super node and the super(args) call head; resolve to
    the same-named method on the superclass.
  • Class.new: resolve new to the class initialize before the builtin filter that
    previously dropped it.
  • require_relative anchoring: anchor require_relative to the caller dir and
    normalize ./ and ../; match require by anchored file name, replacing the
    unanchored substring that over-matched any path containing the import string.
  • send/public_send/send: read the literal symbol argument and resolve the
    dispatched method.

PHP (parsers/php/call_graph_builder.py):

  • Cross-namespace bare-call leak: thread the caller's namespace_name and scope the
    unique-name fallback to the caller's namespace so a bare call no longer leaks
    across namespaces. PHP-native analog of the Ruby module-leak fix (different
    grammar/fields; implemented independently).

Tests: tests/parsers/ruby/test_call_graph_builder.py (10),
tests/parsers/php/test_call_graph_builder.py (2). Both modules loaded under
unique importlib names (call_graph_builder.py / function_extractor.py are basenames
shared by every parser). 11 failed pre-fix (1 same-namespace guard green at base by
design) -> 12 passed after the fix; ruff clean.

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

Resolution defects in the Ruby and PHP call-graph builders dropped real edges
and emitted false ones. Each parser is fixed parser-native with its own grammar;
no token was copied between them.

Ruby (parsers/ruby/call_graph_builder.py):
- Module-function resolution: add a methods_by_module index + thread caller
  module_name. Module self/sibling and Module.method calls now resolve; a bare
  call from outside any module no longer leaks an edge to a module function (the
  same-file and unique-name fallbacks now require both class_name and module_name
  unset).
- super: visit the bare `super` node and the `super(args)` call head; resolve to
  the same-named method on the superclass.
- Class.new: resolve `new` to the class initialize before the builtin filter that
  previously dropped it.
- require_relative anchoring: anchor require_relative to the caller dir and
  normalize ./ and ../; match require by anchored file name, replacing the
  unanchored substring that over-matched any path containing the import string.
- send/public_send/__send__: read the literal symbol argument and resolve the
  dispatched method.

PHP (parsers/php/call_graph_builder.py):
- Cross-namespace bare-call leak: thread the caller's namespace_name and scope the
  unique-name fallback to the caller's namespace so a bare call no longer leaks
  across namespaces. PHP-native analog of the Ruby module-leak fix (different
  grammar/fields; implemented independently).

Tests: tests/parsers/ruby/test_call_graph_builder.py (10),
tests/parsers/php/test_call_graph_builder.py (2). Both modules loaded under
unique importlib names (call_graph_builder.py / function_extractor.py are basenames
shared by every parser). 11 failed pre-fix (1 same-namespace guard green at base by
design) -> 12 passed after the fix; ruff clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tform resolution

The Ruby FunctionExtractor built call-graph keys with str(path.relative_to(repo)), which on
Windows yields backslash separators (lib\sub\a.rb). The require_relative anchoring resolves
those keys with posixpath operations, so posixpath.dirname("lib\sub\a.rb") == "" and the
caller-dir anchoring silently fails — dropping the edge (a wrong/empty call graph for any
subdirectory require_relative on Windows). Use .as_posix() so keys are forward-slash on all
platforms. No behavior change on POSIX (str and as_posix are identical there).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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