( typeName: string, methodName: string, ref: UnresolvedRef, context: ResolutionContext, confidence: number, resolvedBy: ResolvedRef['resolvedBy'], /** * Optional FQN that identifies WHICH class declaration `typeName` * refers to in the caller's file. When multiple candidates share * the same qualifiedName (`FooConverter::convert` in both * `dao/converter/` and `service/converter/`), the FQN's * file-path-suffix picks the right one — the disambiguation * signal Java imports carry but the call site doesn't (#314). */ preferredFqn?: string, /** Recursion guard for the supertype/conformance walk. */ depth = 0, )
| 546 | // Exported for the precedence unit tests (#1079): they assert the |
| 547 | // preferredFqn → same-file → matches[0] ordering directly. |
| 548 | export function resolveMethodOnType( |
| 549 | typeName: string, |
| 550 | methodName: string, |
| 551 | ref: UnresolvedRef, |
| 552 | context: ResolutionContext, |
| 553 | confidence: number, |
| 554 | resolvedBy: ResolvedRef['resolvedBy'], |
| 555 | /** |
| 556 | * Optional FQN that identifies WHICH class declaration `typeName` |
| 557 | * refers to in the caller's file. When multiple candidates share |
| 558 | * the same qualifiedName (`FooConverter::convert` in both |
| 559 | * `dao/converter/` and `service/converter/`), the FQN's |
| 560 | * file-path-suffix picks the right one — the disambiguation |
| 561 | * signal Java imports carry but the call site doesn't (#314). |
| 562 | */ |
| 563 | preferredFqn?: string, |
| 564 | /** Recursion guard for the supertype/conformance walk. */ |
| 565 | depth = 0, |
| 566 | ): ResolvedRef | null { |
| 567 | // Look up methods by name and match by qualifiedName ending in |
| 568 | // `<typeName>::<methodName>`. This works whether the method is defined |
| 569 | // in-class (`class Foo { int bar() { ... } }`) or out-of-line in a separate |
| 570 | // file (`int Foo::bar() { ... }` in foo.cpp while class Foo is in foo.hpp). |
| 571 | // The previous same-file approach missed the latter — the typical C++ layout. |
| 572 | // Prefer the context's per-(type, method) memo: the raw name lookup fetches |
| 573 | // EVERY node sharing the method name — tens of thousands of rows for a |
| 574 | // collision-heavy Java name like `execute` — and re-filtering that per ref |
| 575 | // was a dominant term in the #1122 watchdog kill on large repos. Only the |
| 576 | // ref-independent filter is memoized; per-ref disambiguation stays below. |
| 577 | let matches: Node[]; |
| 578 | if (context.getMethodMatches) { |
| 579 | matches = context.getMethodMatches(typeName, methodName, ref.language); |
| 580 | } else { |
| 581 | const methodCandidates = context.getNodesByName(methodName); |
| 582 | const want = `${typeName}::${methodName}`; |
| 583 | matches = []; |
| 584 | for (const m of methodCandidates) { |
| 585 | if (m.kind !== 'method') continue; |
| 586 | if (m.language !== ref.language) continue; |
| 587 | const qn = m.qualifiedName; |
| 588 | if (qn === want || qn.endsWith(`::${want}`)) { |
| 589 | matches.push(m); |
| 590 | } |
| 591 | } |
| 592 | } |
| 593 | if (matches.length === 0) { |
| 594 | // Conformance fallback: the method may be defined on a supertype `typeName` |
| 595 | // extends, or on a protocol / trait it conforms to (e.g. a Swift protocol- |
| 596 | // extension method, a C# default-interface or extension method, a Kotlin |
| 597 | // extension on a supertype). Walk supertypes transitively (depth-capped) via |
| 598 | // the resolved implements/extends edges — empty in the first resolution pass, |
| 599 | // populated in the conformance pass. Still VALIDATED (the method must exist on |
| 600 | // a supertype), so a wrong inference produces no edge. |
| 601 | if (depth < 4 && context.getSupertypes) { |
| 602 | const viaSupers = nmTimedT('rmot-supers', ref, (): ResolvedRef | null => { |
| 603 | for (const supertype of context.getSupertypes!(typeName, ref.language)) { |
| 604 | const via = resolveMethodOnType( |
| 605 | supertype, methodName, ref, context, confidence, resolvedBy, preferredFqn, depth + 1, |
no test coverage detected