fix(parsers): stop Ruby nested classes deleting their parent, and extract method parameters - #1581
Merged
Merged
Conversation
…ract parameters (#1523, #1527) Nested classes overwrote their parent (#1523) Class names were matched to class nodes by byte range: for each @name capture the code walked the class list and assigned the name to the first class whose range contained it. An outer class always contains an inner class's name node, so the inner name landed on the outer class, and the inner entry — never given a name — was dropped. class Client class TimeoutError < StandardError end end yielded exactly one class: TimeoutError, carrying Client's line range, with StandardError lost. Client vanished from the graph entirely. Each class now reads its own `name` field. tree-sitter-ruby gives the `class` keyword token the same node type as the definition, so nodes without a name field are skipped. Method parameters were always empty (#1527) `_parse_method_parameters` scanned the method node's own children for identifiers, but parameters live inside a `method_parameters` child; the only direct identifier child is the method name, which the code explicitly skipped. Every Ruby method reported no parameters, so no Ruby function ever got a HAS_PARAMETER edge. Now reads the parameters node and handles every Ruby form: def complex(a, b = 1, *rest, key:, **opts, &blk) -> ['a', 'b', '*rest', 'key', '**opts', '&blk'] Golden for sample_project_ruby regenerated: +11 Parameter nodes, no nodes lost, no classes gained or lost (the fixture has no nested classes — that case is covered by unit tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
Hi! 👋 Join our CodeGraphContext Discord channel to collaborate: https://discord.gg/dR4QY32uYQ |
Contributor
🔍 PR Code Graph Analysisfix(parsers): stop Ruby nested classes deleting their parent, and extract method parameters (#1581) 📊 Interactive VisualizationView the blast radius graph: PR Reviewer Dashboard 📦 ArtifactsThe graph JSON has been uploaded as a build artifact: Generated by CodeGraphContext using FalkorDB Lite |
This was referenced Aug 5, 2026
Shashankss1205
added a commit
that referenced
this pull request
Aug 8, 2026
Ten PRs since 0.5.6 — mostly parser correctness, all with regression tests. Parsers - Ruby nested classes no longer delete their parent; method parameters extracted at all (#1523, #1527, #1581) - C/C++ functions returning a pointer or reference are extracted, and registered in pre_scan so they resolve as call targets (#1524, #1582) - C# fields and locals parsed, restoring receiver-type inference for `var x = new T(); x.M();` (#1525, #1584) - JavaScript destructured, array and rest parameters extracted, recording the binding names rather than a placeholder (#1527, #1591) Queries and analysis - Five defects that returned wrong answers without erroring: inflated repository stats, misattributed callers, discarded graph_name, count(*) after OPTIONAL MATCH, an ignored tool argument (#1577) - Dead-code detection made correct and self-consistent, including the JS module-level false positive (#600, #1559, #1578) Indexing - add_package_to_graph on a flat module no longer indexes the whole virtualenv (#1528, #1586) - SCIP job progress no longer exceeds 100% (#1535, #1583) Docs and tests - Database Options table columns realigned (#1590) - MCP tool definition contract validation (#1580) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Shashankss1205
added a commit
that referenced
this pull request
Aug 18, 2026
…issues; finish the #1527 parameter audit (#1648) * perf(kuzu): batch relationship-only UNWIND MERGEs; scope the per-row fallback to node-MERGE shapes (#1605) Kuzu 0.11.3's MERGE pipeline mis-binds when a merged NODE's key repeats non-adjacently in one UNWIND batch ([(A,P),(B,X),(C,P)] binds C to X) — reproduced minimally and pinned in tests. Relationship-only MERGEs (MATCH..MATCH..MERGE rel) do not exhibit the bug, verified with interleaved duplicate endpoint keys and duplicate pairs, so they now run batched: the full integration suite drops from ~5:06 to ~4:09 (-20%) and a sample-project index halves. Inheritance batches are also deduped writer-side so a repeated (child, parent) record cannot double an INHERITS edge on embedded backends. * fix(indexer): retry a failed per-file graph write once before recording it (#1612) A transient write failure under runner load silently cost the graph a whole file's edges (LadybugDB intermittently 51 CONTAINS short in the parity run). Writes are MERGE-idempotent, so one retry converts the blip into success; persistent failures still land in write_failures and the error log. Together with the #1605 batching change (which removes most of the per-row write pressure the flake correlated with), this addresses the observed drop. * test(cgcignore): make the CLI cases hermetic and move them to the integration suite (#1422) The TC-12+ cases shared one fixed /tmp/cgc_test/_home database across every test and run, wiped it mid-suite, and were gated on a live Neo4j — so they were permanently skipped on most machines and intermittently failed with a different name each full-suite run wherever they did run. Each test now gets a fresh HOME and an explicit embedded backend (no server, no gate, no wipe), and the subprocess-driven cases live in tests/integration where that cost belongs. tc01-tc11 (pure PathSpec logic) stay in the unit suite. * fix(cpp): extract lambda parameters through the shared param helper (#1527) The inline version first clobbered its correctly-walked parameter_list with a nonexistent 'parameters' field on lambda_expression, then filtered for bare identifiers over parameter_declaration nodes — every lambda assignment got args: []. lambda_expression carries the same declarator→parameters field chain as function_definition, so the shared extractor handles it, rendering args in the project's established 'type name' form. Last remaining case of the #1527 parameter audit (Ruby #1581, PHP key + #1643, JS #1591 all landed previously). * regen cpp golden: lambda Parameter nodes now extracted
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 #1523 and the Ruby half of #1527.
Full suite: 1128 passed, 7 skipped, no failures.
#1523 — a nested class deleted its parent
Class names were matched to class nodes by byte range: for each
@namecapture, walk the class list and assign the name to the first class whose range contains it, thenbreak. An outer class always contains an inner class's name node, and dict order is document order — so the inner name landed on the outer class, and the inner entry, never given a name, was dropped at line 323.produced exactly one class:
TimeoutError, carryingClient's line range, withStandardErrorlost.Clientvanished from the graph entirely.Each class now reads its own
namefield. One subtlety worth recording: tree-sitter-ruby gives theclasskeyword token the same node type as the definition, so nodes without a name field are skipped rather than treated as anonymous classes.Namespaced error classes, inner value objects and
Structsubclasses are all idiomatic Ruby, so this affected a lot of real files.#1527 (Ruby) — every method reported zero parameters
_parse_method_parametersscanned the method node's own children for identifiers. Parameters live inside amethod_parameterschild; the only directidentifierchild is the method's name, which the code explicitly skipped. So the result was always[]and no Ruby function ever got aHAS_PARAMETERedge.Now handles every Ruby parameter form:
Golden
sample_project_rubyregenerated. Verified semantically rather than by line count:Purely additive. The fixture happens to contain no nested classes, so #1523's effect isn't visible in the golden — that case is covered by the unit tests instead.
tests/unit/parsers/test_ruby_parser.py— 7 tests covering nested classes, siblings, class-in-module, and all parameter forms.Remaining Ruby items
#1538 still tracks the rest of the Ruby findings —
def self.xsingleton methods never captured, nested calls stealing each other's receiver,@@class_vars/$globalsmissing, and variablevaluealwaysNonedue toid()on freshly-allocated node wrappers. Those are separate fixes and not in this PR.🤖 Generated with Claude Code