* Resolve a `this. ` function-as-value reference (#756/#808) to the * ENCLOSING CLASS's own member — never a same-named symbol elsewhere. The * registration idiom (`btn.on('click', this.handleClick)`) names a member * of the class being defined, so the only valid target shares the
(ref: UnresolvedRef)
| 2260 | * file required, no fallback of any kind. |
| 2261 | */ |
| 2262 | private resolveThisMemberFnRef(ref: UnresolvedRef): ResolvedRef | null { |
| 2263 | const member = ref.referenceName.slice('this.'.length); |
| 2264 | if (!member) return null; |
| 2265 | const fromNode = this.queries.getNodeById(ref.fromNodeId); |
| 2266 | if (!fromNode) return null; |
| 2267 | // A hook declared at class-body level (Ruby `before_action :authenticate`) |
| 2268 | // attributes to the CLASS node itself — its qualified name IS the scope. |
| 2269 | // For members, strip the member segment. |
| 2270 | let classPrefix: string; |
| 2271 | if (SUPERTYPE_BEARING_KINDS.has(fromNode.kind) || fromNode.kind === 'module') { |
| 2272 | classPrefix = fromNode.qualifiedName; |
| 2273 | } else { |
| 2274 | const sep = fromNode.qualifiedName.lastIndexOf('::'); |
| 2275 | if (sep <= 0) return null; // not inside a class scope |
| 2276 | classPrefix = fromNode.qualifiedName.slice(0, sep); |
| 2277 | } |
| 2278 | const candidates = this.context |
| 2279 | .getNodesByQualifiedName(`${classPrefix}::${member}`) |
| 2280 | .filter( |
| 2281 | (n) => |
| 2282 | (n.kind === 'function' || n.kind === 'method') && |
| 2283 | n.filePath === ref.filePath && |
| 2284 | n.id !== ref.fromNodeId |
| 2285 | ); |
| 2286 | if (candidates.length === 0) { |
| 2287 | // Not on the class itself — possibly INHERITED. implements/extends |
| 2288 | // edges don't exist yet in this pass, so retry in the supertype pass |
| 2289 | // (resolveDeferredThisMemberRefs) instead of giving up. |
| 2290 | this.deferredThisMemberRefs.push(ref); |
| 2291 | return null; |
| 2292 | } |
| 2293 | const target = candidates.reduce((a, b) => (a.startLine <= b.startLine ? a : b)); |
| 2294 | return { |
| 2295 | original: ref, |
| 2296 | targetNodeId: target.id, |
| 2297 | confidence: 0.95, |
| 2298 | resolvedBy: 'function-ref', |
| 2299 | }; |
| 2300 | } |
| 2301 | |
| 2302 | /** |
| 2303 | * Second pass for `this.<member>` refs whose member wasn't on the enclosing |
no test coverage detected