Skip to content

Commit 269dae7

Browse files
committed
Fix definition bugs
1 parent e94ccb1 commit 269dae7

File tree

3 files changed

+98
-25
lines changed

3 files changed

+98
-25
lines changed

languageServer/src/LanguageServer.ts

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ import {
55
_Connection,
66
TextDocumentPositionParams,
77
CodeActionParams,
8-
DefinitionParams
8+
DefinitionParams,
9+
SymbolKind,
10+
Location,
11+
Position,
12+
Range,
13+
DocumentSymbol
914
} from 'vscode-languageserver/node'
1015
import { TextDocument } from 'vscode-languageserver-textdocument'
16+
import { URI } from 'vscode-uri'
1117
import { TextDocumentWrapper } from './TextDocumentWrapper'
1218

1319
export class LanguageServer {
@@ -18,7 +24,13 @@ export class LanguageServer {
1824

1925
connection.onInitialize(() => this.onInitialize())
2026

21-
connection.onDefinition(params => this.onDefinition(params))
27+
connection.onDefinition(params => {
28+
if (!params.textDocument.uri.endsWith('dvc.yaml')) {
29+
return null
30+
}
31+
32+
return this.onDefinition(params)
33+
})
2234

2335
this.documents.listen(connection)
2436

@@ -41,26 +53,89 @@ export class LanguageServer {
4153
return new TextDocumentWrapper(doc)
4254
}
4355

56+
private getFilePathLocations(
57+
symbolUnderCursor: DocumentSymbol,
58+
allDocs: TextDocument[]
59+
) {
60+
if (symbolUnderCursor.kind !== SymbolKind.File) {
61+
return []
62+
}
63+
64+
const filePath = symbolUnderCursor.name
65+
66+
const matchingFiles = allDocs.filter(doc =>
67+
URI.file(doc.uri).fsPath.endsWith(filePath)
68+
)
69+
70+
return matchingFiles.map(doc => {
71+
const uri = doc.uri
72+
const start = Position.create(0, 0)
73+
const end = doc.positionAt(doc.getText().length - 1)
74+
const range = Range.create(start, end)
75+
76+
return Location.create(uri, range)
77+
})
78+
}
79+
80+
private getLocationsFromOtherDocuments(
81+
symbolUnderCursor: DocumentSymbol,
82+
allDocs: TextDocument[]
83+
) {
84+
const locationsAccumulator = []
85+
86+
for (const txtDoc of allDocs) {
87+
const finder = this.wrap(txtDoc)
88+
const locations = finder.findLocationsFor(symbolUnderCursor)
89+
locationsAccumulator.push(...locations)
90+
}
91+
92+
return locationsAccumulator
93+
}
94+
4495
private onDefinition(params: DefinitionParams) {
4596
const document = this.getDvcTextDocument(params)
4697
const symbolUnderCursor = document?.symbolAt(params.position)
4798

48-
if (symbolUnderCursor) {
99+
if (document && symbolUnderCursor) {
49100
const allDocs = this.documents.all()
50101
const locationsAccumulator = []
51102

52-
for (const txtDoc of allDocs) {
53-
const finder = this.wrap(txtDoc)
54-
const locations = finder.findLocationsFor(symbolUnderCursor)
55-
locationsAccumulator.push(...locations)
103+
const fileLocations = this.getFilePathLocations(
104+
symbolUnderCursor,
105+
allDocs
106+
)
107+
108+
locationsAccumulator.push(...fileLocations)
109+
110+
const locationsFromOtherDocuments = this.getLocationsFromOtherDocuments(
111+
symbolUnderCursor,
112+
allDocs
113+
)
114+
115+
locationsAccumulator.push(...locationsFromOtherDocuments)
116+
117+
const externalLocations = locationsAccumulator.filter(
118+
location => location.uri !== document.uri
119+
)
120+
121+
if (externalLocations.length > 0) {
122+
return this.arrayOrSingleResponse(externalLocations)
56123
}
57124

58-
return locationsAccumulator ?? []
125+
return this.arrayOrSingleResponse(locationsAccumulator)
59126
}
60127

61128
return null
62129
}
63130

131+
private arrayOrSingleResponse<T>(elements: T[]) {
132+
if (elements.length === 1) {
133+
return elements[0]
134+
}
135+
136+
return elements
137+
}
138+
64139
private onInitialize() {
65140
const serverCapabilities: ServerCapabilities = {
66141
definitionProvider: true

languageServer/src/TextDocumentWrapper.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,17 @@ export class TextDocumentWrapper implements ITextDocumentWrapper {
109109
) {
110110
const nodeValue = `${node.value}`
111111

112+
let symbolKind: SymbolKind = SymbolKind.String
113+
114+
if (/\.[A-Za-z]+$/.test(nodeValue)) {
115+
symbolKind = SymbolKind.File
116+
}
117+
112118
const symbolsSoFar: DocumentSymbol[] = [
113119
DocumentSymbol.create(
114120
nodeValue,
115121
undefined,
116-
SymbolKind.String,
122+
symbolKind,
117123
Range.create(this.positionAt(nodeStart), this.positionAt(nodeEnd)),
118124
Range.create(this.positionAt(nodeStart), this.positionAt(valueEnd))
119125
),

languageServer/src/test/definitions.test.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,10 @@ describe('textDocument/definitions', () => {
3333
const response = await requestDefinitions(dvcYaml, 'auc')
3434

3535
expect(response).toBeTruthy()
36-
expect(response).toStrictEqual([
37-
{
38-
range: Range.create(Position.create(5, 8), Position.create(6, 0)),
39-
uri: 'file:///dvc.yaml'
40-
},
41-
{
42-
range: Range.create(Position.create(4, 0), Position.create(4, 3)),
43-
uri: 'file:///params.yaml'
44-
}
45-
])
36+
expect(response).toStrictEqual({
37+
range: Range.create(Position.create(4, 0), Position.create(4, 3)),
38+
uri: 'file:///params.yaml'
39+
})
4640
})
4741

4842
it('should be able to read a complicated command from a stage', async () => {
@@ -56,11 +50,9 @@ describe('textDocument/definitions', () => {
5650
const response = await requestDefinitions(dvcYaml, '{item.os}')
5751

5852
expect(response).toBeTruthy()
59-
expect(response).toStrictEqual([
60-
{
61-
range: Range.create(Position.create(15, 8), Position.create(15, 10)),
62-
uri: 'file:///dvc.yaml'
63-
}
64-
])
53+
expect(response).toStrictEqual({
54+
range: Range.create(Position.create(15, 8), Position.create(15, 10)),
55+
uri: 'file:///dvc.yaml'
56+
})
6557
})
6658
})

0 commit comments

Comments
 (0)