Skip to content

Commit 77a3902

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 64a37ea commit 77a3902

File tree

5 files changed

+289
-125
lines changed

5 files changed

+289
-125
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: 116 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 { initializeParser } from '../parser'
@@ -39,15 +39,60 @@ describe('analyze', () => {
3939
describe('findDefinition', () => {
4040
it('returns an empty list if word is not found', () => {
4141
analyzer.analyze(CURRENT_URI, FIXTURES.INSTALL)
42-
const result = analyzer.findDefinition({ word: 'foobar' })
42+
const result = analyzer.findDefinition({ uri: CURRENT_URI, word: 'foobar' })
4343
expect(result).toEqual([])
4444
})
4545

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

@@ -88,6 +133,48 @@ describe('findSymbolsForFile', () => {
88133
})
89134
})
90135

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

137-
describe('findSymbolCompletions', () => {
224+
describe('findSymbolsMatchingWord', () => {
138225
it('return a list of symbols across the workspace', () => {
139226
analyzer.analyze('install.sh', FIXTURES.INSTALL)
140227
analyzer.analyze('sourcing-sh', FIXTURES.SOURCING)
141228

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

217245
expect(
218-
analyzer.findSymbolsMatchingWord({ word: 'xxxxxxxx', exactMatch: false }),
246+
analyzer.findSymbolsMatchingWord({
247+
word: 'BLU',
248+
uri: FIXTURE_URI.INSTALL,
249+
exactMatch: false,
250+
}),
219251
).toMatchInlineSnapshot(`Array []`)
220252

221253
expect(
222-
analyzer.findSymbolsMatchingWord({ word: 'BLU', exactMatch: false }),
254+
analyzer.findSymbolsMatchingWord({
255+
word: 'BLU',
256+
uri: FIXTURE_URI.SOURCING,
257+
exactMatch: false,
258+
}),
223259
).toMatchInlineSnapshot(`Array []`)
224260
})
225261
})

server/src/__tests__/server.test.ts

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,85 @@ describe('server', () => {
520520
{} as any,
521521
)
522522

523-
// they are all variables
524-
expect(Array.from(new Set(result.map((item: any) => item.kind)))).toEqual([
525-
lsp.CompletionItemKind.Variable,
526-
])
523+
expect(result).toMatchInlineSnapshot(`
524+
Array [
525+
Object {
526+
"data": Object {
527+
"name": "BOLD",
528+
"type": 3,
529+
},
530+
"documentation": undefined,
531+
"kind": 6,
532+
"label": "BOLD",
533+
},
534+
Object {
535+
"data": Object {
536+
"name": "RED",
537+
"type": 3,
538+
},
539+
"documentation": "### Variable: **RED** - *defined in ../extension.inc*",
540+
"kind": 6,
541+
"label": "RED",
542+
},
543+
Object {
544+
"data": Object {
545+
"name": "GREEN",
546+
"type": 3,
547+
},
548+
"documentation": "### Variable: **GREEN** - *defined in ../extension.inc*",
549+
"kind": 6,
550+
"label": "GREEN",
551+
},
552+
Object {
553+
"data": Object {
554+
"name": "BLUE",
555+
"type": 3,
556+
},
557+
"documentation": "### Variable: **BLUE** - *defined in ../extension.inc*",
558+
"kind": 6,
559+
"label": "BLUE",
560+
},
561+
Object {
562+
"data": Object {
563+
"name": "RESET",
564+
"type": 3,
565+
},
566+
"documentation": "### Variable: **RESET** - *defined in ../extension.inc*",
567+
"kind": 6,
568+
"label": "RESET",
569+
},
570+
Object {
571+
"data": Object {
572+
"name": "USER",
573+
"type": 3,
574+
},
575+
"documentation": "### Variable: **USER** - *defined in ../issue101.sh*",
576+
"kind": 6,
577+
"label": "USER",
578+
},
579+
Object {
580+
"data": Object {
581+
"name": "PASSWORD",
582+
"type": 3,
583+
},
584+
"documentation": "### Variable: **PASSWORD** - *defined in ../issue101.sh*",
585+
"kind": 6,
586+
"label": "PASSWORD",
587+
},
588+
Object {
589+
"data": Object {
590+
"name": "COMMENTS",
591+
"type": 3,
592+
},
593+
"documentation": "### Variable: **COMMENTS** - *defined in ../issue101.sh*
594+
595+
\`\`\`txt
596+
Having shifted twice, the rest is now comments ...
597+
\`\`\`",
598+
"kind": 6,
599+
"label": "COMMENTS",
600+
},
601+
]
602+
`)
527603
})
528604
})

0 commit comments

Comments
 (0)