Skip to content

Commit 36a1769

Browse files
committed
Support sourcing files
- Only variables found in the sourced files are completed on - Jump to definition works on the source file path (e.g. clicking "source my-file.sh")
1 parent ff2d7b7 commit 36a1769

File tree

5 files changed

+294
-121
lines changed

5 files changed

+294
-121
lines changed

server/src/__tests__/__snapshots__/analyzer.test.ts.snap

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,6 @@ Array [
3838
]
3939
`;
4040

41-
exports[`findDefinition returns a list of locations if parameter is found 1`] = `
42-
Array [
43-
Object {
44-
"range": Object {
45-
"end": Object {
46-
"character": 37,
47-
"line": 148,
48-
},
49-
"start": Object {
50-
"character": 0,
51-
"line": 148,
52-
},
53-
},
54-
"uri": "dummy-uri.sh",
55-
},
56-
]
57-
`;
58-
5941
exports[`findReferences returns a list of locations if parameter is found 1`] = `
6042
Array [
6143
Object {

server/src/__tests__/analyzer.test.ts

Lines changed: 120 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import FIXTURES, { FIXTURE_FOLDER } from '../../../testing/fixtures'
1+
import FIXTURES, { FIXTURE_FOLDER, FIXTURE_URI } from '../../../testing/fixtures'
22
import { getMockConnection } from '../../../testing/mocks'
33
import Analyzer from '../analyser'
44
import { getDefaultConfiguration } from '../config'
@@ -42,15 +42,60 @@ describe('analyze', () => {
4242
describe('findDefinition', () => {
4343
it('returns an empty list if word is not found', () => {
4444
analyzer.analyze(CURRENT_URI, FIXTURES.INSTALL)
45-
const result = analyzer.findDefinition({ word: 'foobar' })
45+
const result = analyzer.findDefinition({ uri: CURRENT_URI, word: 'foobar' })
4646
expect(result).toEqual([])
4747
})
4848

49+
it('returns a location to a file if word is the path in a sourcing statement', () => {
50+
analyzer.analyze(CURRENT_URI, FIXTURES.SOURCING)
51+
const result = analyzer.findDefinition({
52+
uri: CURRENT_URI,
53+
word: './extension.inc',
54+
position: { character: 10, line: 2 },
55+
})
56+
expect(result).toMatchInlineSnapshot(`
57+
Array [
58+
Object {
59+
"range": Object {
60+
"end": Object {
61+
"character": 0,
62+
"line": 0,
63+
},
64+
"start": Object {
65+
"character": 0,
66+
"line": 0,
67+
},
68+
},
69+
"uri": "extension.inc",
70+
},
71+
]
72+
`)
73+
})
74+
4975
it('returns a list of locations if parameter is found', () => {
5076
analyzer.analyze(CURRENT_URI, FIXTURES.INSTALL)
51-
const result = analyzer.findDefinition({ word: 'node_version' })
77+
const result = analyzer.findDefinition({
78+
uri: CURRENT_URI,
79+
word: 'node_version',
80+
})
5281
expect(result).not.toEqual([])
53-
expect(result).toMatchSnapshot()
82+
expect(result).toMatchInlineSnapshot(`
83+
Array [
84+
Object {
85+
"range": Object {
86+
"end": Object {
87+
"character": 37,
88+
"line": 148,
89+
},
90+
"start": Object {
91+
"character": 0,
92+
"line": 148,
93+
},
94+
},
95+
"uri": "dummy-uri.sh",
96+
},
97+
]
98+
`)
5499
})
55100
})
56101

@@ -91,6 +136,52 @@ describe('findSymbolsForFile', () => {
91136
})
92137
})
93138

139+
describe('findAllSourcedUris', () => {
140+
it('returns references to sourced files', async () => {
141+
const parser = await initializeParser()
142+
const connection = getMockConnection()
143+
144+
const newAnalyzer = new Analyzer({ console: connection.console, parser })
145+
await newAnalyzer.initiateBackgroundAnalysis({
146+
backgroundAnalysisMaxFiles: defaultConfig.backgroundAnalysisMaxFiles,
147+
globPattern: defaultConfig.globPattern,
148+
rootPath: FIXTURE_FOLDER,
149+
})
150+
151+
const result = newAnalyzer.findAllSourcedUris({ uri: FIXTURE_URI.SOURCING })
152+
expect(result).toEqual(
153+
new Set([
154+
`file://${FIXTURE_FOLDER}issue101.sh`,
155+
`file://${FIXTURE_FOLDER}extension.inc`,
156+
]),
157+
)
158+
})
159+
160+
it('returns references to sourced files without file extension', async () => {
161+
const parser = await initializeParser()
162+
const connection = getMockConnection()
163+
164+
const newAnalyzer = new Analyzer({ console: connection.console, parser })
165+
await newAnalyzer.initiateBackgroundAnalysis({
166+
backgroundAnalysisMaxFiles: defaultConfig.backgroundAnalysisMaxFiles,
167+
globPattern: defaultConfig.globPattern,
168+
rootPath: FIXTURE_FOLDER,
169+
})
170+
171+
// Parse the file without extension
172+
newAnalyzer.analyze(FIXTURE_URI.MISSING_EXTENSION, FIXTURES.MISSING_EXTENSION)
173+
174+
const result = newAnalyzer.findAllSourcedUris({ uri: FIXTURE_URI.MISSING_EXTENSION })
175+
expect(result).toEqual(
176+
new Set([
177+
`file://${FIXTURE_FOLDER}extension.inc`,
178+
`file://${FIXTURE_FOLDER}issue101.sh`,
179+
`file://${FIXTURE_FOLDER}sourcing.sh`,
180+
]),
181+
)
182+
})
183+
})
184+
94185
describe('wordAtPoint', () => {
95186
it('returns current word at a given point', () => {
96187
analyzer.analyze(CURRENT_URI, FIXTURES.INSTALL)
@@ -137,92 +228,41 @@ describe('commandNameAtPoint', () => {
137228
})
138229
})
139230

140-
describe('findSymbolCompletions', () => {
231+
describe('findSymbolsMatchingWord', () => {
141232
it('return a list of symbols across the workspace', () => {
142233
analyzer.analyze('install.sh', FIXTURES.INSTALL)
143234
analyzer.analyze('sourcing-sh', FIXTURES.SOURCING)
144235

145236
expect(
146-
analyzer.findSymbolsMatchingWord({ word: 'npm_config_logl', exactMatch: false }),
147-
).toMatchInlineSnapshot(`
148-
Array [
149-
Object {
150-
"kind": 13,
151-
"location": Object {
152-
"range": Object {
153-
"end": Object {
154-
"character": 27,
155-
"line": 40,
156-
},
157-
"start": Object {
158-
"character": 0,
159-
"line": 40,
160-
},
161-
},
162-
"uri": "dummy-uri.sh",
163-
},
164-
"name": "npm_config_loglevel",
165-
},
166-
Object {
167-
"kind": 13,
168-
"location": Object {
169-
"range": Object {
170-
"end": Object {
171-
"character": 31,
172-
"line": 48,
173-
},
174-
"start": Object {
175-
"character": 2,
176-
"line": 48,
177-
},
178-
},
179-
"uri": "dummy-uri.sh",
180-
},
181-
"name": "npm_config_loglevel",
182-
},
183-
Object {
184-
"kind": 13,
185-
"location": Object {
186-
"range": Object {
187-
"end": Object {
188-
"character": 27,
189-
"line": 40,
190-
},
191-
"start": Object {
192-
"character": 0,
193-
"line": 40,
194-
},
195-
},
196-
"uri": "install.sh",
197-
},
198-
"name": "npm_config_loglevel",
199-
},
200-
Object {
201-
"kind": 13,
202-
"location": Object {
203-
"range": Object {
204-
"end": Object {
205-
"character": 31,
206-
"line": 48,
207-
},
208-
"start": Object {
209-
"character": 2,
210-
"line": 48,
211-
},
212-
},
213-
"uri": "install.sh",
214-
},
215-
"name": "npm_config_loglevel",
216-
},
217-
]
218-
`)
237+
analyzer.findSymbolsMatchingWord({
238+
word: 'npm_config_logl',
239+
uri: FIXTURE_URI.INSTALL,
240+
exactMatch: false,
241+
}),
242+
).toMatchInlineSnapshot(`Array []`)
243+
244+
expect(
245+
analyzer.findSymbolsMatchingWord({
246+
word: 'xxxxxxxx',
247+
uri: FIXTURE_URI.INSTALL,
248+
exactMatch: false,
249+
}),
250+
).toMatchInlineSnapshot(`Array []`)
219251

220252
expect(
221-
analyzer.findSymbolsMatchingWord({ word: 'xxxxxxxx', exactMatch: false }),
253+
analyzer.findSymbolsMatchingWord({
254+
word: 'BLU',
255+
uri: FIXTURE_URI.INSTALL,
256+
exactMatch: false,
257+
}),
222258
).toMatchInlineSnapshot(`Array []`)
223259

224260
expect(
225-
analyzer.findSymbolsMatchingWord({ word: 'BLU', exactMatch: false }),
261+
analyzer.findSymbolsMatchingWord({
262+
word: 'BLU',
263+
uri: FIXTURE_URI.SOURCING,
264+
exactMatch: false,
265+
}),
226266
).toMatchInlineSnapshot(`Array []`)
227267
})
228268
})

server/src/__tests__/server.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,86 @@ describe('server', () => {
511511
expect(Array.from(new Set(result.map((item: any) => item.kind)))).toEqual([
512512
LSP.CompletionItemKind.Variable,
513513
])
514+
expect(result).toMatchInlineSnapshot(`
515+
Array [
516+
Object {
517+
"data": Object {
518+
"name": "BOLD",
519+
"type": 3,
520+
},
521+
"documentation": undefined,
522+
"kind": 6,
523+
"label": "BOLD",
524+
},
525+
Object {
526+
"data": Object {
527+
"name": "RED",
528+
"type": 3,
529+
},
530+
"documentation": "### Variable: **RED** - *defined in ../extension.inc*",
531+
"kind": 6,
532+
"label": "RED",
533+
},
534+
Object {
535+
"data": Object {
536+
"name": "GREEN",
537+
"type": 3,
538+
},
539+
"documentation": "### Variable: **GREEN** - *defined in ../extension.inc*",
540+
"kind": 6,
541+
"label": "GREEN",
542+
},
543+
Object {
544+
"data": Object {
545+
"name": "BLUE",
546+
"type": 3,
547+
},
548+
"documentation": "### Variable: **BLUE** - *defined in ../extension.inc*",
549+
"kind": 6,
550+
"label": "BLUE",
551+
},
552+
Object {
553+
"data": Object {
554+
"name": "RESET",
555+
"type": 3,
556+
},
557+
"documentation": "### Variable: **RESET** - *defined in ../extension.inc*",
558+
"kind": 6,
559+
"label": "RESET",
560+
},
561+
Object {
562+
"data": Object {
563+
"name": "USER",
564+
"type": 3,
565+
},
566+
"documentation": "### Variable: **USER** - *defined in ../issue101.sh*",
567+
"kind": 6,
568+
"label": "USER",
569+
},
570+
Object {
571+
"data": Object {
572+
"name": "PASSWORD",
573+
"type": 3,
574+
},
575+
"documentation": "### Variable: **PASSWORD** - *defined in ../issue101.sh*",
576+
"kind": 6,
577+
"label": "PASSWORD",
578+
},
579+
Object {
580+
"data": Object {
581+
"name": "COMMENTS",
582+
"type": 3,
583+
},
584+
"documentation": "### Variable: **COMMENTS** - *defined in ../issue101.sh*
585+
586+
\`\`\`txt
587+
Having shifted twice, the rest is now comments ...
588+
\`\`\`",
589+
"kind": 6,
590+
"label": "COMMENTS",
591+
},
592+
]
593+
`)
514594
})
515595

516596
it('responds to onCodeAction', async () => {

0 commit comments

Comments
 (0)