| 126 | * Returns the deepest token at a given position, reusing TypeScript's internal traversal. |
| 127 | */ |
| 128 | export function findNodeAtPosition( |
| 129 | ts: typeof tslib, |
| 130 | sourceFile: tslib.SourceFile, |
| 131 | position: number, |
| 132 | ): tslib.Node | undefined { |
| 133 | const getTokenAtPosition = ( |
| 134 | ts as unknown as { |
| 135 | getTokenAtPosition: (sf: tslib.SourceFile, pos: number) => tslib.Node |
| 136 | } |
| 137 | ).getTokenAtPosition |
| 138 | |
| 139 | if (getTokenAtPosition) { |
| 140 | return getTokenAtPosition(sourceFile, position) |
| 141 | } |
| 142 | |
| 143 | // Fallback if the internal API is removed in a future TS version |
| 144 | function find(node: tslib.Node): tslib.Node | undefined { |
| 145 | if (position >= node.getStart() && position < node.getEnd()) { |
| 146 | let found: tslib.Node | undefined |
| 147 | node.forEachChild((child) => { |
| 148 | if (!found) { |
| 149 | found = find(child) |
| 150 | } |
| 151 | }) |
| 152 | return found || node |
| 153 | } |
| 154 | return undefined |
| 155 | } |
| 156 | |
| 157 | return find(sourceFile) |
| 158 | } |