Skip to content

Commit f491673

Browse files
Keen Yee LiauAndrewKushnir
authored andcommitted
feat(language-service): Implement definitionAndBoundSpan (#30125)
This PR adds the implementation for `definitionAndBoundSpan` because it's now preferred over `definition`. vscode would send this new request for `Go to definition`. As part of this PR the implementation for `definition` is refactored and simplified. Goldens for both methods are checked in. PR Close #30125
1 parent 6701250 commit f491673

4 files changed

Lines changed: 117 additions & 39 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"seq": 0,
3+
"type": "response",
4+
"command": "definitionAndBoundSpan",
5+
"request_seq": 2,
6+
"success": true,
7+
"body": {
8+
"definitions": [
9+
{
10+
"file": "${PWD}/project/app/app.component.ts",
11+
"start": {
12+
"line": 7,
13+
"offset": 30
14+
},
15+
"end": {
16+
"line": 7,
17+
"offset": 47
18+
}
19+
}
20+
],
21+
"textSpan": {
22+
"start": {
23+
"line": 7,
24+
"offset": 30
25+
},
26+
"end": {
27+
"line": 7,
28+
"offset": 47
29+
}
30+
}
31+
}
32+
}

‎integration/language_service_plugin/test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,25 @@ describe('Angular Language Service', () => {
139139
});
140140
expect(resp2).toMatchGolden('definition.json');
141141
});
142+
143+
it('should perform definitionAndBoundSpan', async () => {
144+
client.sendRequest('open', {
145+
file: `${PWD}/project/app/app.component.ts`,
146+
});
147+
148+
const resp1 = await client.sendRequest('reload', {
149+
file: `${PWD}/project/app/app.component.ts`,
150+
tmpFile: `${PWD}/project/app/app.component.ts`,
151+
}) as any;
152+
expect(resp1.command).toBe('reload');
153+
expect(resp1.success).toBe(true);
154+
155+
const resp2 = await client.sendRequest('definitionAndBoundSpan', {
156+
file: `${PWD}/project/app/app.component.ts`,
157+
line: 5,
158+
offset: 28,
159+
});
160+
expect(resp2).toMatchGolden('definitionAndBoundSpan.json');
161+
});
162+
142163
});

‎integration/language_service_plugin/yarn.lock‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44

55
"@angular/core@file:../../dist/packages-dist/core":
6-
version "7.2.0"
6+
version "8.0.0-beta.13"
77
dependencies:
88
tslib "^1.9.0"
99

1010
"@angular/language-service@file:../../dist/packages-dist/language-service":
11-
version "7.2.0"
11+
version "8.0.0-beta.13"
1212

1313
"@types/node@file:../../node_modules/@types/node":
1414
version "10.9.4"
@@ -61,16 +61,16 @@ inherits@2:
6161
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
6262
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
6363

64-
jasmine-core@~3.1.0:
65-
version "3.1.0"
66-
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.1.0.tgz#a4785e135d5df65024dfc9224953df585bd2766c"
67-
integrity sha1-pHheE11d9lAk38kiSVPfWFvSdmw=
64+
jasmine-core@~3.3.0:
65+
version "3.3.0"
66+
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.3.0.tgz#dea1cdc634bc93c7e0d4ad27185df30fa971b10e"
67+
integrity sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA==
6868

6969
"jasmine@file:../../node_modules/jasmine":
70-
version "3.1.0"
70+
version "3.3.1"
7171
dependencies:
7272
glob "^7.0.6"
73-
jasmine-core "~3.1.0"
73+
jasmine-core "~3.3.0"
7474

7575
minimatch@^3.0.4:
7676
version "3.0.4"
@@ -97,7 +97,7 @@ tslib@^1.9.0:
9797
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
9898

9999
"typescript@file:../../node_modules/typescript":
100-
version "3.2.2"
100+
version "3.4.2"
101101

102102
wrappy@1:
103103
version "1.0.2"

‎packages/language-service/src/ts_plugin.ts‎

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as ts from 'typescript'; // used as value, passed in by tsserver at run
1010
import * as tss from 'typescript/lib/tsserverlibrary'; // used as type only
1111

1212
import {createLanguageService} from './language_service';
13-
import {Completion, Diagnostic, DiagnosticMessageChain} from './types';
13+
import {Completion, Diagnostic, DiagnosticMessageChain, Location} from './types';
1414
import {TypeScriptServiceHost} from './typescript_host';
1515

1616
const projectHostMap = new WeakMap<tss.server.Project, TypeScriptServiceHost>();
@@ -156,36 +156,61 @@ export function create(info: tss.server.PluginCreateInfo): ts.LanguageService {
156156
return base;
157157
};
158158

159-
proxy.getDefinitionAtPosition = function(
160-
fileName: string, position: number): ReadonlyArray<ts.DefinitionInfo> {
161-
let base = oldLS.getDefinitionAtPosition(fileName, position);
162-
if (base && base.length) {
163-
return base;
164-
}
159+
proxy.getDefinitionAtPosition = function(fileName: string, position: number):
160+
ReadonlyArray<ts.DefinitionInfo>|
161+
undefined {
162+
const base = oldLS.getDefinitionAtPosition(fileName, position);
163+
if (base && base.length) {
164+
return base;
165+
}
166+
const ours = ls.getDefinitionAt(fileName, position);
167+
if (ours && ours.length) {
168+
return ours.map((loc: Location) => {
169+
return {
170+
fileName: loc.fileName,
171+
textSpan: {
172+
start: loc.span.start,
173+
length: loc.span.end - loc.span.start,
174+
},
175+
name: '',
176+
kind: ts.ScriptElementKind.unknown,
177+
containerName: loc.fileName,
178+
containerKind: ts.ScriptElementKind.unknown,
179+
};
180+
});
181+
}
182+
};
165183

166-
return tryOperation('get definition', () => {
167-
const ours = ls.getDefinitionAt(fileName, position);
168-
let combined;
169-
170-
if (ours && ours.length) {
171-
combined = base && base.concat([]) || [];
172-
for (const loc of ours) {
173-
combined.push({
174-
fileName: loc.fileName,
175-
textSpan: {start: loc.span.start, length: loc.span.end - loc.span.start},
176-
name: '',
177-
// TODO: remove any and fix type error.
178-
kind: 'definition' as any,
179-
containerName: loc.fileName,
180-
containerKind: 'file' as any,
181-
});
182-
}
183-
} else {
184-
combined = base;
185-
}
186-
return combined;
187-
}) || [];
188-
};
184+
proxy.getDefinitionAndBoundSpan = function(fileName: string, position: number):
185+
ts.DefinitionInfoAndBoundSpan |
186+
undefined {
187+
const base = oldLS.getDefinitionAndBoundSpan(fileName, position);
188+
if (base && base.definitions && base.definitions.length) {
189+
return base;
190+
}
191+
const ours = ls.getDefinitionAt(fileName, position);
192+
if (ours && ours.length) {
193+
return {
194+
definitions: ours.map((loc: Location) => {
195+
return {
196+
fileName: loc.fileName,
197+
textSpan: {
198+
start: loc.span.start,
199+
length: loc.span.end - loc.span.start,
200+
},
201+
name: '',
202+
kind: ts.ScriptElementKind.unknown,
203+
containerName: loc.fileName,
204+
containerKind: ts.ScriptElementKind.unknown,
205+
};
206+
}),
207+
textSpan: {
208+
start: ours[0].span.start,
209+
length: ours[0].span.end - ours[0].span.start,
210+
},
211+
};
212+
}
213+
};
189214

190215
return proxy;
191216
}

0 commit comments

Comments
 (0)