fix(ruby): method-level call resolution, HAS_METHOD edges, and dispatch table#278
Conversation
…ch table refactoring - Replace all `if (language === Ruby)` checks in processors with a `callRouters` dispatch table in call-routing.ts (renamed from ruby-call-routing.ts to preserve git history) - Add Ruby `method` and `singleton_method` to FUNCTION_NODE_TYPES so findEnclosingFunction produces Method-level CALLS sources - Add Ruby `class` and `module` to CLASS_CONTAINER_TYPES for HAS_METHOD edge generation - Add bare call capture via tree-sitter query `(body_statement (identifier))` for Ruby methods called without parentheses - Add Ruby member call detection (`call` node with `receiver` field) to inferCallForm and extractReceiverName - Wire resolveRubyImport into resolveLanguageImport - Add 24 integration tests across 5 suites: heritage/properties, arity filtering, member calls, ambiguous disambiguation, local shadow - Add ruby.test.ts to CI integration workflow
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@claude review these changes and find gaps in ruby resolution strategies. |
|
Claude finished @magyargergo's task in 3m 56s —— View job Ruby Resolution Strategy Review
Good structural work here — the dispatch table refactor is clean and the new test coverage is solid. That said, a review of the resolution pipeline surfaces several gaps worth addressing. 1. Singleton method label mismatch — CALLS attribution broken for
|
| Gap | Severity | File |
|---|---|---|
Singleton method label mismatch (def self.foo → CALLS broken) |
Bug | tree-sitter-queries.ts, utils.ts:432 |
User.new not resolved to User class |
Medium | call-processor.ts:387 |
attr_* Properties missing ownerId / HAS_METHOD |
Medium | parse-worker.ts:912, call-processor.ts:161 |
Bare call over-capture (body_statement identifier) |
Low/Medium | tree-sitter-queries.ts:527 |
extend vs include semantic distinction |
Low | call-routing.ts:106 |
self.method() receiver not resolved to class |
Low/Medium | utils.ts:823 |
Bare require of local files untested |
Low | ruby.test.ts |
prepend untested |
Low | ruby.test.ts |
The singleton method bug (#1) and missing ownerId for properties (#3) are the highest priority. The User.new gap (#2) is architecturally interesting since Ruby's constructor dispatch doesn't map cleanly to the constructor detection used by other languages.
CI Report✅ All checks passed Pipeline Status
Test Results✅ 1672 passed Code CoverageCombined (Unit + Integration)
Coverage breakdown by test suiteUnit Tests
Integration Tests
Coverage thresholds are auto-ratcheted — they only go upVitest 📋 View full run · Generated by CI |
- Fix singleton_method label mismatch: @definition.function → @definition.method so CALLS edges from `def self.foo` bodies get correct sourceId - Add ownerId and HAS_METHOD edges to attr_* Property nodes by calling findEnclosingClassId in both parse-worker and call-processor property branches - Distinguish include/extend/prepend heritage: add heritageKind to RubyHeritageItem, propagate through heritage pipeline as IMPLEMENTS reason - Document bare call over-capture limitation in tree-sitter query comment - Add bare `require` (non-relative) import test coverage - Add prepend/extend test coverage with distinct Loggable/Cacheable modules 31 Ruby integration tests passing, no regressions in other language resolvers.
|
@claude review my changes since last time and take into account that some items have been defferred and mentioned in the PRs message |
|
Claude finished @magyargergo's task in 5m 55s —— View job Ruby Resolution Strategy — Follow-up Review
All six non-deferred gaps from the previous review are addressed. Two items ( Previously-identified gaps — status
New observations1. Web
|
…, singleton_method label
- Web call-processor: use item.heritageKind as IMPLEMENTS reason instead of
hardcoded 'trait-impl', add :${kind} suffix to edge ID for uniqueness
- Web call-processor: port findEnclosingClassId, add HAS_METHOD edges for
attr_* Property nodes to match CLI fix
- Web call-processor: singleton_method label 'Function' → 'Method' to match
CLI tree-sitter query fix
- CLI parse-worker: update stale ExtractedHeritage.kind JSDoc to include
'include' | 'extend' | 'prepend'
Web package was missing HAS_METHOD in the RelationshipType union, causing a type mismatch with the HAS_METHOD edges emitted by the attr_* property fix in call-processor.ts.
|
@claude review my changes since last time and take into account that some items have been defferred and mentioned in the PRs message |
|
Claude finished @magyargergo's task in 4m 3s —— View job Ruby Resolution Strategy — Third Review
All three items from the second review are addressed in commits Items from second review — status
New observations1. Heritage fallback generates wrong label for Ruby classes [Low / pre-existing]File: } else if (h.kind === 'trait-impl' || h.kind === 'include' || h.kind === 'extend' || h.kind === 'prepend') {
const structId = symbolTable.lookupExact(h.filePath, h.className) ||
resolveSymbol(...)?.nodeId ||
generateId('Struct', `${h.filePath}:${h.className}`); // ← 'Struct', not 'Class'If a Ruby class (or module) is somehow missing from the symbol table, the fallback ID is 2. Web
|
Summary
Continuation of #111 — fixes Ruby-specific gaps left after the initial Ruby language support was merged.
if (language === Ruby)checks in processors with acallRoutersdispatch table incall-routing.ts(renamed fromruby-call-routing.ts)findEnclosingFunctionnow recognizesmethodandsingleton_methodAST nodesCLASS_CONTAINER_TYPESnow includesclassandmodulecallnode withreceiverfield) toinferCallFormandextractReceiverNameresolveRubyImportintoresolveLanguageImport(was dead code)ruby.test.tsto CI integration workflowResolution gaps fixed (from code review)
@definition.function→@definition.methodforsingleton_method— CALLS edges fromdef self.foobodies now resolve correctlyattr_accessor/attr_reader/attr_writernow getfindEnclosingClassId+ HAS_METHOD edges in both parse-worker and call-processorheritageKindfield added toRubyHeritageItem, propagated through heritage pipeline as IMPLEMENTS edgereason('include','extend','prepend')body_statement (identifier)query in tree-sitter commentrequiretest coverage: Added non-relativerequire 'lib/...'import to fixture + test assertionprependtest coverage: Addedprepend Cacheablewith distinct module fixture + test assertionDeferred to #274
User.newconstructor calls not linked toUserclass — requires constructor-dispatch type inference infrastructureself.method()receiver not resolved to enclosing class — requiresself→ enclosing class type mapping inlookupTypeEnvTest plan
obj.method(), HAS_METHOD edgestsc --noEmit)Files changed
call-routing.ts(CLI + web)ruby-call-routing.ts, addedcallRoutersRecord,heritageKindonRubyHeritageItemcall-processor.ts,parse-worker.ts,import-processor.ts(CLI + web)if (Ruby)with dispatch, properties get ownerId + HAS_METHODheritage-processor.tsinclude/extend/prependkinds alongsidetrait-implutils.tsmethod/singleton_methodto FUNCTION_NODE_TYPES,class/moduleto CLASS_CONTAINER_TYPES, Ruby member call detectiontree-sitter-queries.tssingleton_method→@definition.method,(body_statement (identifier))query with over-capture docsimport-processor.tsresolveRubyImportintoresolveLanguageImportci-integration.ymlruby.test.tsto pipeline and coverage jobsruby.test.ts+ 7 fixture files