Skip to content

Commit 1732deb

Browse files
committed
Traverse additional nodes for global definitions
1 parent 0b765f7 commit 1732deb

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

server/src/util/declarations.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ const TREE_SITTER_TYPE_TO_LSP_KIND: { [type: string]: LSP.SymbolKind | undefined
1313
export type GlobalDeclarations = { [word: string]: LSP.SymbolInformation }
1414
export type Declarations = { [word: string]: LSP.SymbolInformation[] }
1515

16+
const GLOBAL_DECLARATION_LEAF_NODE_TYPES = new Set([
17+
'if_statement',
18+
'function_definition',
19+
])
20+
1621
/**
1722
* Returns declarations (functions or variables) from a given root node
1823
* that would be available after sourcing the file. This currently does
19-
* not include global variables defined inside function as we do not do
20-
* any flow tracing.
24+
* not include global variables defined inside if statements or functions
25+
* as we do not do any flow tracing.
2126
*
2227
* Will only return one declaration per symbol name – the latest definition.
2328
* This behavior is consistent with how Bash behaves, but differs between
@@ -35,14 +40,18 @@ export function getGlobalDeclarations({
3540
}): GlobalDeclarations {
3641
const globalDeclarations: GlobalDeclarations = {}
3742

38-
tree.rootNode.children.forEach((node) => {
43+
TreeSitterUtil.forEach(tree.rootNode, (node) => {
44+
const followChildren = !GLOBAL_DECLARATION_LEAF_NODE_TYPES.has(node.type)
45+
3946
if (TreeSitterUtil.isDefinition(node)) {
4047
const symbol = nodeToSymbolInformation({ node, uri })
4148
if (symbol) {
4249
const word = symbol.name
4350
globalDeclarations[word] = symbol
4451
}
4552
}
53+
54+
return followChildren
4655
})
4756

4857
return globalDeclarations

server/src/util/tree-sitter.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import { Range } from 'vscode-languageserver/node'
22
import { SyntaxNode } from 'web-tree-sitter'
33

4-
export function forEach(node: SyntaxNode, cb: (n: SyntaxNode) => void) {
5-
cb(node)
6-
if (node.children.length) {
7-
node.children.forEach((n) => forEach(n, cb))
4+
/**
5+
* Recursively iterate over all nodes in a tree.
6+
*
7+
* @param node The node to start iterating from
8+
* @param callback The callback to call for each node. Return false to stop following children.
9+
*/
10+
export function forEach(node: SyntaxNode, callback: (n: SyntaxNode) => void | boolean) {
11+
const followChildren = callback(node) !== false
12+
if (followChildren && node.children.length) {
13+
node.children.forEach((n) => forEach(n, callback))
814
}
915
}
1016

0 commit comments

Comments
 (0)