( node: ts.Node, kindOrGuard: ts.SyntaxKind | ((node: ts.Node) => node is T), max = Infinity, recursive = false, )
| 128 | ): T[]; |
| 129 | |
| 130 | export function findNodes<T extends ts.Node>( |
| 131 | node: ts.Node, |
| 132 | kindOrGuard: ts.SyntaxKind | ((node: ts.Node) => node is T), |
| 133 | max = Infinity, |
| 134 | recursive = false, |
| 135 | ): T[] { |
| 136 | if (!node || max == 0) { |
| 137 | return []; |
| 138 | } |
| 139 | |
| 140 | const test = |
| 141 | typeof kindOrGuard === 'function' |
| 142 | ? kindOrGuard |
| 143 | : (node: ts.Node): node is T => node.kind === kindOrGuard; |
| 144 | |
| 145 | // Caching is only supported for the entire file |
| 146 | if (ts.isSourceFile(node)) { |
| 147 | const sourceFileCache = findNodesCache.get(node); |
| 148 | if (sourceFileCache?.has(kindOrGuard)) { |
| 149 | return sourceFileCache.get(kindOrGuard) as T[]; |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | const arr: T[] = []; |
| 154 | if (test(node)) { |
| 155 | arr.push(node); |
| 156 | max--; |
| 157 | } |
| 158 | if (max > 0 && (recursive || !test(node))) { |
| 159 | for (const child of node.getChildren()) { |
| 160 | findNodes(child, test, max, recursive).forEach((node) => { |
| 161 | if (max > 0) { |
| 162 | arr.push(node); |
| 163 | } |
| 164 | max--; |
| 165 | }); |
| 166 | |
| 167 | if (max <= 0) { |
| 168 | break; |
| 169 | } |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | if (ts.isSourceFile(node)) { |
| 174 | let sourceFileCache = findNodesCache.get(node); |
| 175 | if (!sourceFileCache) { |
| 176 | sourceFileCache = new Map(); |
| 177 | findNodesCache.set(node, sourceFileCache); |
| 178 | } |
| 179 | sourceFileCache.set(kindOrGuard, arr); |
| 180 | } |
| 181 | |
| 182 | return arr; |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * Get all the nodes from a source. |
no test coverage detected