| 88 | * Context for resolution - provides access to the graph |
| 89 | */ |
| 90 | export interface ResolutionContext { |
| 91 | /** Get all nodes in a file */ |
| 92 | getNodesInFile(filePath: string): Node[]; |
| 93 | /** Whether any node in the file is exported (`getNodesInFile(f).some(n => n.isExported)`), as one indexed probe. */ |
| 94 | fileHasExportedNode?(filePath: string): boolean; |
| 95 | /** `getNodesInFile(f).filter(n => n.isExported)`, without decoding the rest of the file. */ |
| 96 | getExportedNodesInFile?(filePath: string): Node[]; |
| 97 | /** `getNodesInFile(f).filter(n => n.name === name)`, without decoding the rest of the file. */ |
| 98 | getNodesInFileNamed?(filePath: string, name: string): Node[]; |
| 99 | /** Get all nodes by name */ |
| 100 | getNodesByName(name: string): Node[]; |
| 101 | /** Get all nodes by qualified name */ |
| 102 | getNodesByQualifiedName(qualifiedName: string): Node[]; |
| 103 | /** Get all nodes of a kind */ |
| 104 | getNodesByKind(kind: Node['kind']): Node[]; |
| 105 | /** |
| 106 | * Stream nodes of a kind one at a time instead of materializing (and, unlike |
| 107 | * `getNodesByKind`, without populating the resolver's per-kind array cache). |
| 108 | * For unbounded kinds (`function`, `method`, `struct`) on a symbol-dense |
| 109 | * project the full array is gigabytes — the dynamic-edge synthesizers must |
| 110 | * use this so their memory stays O(1) in node count (#610, #1212). Optional |
| 111 | * so minimal test contexts compile; callers fall back to getNodesByKind. |
| 112 | */ |
| 113 | iterateNodesByKind?(kind: Node['kind']): IterableIterator<Node>; |
| 114 | /** Check if a file exists */ |
| 115 | fileExists(filePath: string): boolean; |
| 116 | /** Read file content */ |
| 117 | readFile(filePath: string): string | null; |
| 118 | /** `readFile(filePath)?.includes(needle) ?? false` for an ASCII `needle`, without decoding a file that lacks it. */ |
| 119 | fileContains?(filePath: string, needle: string): boolean; |
| 120 | /** |
| 121 | * `readFile(filePath)` split into lines, LRU-cached per file. Receiver-type |
| 122 | * inference scans source lines for EVERY `receiver.method()` ref; splitting |
| 123 | * the whole file per ref made that O(refs-in-file × file-size) — ~20% of |
| 124 | * total index CPU on a Java-heavy repo and a driver of the #1122 watchdog |
| 125 | * kill on large ones. Optional so external/test contexts compile without it; |
| 126 | * callers fall back to splitting `readFile` themselves. |
| 127 | */ |
| 128 | getFileLines?(filePath: string): string[] | null; |
| 129 | /** |
| 130 | * The method-definition nodes matching `typeName::methodName` in the language family — |
| 131 | * exactly `resolveMethodOnType`'s kind/language/qualifiedName-suffix filter, |
| 132 | * LRU-cached per (language, type, method). The uncached path re-fetches every |
| 133 | * node sharing the METHOD name (unbounded — tens of thousands on a collision- |
| 134 | * heavy Java repo) and re-scans it per ref, the dominant term in the #1122 |
| 135 | * watchdog kill. Cached entries hold only the small filtered result; per-ref |
| 136 | * disambiguation (import FQN, call-site file) stays in the caller so a cached |
| 137 | * entry is valid from any call site. Optional for external/test contexts. |
| 138 | */ |
| 139 | getMethodMatches?(typeName: string, methodName: string, language: Language): Node[]; |
| 140 | /** Get project root */ |
| 141 | getProjectRoot(): string; |
| 142 | /** Get all files */ |
| 143 | getAllFiles(): string[]; |
| 144 | /** Get nodes by lowercase name (O(1) lookup for fuzzy matching) */ |
| 145 | getNodesByLowerName(lowerName: string): Node[]; |
| 146 | /** |
| 147 | * Direct supertypes of the type named `typeName` (same language): the classes |
no outgoing calls
no test coverage detected