Skip to content

Commit c409127

Browse files
committed
Support variables defined using the : command
1 parent 0cd379d commit c409127

File tree

4 files changed

+139
-71
lines changed

4 files changed

+139
-71
lines changed

Diff for: server/src/__tests__/__snapshots__/analyzer.test.ts.snap

+17
Original file line numberDiff line numberDiff line change
@@ -934,5 +934,22 @@ Array [
934934
},
935935
"name": "ret",
936936
},
937+
Object {
938+
"kind": 13,
939+
"location": Object {
940+
"range": Object {
941+
"end": Object {
942+
"character": 24,
943+
"line": 273,
944+
},
945+
"start": Object {
946+
"character": 5,
947+
"line": 273,
948+
},
949+
},
950+
"uri": "dummy-uri.sh",
951+
},
952+
"name": "FILE_PATH_EXPANSION",
953+
},
937954
]
938955
`;

Diff for: server/src/__tests__/analyzer.test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,23 @@ describe('getAllVariables', () => {
979979
},
980980
"name": "RESET",
981981
},
982+
Object {
983+
"kind": 13,
984+
"location": Object {
985+
"range": Object {
986+
"end": Object {
987+
"character": 14,
988+
"line": 25,
989+
},
990+
"start": Object {
991+
"character": 5,
992+
"line": 25,
993+
},
994+
},
995+
"uri": "file://__REPO_ROOT_FOLDER__/testing/fixtures/extension.inc",
996+
},
997+
"name": "FILE_PATH",
998+
},
982999
]
9831000
`)
9841001
})

Diff for: server/src/__tests__/server.test.ts

+66-55
Original file line numberDiff line numberDiff line change
@@ -560,61 +560,72 @@ describe('server', () => {
560560

561561
// they are all variables
562562
expect(result).toMatchInlineSnapshot(`
563-
Array [
564-
Object {
565-
"data": Object {
566-
"type": 3,
567-
},
568-
"documentation": undefined,
569-
"kind": 6,
570-
"label": "BOLD",
571-
},
572-
Object {
573-
"data": Object {
574-
"type": 3,
575-
},
576-
"documentation": Object {
577-
"kind": "markdown",
578-
"value": "Variable: **RED** - *defined in extension.inc*",
579-
},
580-
"kind": 6,
581-
"label": "RED",
582-
},
583-
Object {
584-
"data": Object {
585-
"type": 3,
586-
},
587-
"documentation": Object {
588-
"kind": "markdown",
589-
"value": "Variable: **GREEN** - *defined in extension.inc*",
590-
},
591-
"kind": 6,
592-
"label": "GREEN",
593-
},
594-
Object {
595-
"data": Object {
596-
"type": 3,
597-
},
598-
"documentation": Object {
599-
"kind": "markdown",
600-
"value": "Variable: **BLUE** - *defined in extension.inc*",
601-
},
602-
"kind": 6,
603-
"label": "BLUE",
604-
},
605-
Object {
606-
"data": Object {
607-
"type": 3,
608-
},
609-
"documentation": Object {
610-
"kind": "markdown",
611-
"value": "Variable: **RESET** - *defined in extension.inc*",
612-
},
613-
"kind": 6,
614-
"label": "RESET",
615-
},
616-
]
617-
`)
563+
Array [
564+
Object {
565+
"data": Object {
566+
"type": 3,
567+
},
568+
"documentation": undefined,
569+
"kind": 6,
570+
"label": "BOLD",
571+
},
572+
Object {
573+
"data": Object {
574+
"type": 3,
575+
},
576+
"documentation": Object {
577+
"kind": "markdown",
578+
"value": "Variable: **RED** - *defined in extension.inc*",
579+
},
580+
"kind": 6,
581+
"label": "RED",
582+
},
583+
Object {
584+
"data": Object {
585+
"type": 3,
586+
},
587+
"documentation": Object {
588+
"kind": "markdown",
589+
"value": "Variable: **GREEN** - *defined in extension.inc*",
590+
},
591+
"kind": 6,
592+
"label": "GREEN",
593+
},
594+
Object {
595+
"data": Object {
596+
"type": 3,
597+
},
598+
"documentation": Object {
599+
"kind": "markdown",
600+
"value": "Variable: **BLUE** - *defined in extension.inc*",
601+
},
602+
"kind": 6,
603+
"label": "BLUE",
604+
},
605+
Object {
606+
"data": Object {
607+
"type": 3,
608+
},
609+
"documentation": Object {
610+
"kind": "markdown",
611+
"value": "Variable: **RESET** - *defined in extension.inc*",
612+
},
613+
"kind": 6,
614+
"label": "RESET",
615+
},
616+
Object {
617+
"data": Object {
618+
"type": 3,
619+
},
620+
"documentation": Object {
621+
"kind": "markdown",
622+
"value": "Variable: **FILE_PATH** - *defined in extension.inc*",
623+
},
624+
"kind": 6,
625+
"label": "FILE_PATH",
626+
},
627+
]
628+
`)
618629
})
619630
})
620631

Diff for: server/src/util/declarations.ts

+39-16
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,10 @@ export function getGlobalDeclarations({
4343
TreeSitterUtil.forEach(tree.rootNode, (node) => {
4444
const followChildren = !GLOBAL_DECLARATION_LEAF_NODE_TYPES.has(node.type)
4545

46-
if (TreeSitterUtil.isDefinition(node)) {
47-
const symbol = nodeToSymbolInformation({ node, uri })
48-
if (symbol) {
49-
const word = symbol.name
50-
globalDeclarations[word] = symbol
51-
}
46+
const symbol = getDeclarationSymbolFromNode({ node, uri })
47+
if (symbol) {
48+
const word = symbol.name
49+
globalDeclarations[word] = symbol
5250
}
5351

5452
return followChildren
@@ -71,15 +69,10 @@ export function getAllDeclarationsInTree({
7169
const symbols: LSP.SymbolInformation[] = []
7270

7371
TreeSitterUtil.forEach(tree.rootNode, (node) => {
74-
if (TreeSitterUtil.isDefinition(node)) {
75-
const symbol = nodeToSymbolInformation({ node, uri })
76-
77-
if (symbol) {
78-
symbols.push(symbol)
79-
}
72+
const symbol = getDeclarationSymbolFromNode({ node, uri })
73+
if (symbol) {
74+
symbols.push(symbol)
8075
}
81-
82-
return
8376
})
8477

8578
return symbols
@@ -122,8 +115,6 @@ export function getLocalDeclarations({
122115
uri,
123116
})
124117
}
125-
} else if (TreeSitterUtil.isDefinition(childNode)) {
126-
symbol = nodeToSymbolInformation({ node: childNode, uri })
127118
} else if (childNode.type === 'for_statement') {
128119
const variableNode = childNode.child(1)
129120
if (variableNode && variableNode.type === 'variable_name') {
@@ -134,6 +125,8 @@ export function getLocalDeclarations({
134125
uri,
135126
)
136127
}
128+
} else {
129+
symbol = getDeclarationSymbolFromNode({ node: childNode, uri })
137130
}
138131

139132
if (symbol) {
@@ -222,3 +215,33 @@ function nodeToSymbolInformation({
222215
containerName,
223216
)
224217
}
218+
219+
function getDeclarationSymbolFromNode({
220+
node,
221+
uri,
222+
}: {
223+
node: Parser.SyntaxNode
224+
uri: string
225+
}): LSP.SymbolInformation | null {
226+
if (TreeSitterUtil.isDefinition(node)) {
227+
return nodeToSymbolInformation({ node, uri })
228+
} else if (node.type === 'command' && node.text.startsWith(': ')) {
229+
// : does argument expansion and retains the side effects.
230+
// A common usage is to define default values of environment variables, e.g. : "${VARIABLE:="default"}".
231+
const variableNode = node.namedChildren
232+
.find((c) => c.type === 'string')
233+
?.namedChildren.find((c) => c.type === 'expansion')
234+
?.namedChildren.find((c) => c.type === 'variable_name')
235+
236+
if (variableNode) {
237+
return LSP.SymbolInformation.create(
238+
variableNode.text,
239+
LSP.SymbolKind.Variable,
240+
TreeSitterUtil.range(variableNode),
241+
uri,
242+
)
243+
}
244+
}
245+
246+
return null
247+
}

0 commit comments

Comments
 (0)