typescript-language-server 0.11.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/README.md +160 -27
- package/lib/calls.d.ts +3 -3
- package/lib/calls.d.ts.map +1 -1
- package/lib/calls.js +143 -195
- package/lib/calls.js.map +1 -1
- package/lib/cli.js +9 -33
- package/lib/cli.js.map +1 -1
- package/lib/commands.d.ts +1 -0
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +4 -5
- package/lib/commands.js.map +1 -1
- package/lib/completion.d.ts +8 -11
- package/lib/completion.d.ts.map +1 -1
- package/lib/completion.js +121 -163
- package/lib/completion.js.map +1 -1
- package/lib/configuration-manager.d.ts +47 -0
- package/lib/configuration-manager.d.ts.map +1 -0
- package/lib/configuration-manager.js +105 -0
- package/lib/configuration-manager.js.map +1 -0
- package/lib/diagnostic-queue.d.ts +10 -9
- package/lib/diagnostic-queue.d.ts.map +1 -1
- package/lib/diagnostic-queue.js +13 -21
- package/lib/diagnostic-queue.js.map +1 -1
- package/lib/document-symbol.d.ts +2 -2
- package/lib/document-symbol.d.ts.map +1 -1
- package/lib/document-symbol.js +20 -25
- package/lib/document-symbol.js.map +1 -1
- package/lib/document.d.ts +1 -1
- package/lib/document.d.ts.map +1 -1
- package/lib/document.js +6 -34
- package/lib/document.js.map +1 -1
- package/lib/features/fix-all.d.ts +4 -4
- package/lib/features/fix-all.d.ts.map +1 -1
- package/lib/features/fix-all.js +104 -147
- package/lib/features/fix-all.js.map +1 -1
- package/lib/features/inlay-hints.d.ts +11 -0
- package/lib/features/inlay-hints.d.ts.map +1 -0
- package/lib/features/inlay-hints.js +70 -0
- package/lib/features/inlay-hints.js.map +1 -0
- package/lib/features/source-definition.d.ts +11 -0
- package/lib/features/source-definition.d.ts.map +1 -0
- package/lib/features/source-definition.js +50 -0
- package/lib/features/source-definition.js.map +1 -0
- package/lib/file-lsp-server.spec.js +26 -36
- package/lib/file-lsp-server.spec.js.map +1 -1
- package/lib/hover.d.ts +4 -3
- package/lib/hover.d.ts.map +1 -1
- package/lib/hover.js +53 -17
- package/lib/hover.js.map +1 -1
- package/lib/logger.d.ts +12 -4
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +37 -44
- package/lib/logger.js.map +1 -1
- package/lib/lsp-client.d.ts +13 -17
- package/lib/lsp-client.d.ts.map +1 -1
- package/lib/lsp-client.js +32 -91
- package/lib/lsp-client.js.map +1 -1
- package/lib/lsp-connection.d.ts +1 -1
- package/lib/lsp-connection.d.ts.map +1 -1
- package/lib/lsp-connection.js +13 -39
- package/lib/lsp-connection.js.map +1 -1
- package/lib/lsp-protocol.calls.proposed.d.ts +1 -1
- package/lib/lsp-protocol.calls.proposed.d.ts.map +1 -1
- package/lib/lsp-protocol.calls.proposed.js +7 -32
- package/lib/lsp-protocol.calls.proposed.js.map +1 -1
- package/lib/lsp-protocol.inlayHints.proposed.d.ts +2 -11
- package/lib/lsp-protocol.inlayHints.proposed.d.ts.map +1 -1
- package/lib/lsp-protocol.inlayHints.proposed.js +2 -28
- package/lib/lsp-protocol.inlayHints.proposed.js.map +1 -1
- package/lib/lsp-server.d.ts +27 -28
- package/lib/lsp-server.d.ts.map +1 -1
- package/lib/lsp-server.js +868 -926
- package/lib/lsp-server.js.map +1 -1
- package/lib/lsp-server.spec.js +956 -606
- package/lib/lsp-server.spec.js.map +1 -1
- package/lib/organize-imports.d.ts +3 -3
- package/lib/organize-imports.d.ts.map +1 -1
- package/lib/organize-imports.js +5 -32
- package/lib/organize-imports.js.map +1 -1
- package/lib/organize-imports.spec.js +17 -42
- package/lib/organize-imports.spec.js.map +1 -1
- package/lib/protocol-translation.d.ts +5 -10
- package/lib/protocol-translation.d.ts.map +1 -1
- package/lib/protocol-translation.js +39 -168
- package/lib/protocol-translation.js.map +1 -1
- package/lib/quickfix.d.ts +3 -3
- package/lib/quickfix.d.ts.map +1 -1
- package/lib/quickfix.js +7 -35
- package/lib/quickfix.js.map +1 -1
- package/lib/refactor.d.ts +2 -2
- package/lib/refactor.d.ts.map +1 -1
- package/lib/refactor.js +11 -36
- package/lib/refactor.js.map +1 -1
- package/lib/semantic-tokens.d.ts +1 -1
- package/lib/semantic-tokens.d.ts.map +1 -1
- package/lib/semantic-tokens.js +1 -5
- package/lib/semantic-tokens.js.map +1 -1
- package/lib/test-utils.d.ts +11 -5
- package/lib/test-utils.d.ts.map +1 -1
- package/lib/test-utils.js +137 -120
- package/lib/test-utils.js.map +1 -1
- package/lib/ts-protocol.d.ts +8 -20
- package/lib/ts-protocol.d.ts.map +1 -1
- package/lib/ts-protocol.js +4 -31
- package/lib/ts-protocol.js.map +1 -1
- package/lib/tsp-client.d.ts +46 -43
- package/lib/tsp-client.d.ts.map +1 -1
- package/lib/tsp-client.js +31 -52
- package/lib/tsp-client.js.map +1 -1
- package/lib/tsp-client.spec.js +48 -75
- package/lib/tsp-client.spec.js.map +1 -1
- package/lib/tsp-command-types.d.ts +1 -0
- package/lib/tsp-command-types.d.ts.map +1 -1
- package/lib/tsp-command-types.js +4 -8
- package/lib/tsp-command-types.js.map +1 -1
- package/lib/utils/SnippetString.js +1 -4
- package/lib/utils/SnippetString.js.map +1 -1
- package/lib/utils/api.d.ts +1 -0
- package/lib/utils/api.d.ts.map +1 -1
- package/lib/utils/api.js +3 -28
- package/lib/utils/api.js.map +1 -1
- package/lib/utils/configuration.d.ts +2 -2
- package/lib/utils/configuration.d.ts.map +1 -1
- package/lib/utils/configuration.js +1 -2
- package/lib/utils/errorCodes.js +11 -14
- package/lib/utils/errorCodes.js.map +1 -1
- package/lib/utils/fixNames.js +13 -16
- package/lib/utils/fixNames.js.map +1 -1
- package/lib/utils/modules-resolver.js +7 -34
- package/lib/utils/modules-resolver.js.map +1 -1
- package/lib/utils/modules-resolver.spec.d.ts +1 -1
- package/lib/utils/modules-resolver.spec.d.ts.map +1 -1
- package/lib/utils/modules-resolver.spec.js +11 -34
- package/lib/utils/modules-resolver.spec.js.map +1 -1
- package/lib/utils/typeConverters.d.ts +20 -2
- package/lib/utils/typeConverters.d.ts.map +1 -1
- package/lib/utils/typeConverters.js +105 -9
- package/lib/utils/typeConverters.js.map +1 -1
- package/lib/utils/types.js +2 -29
- package/lib/utils/types.js.map +1 -1
- package/lib/utils/versionProvider.d.ts +3 -3
- package/lib/utils/versionProvider.d.ts.map +1 -1
- package/lib/utils/versionProvider.js +52 -60
- package/lib/utils/versionProvider.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +3 -5
- package/lib/utils.js.map +1 -1
- package/package.json +38 -33
package/lib/lsp-server.spec.js
CHANGED
|
@@ -1,120 +1,90 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*
|
|
3
2
|
* Copyright (C) 2017, 2018 TypeFox and others.
|
|
4
3
|
*
|
|
5
4
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
|
6
5
|
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
-
if (mod && mod.__esModule) return mod;
|
|
26
|
-
var result = {};
|
|
27
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
-
__setModuleDefault(result, mod);
|
|
29
|
-
return result;
|
|
30
|
-
};
|
|
31
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
32
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
33
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
34
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
35
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
36
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
37
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
const chai = __importStar(require("chai"));
|
|
42
|
-
const lsp = __importStar(require("vscode-languageserver/node"));
|
|
43
|
-
const lspcalls = __importStar(require("./lsp-protocol.calls.proposed"));
|
|
44
|
-
const test_utils_1 = require("./test-utils");
|
|
45
|
-
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
46
|
-
const types_1 = require("./utils/types");
|
|
7
|
+
import * as chai from 'chai';
|
|
8
|
+
import fs from 'fs-extra';
|
|
9
|
+
import * as lsp from 'vscode-languageserver';
|
|
10
|
+
import * as lspcalls from './lsp-protocol.calls.proposed.js';
|
|
11
|
+
import { uri, createServer, position, lastPosition, filePath, positionAfter, readContents, toPlatformEOL } from './test-utils.js';
|
|
12
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
13
|
+
import { Commands } from './commands.js';
|
|
14
|
+
import { CodeActionKind } from './utils/types.js';
|
|
47
15
|
const assert = chai.assert;
|
|
48
16
|
const diagnostics = new Map();
|
|
49
17
|
let server;
|
|
50
|
-
before(() =>
|
|
51
|
-
server =
|
|
52
|
-
rootUri:
|
|
53
|
-
publishDiagnostics: args => diagnostics.set(args.uri, args)
|
|
18
|
+
before(async () => {
|
|
19
|
+
server = await createServer({
|
|
20
|
+
rootUri: uri(),
|
|
21
|
+
publishDiagnostics: args => diagnostics.set(args.uri, args),
|
|
54
22
|
});
|
|
55
23
|
server.didChangeConfiguration({
|
|
56
24
|
settings: {
|
|
57
25
|
completions: {
|
|
58
|
-
completeFunctionCalls: true
|
|
59
|
-
}
|
|
60
|
-
}
|
|
26
|
+
completeFunctionCalls: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
61
29
|
});
|
|
62
|
-
})
|
|
30
|
+
});
|
|
63
31
|
beforeEach(() => {
|
|
64
32
|
server.closeAll();
|
|
65
33
|
// "closeAll" triggers final publishDiagnostics with an empty list so clear last.
|
|
66
34
|
diagnostics.clear();
|
|
35
|
+
server.workspaceEdits = [];
|
|
67
36
|
});
|
|
68
37
|
after(() => {
|
|
69
38
|
server.closeAll();
|
|
39
|
+
server.shutdown();
|
|
70
40
|
});
|
|
71
41
|
describe('completion', () => {
|
|
72
|
-
it('simple test', () =>
|
|
42
|
+
it('simple test', async () => {
|
|
73
43
|
const doc = {
|
|
74
|
-
uri:
|
|
44
|
+
uri: uri('bar.ts'),
|
|
75
45
|
languageId: 'typescript',
|
|
76
46
|
version: 1,
|
|
77
47
|
text: `
|
|
78
48
|
export function foo(): void {
|
|
79
49
|
console.log('test')
|
|
80
50
|
}
|
|
81
|
-
|
|
51
|
+
`,
|
|
82
52
|
};
|
|
83
53
|
server.didOpenTextDocument({
|
|
84
|
-
textDocument: doc
|
|
54
|
+
textDocument: doc,
|
|
85
55
|
});
|
|
86
|
-
const pos =
|
|
87
|
-
const proposals =
|
|
56
|
+
const pos = position(doc, 'console');
|
|
57
|
+
const proposals = await server.completion({ textDocument: doc, position: pos });
|
|
88
58
|
assert.isNotNull(proposals);
|
|
89
59
|
assert.isAtLeast(proposals.items.length, 800);
|
|
90
60
|
const item = proposals.items.find(i => i.label === 'addEventListener');
|
|
91
61
|
assert.isDefined(item);
|
|
92
|
-
const resolvedItem =
|
|
62
|
+
const resolvedItem = await server.completionResolve(item);
|
|
93
63
|
assert.isNotTrue(resolvedItem.deprecated, 'resolved item is not deprecated');
|
|
94
64
|
assert.isDefined(resolvedItem.detail);
|
|
95
65
|
server.didCloseTextDocument({ textDocument: doc });
|
|
96
|
-
})
|
|
97
|
-
it('simple JS test', () =>
|
|
66
|
+
});
|
|
67
|
+
it('simple JS test', async () => {
|
|
98
68
|
const doc = {
|
|
99
|
-
uri:
|
|
69
|
+
uri: uri('bar.js'),
|
|
100
70
|
languageId: 'javascript',
|
|
101
71
|
version: 1,
|
|
102
72
|
text: `
|
|
103
73
|
export function foo() {
|
|
104
74
|
console.log('test')
|
|
105
75
|
}
|
|
106
|
-
|
|
76
|
+
`,
|
|
107
77
|
};
|
|
108
78
|
server.didOpenTextDocument({
|
|
109
|
-
textDocument: doc
|
|
79
|
+
textDocument: doc,
|
|
110
80
|
});
|
|
111
|
-
const pos =
|
|
112
|
-
const proposals =
|
|
81
|
+
const pos = position(doc, 'console');
|
|
82
|
+
const proposals = await server.completion({ textDocument: doc, position: pos });
|
|
113
83
|
assert.isNotNull(proposals);
|
|
114
84
|
assert.isAtLeast(proposals.items.length, 800);
|
|
115
85
|
const item = proposals.items.find(i => i.label === 'addEventListener');
|
|
116
86
|
assert.isDefined(item);
|
|
117
|
-
const resolvedItem =
|
|
87
|
+
const resolvedItem = await server.completionResolve(item);
|
|
118
88
|
assert.isDefined(resolvedItem.detail);
|
|
119
89
|
const containsInvalidCompletions = proposals.items.reduce((accumulator, current) => {
|
|
120
90
|
if (accumulator) {
|
|
@@ -126,10 +96,10 @@ describe('completion', () => {
|
|
|
126
96
|
}, false);
|
|
127
97
|
assert.isFalse(containsInvalidCompletions);
|
|
128
98
|
server.didCloseTextDocument({ textDocument: doc });
|
|
129
|
-
})
|
|
130
|
-
it('deprecated by JSDoc', () =>
|
|
99
|
+
});
|
|
100
|
+
it('deprecated by JSDoc', async () => {
|
|
131
101
|
const doc = {
|
|
132
|
-
uri:
|
|
102
|
+
uri: uri('bar.ts'),
|
|
133
103
|
languageId: 'typescript',
|
|
134
104
|
version: 1,
|
|
135
105
|
text: `
|
|
@@ -142,58 +112,58 @@ describe('completion', () => {
|
|
|
142
112
|
}
|
|
143
113
|
|
|
144
114
|
foo(); // call me
|
|
145
|
-
|
|
115
|
+
`,
|
|
146
116
|
};
|
|
147
117
|
server.didOpenTextDocument({
|
|
148
|
-
textDocument: doc
|
|
118
|
+
textDocument: doc,
|
|
149
119
|
});
|
|
150
|
-
const pos =
|
|
151
|
-
const proposals =
|
|
120
|
+
const pos = position(doc, 'foo(); // call me');
|
|
121
|
+
const proposals = await server.completion({ textDocument: doc, position: pos });
|
|
152
122
|
assert.isNotNull(proposals);
|
|
153
123
|
const item = proposals.items.find(i => i.label === 'foo');
|
|
154
124
|
assert.isDefined(item);
|
|
155
|
-
const resolvedItem =
|
|
125
|
+
const resolvedItem = await server.completionResolve(item);
|
|
156
126
|
assert.isDefined(resolvedItem.detail);
|
|
157
127
|
assert.isArray(resolvedItem.tags);
|
|
158
128
|
assert.include(resolvedItem.tags, lsp.CompletionItemTag.Deprecated, 'resolved item is deprecated');
|
|
159
129
|
server.didCloseTextDocument({ textDocument: doc });
|
|
160
|
-
})
|
|
161
|
-
it('incorrect source location', () =>
|
|
130
|
+
});
|
|
131
|
+
it('incorrect source location', async () => {
|
|
162
132
|
const doc = {
|
|
163
|
-
uri:
|
|
133
|
+
uri: uri('bar.ts'),
|
|
164
134
|
languageId: 'typescript',
|
|
165
135
|
version: 1,
|
|
166
136
|
text: `
|
|
167
137
|
export function foo(): void {
|
|
168
138
|
console.log('test')
|
|
169
139
|
}
|
|
170
|
-
|
|
140
|
+
`,
|
|
171
141
|
};
|
|
172
142
|
server.didOpenTextDocument({
|
|
173
|
-
textDocument: doc
|
|
143
|
+
textDocument: doc,
|
|
174
144
|
});
|
|
175
|
-
const pos =
|
|
176
|
-
const proposals =
|
|
145
|
+
const pos = position(doc, 'foo');
|
|
146
|
+
const proposals = await server.completion({ textDocument: doc, position: pos });
|
|
177
147
|
assert.isNull(proposals);
|
|
178
148
|
server.didCloseTextDocument({ textDocument: doc });
|
|
179
|
-
})
|
|
180
|
-
it('includes completions from global modules', () =>
|
|
149
|
+
});
|
|
150
|
+
it('includes completions from global modules', async () => {
|
|
181
151
|
const doc = {
|
|
182
|
-
uri:
|
|
152
|
+
uri: uri('bar.ts'),
|
|
183
153
|
languageId: 'typescript',
|
|
184
154
|
version: 1,
|
|
185
|
-
text: 'pathex'
|
|
155
|
+
text: 'pathex',
|
|
186
156
|
};
|
|
187
157
|
server.didOpenTextDocument({ textDocument: doc });
|
|
188
|
-
const proposals =
|
|
158
|
+
const proposals = await server.completion({ textDocument: doc, position: position(doc, 'ex') });
|
|
189
159
|
assert.isNotNull(proposals);
|
|
190
160
|
const pathExistsCompletion = proposals.items.find(completion => completion.label === 'pathExists');
|
|
191
161
|
assert.isDefined(pathExistsCompletion);
|
|
192
162
|
server.didCloseTextDocument({ textDocument: doc });
|
|
193
|
-
})
|
|
194
|
-
it('includes completions with invalid identifier names', () =>
|
|
163
|
+
});
|
|
164
|
+
it('includes completions with invalid identifier names', async () => {
|
|
195
165
|
const doc = {
|
|
196
|
-
uri:
|
|
166
|
+
uri: uri('bar.ts'),
|
|
197
167
|
languageId: 'typescript',
|
|
198
168
|
version: 1,
|
|
199
169
|
text: `
|
|
@@ -203,159 +173,159 @@ describe('completion', () => {
|
|
|
203
173
|
|
|
204
174
|
const foo: Foo
|
|
205
175
|
foo.i
|
|
206
|
-
|
|
176
|
+
`,
|
|
207
177
|
};
|
|
208
178
|
server.didOpenTextDocument({ textDocument: doc });
|
|
209
|
-
const proposals =
|
|
179
|
+
const proposals = await server.completion({ textDocument: doc, position: positionAfter(doc, '.i') });
|
|
210
180
|
assert.isNotNull(proposals);
|
|
211
181
|
const completion = proposals.items.find(completion => completion.label === 'invalid-identifier-name');
|
|
212
182
|
assert.isDefined(completion);
|
|
213
183
|
assert.isDefined(completion.textEdit);
|
|
214
184
|
assert.equal(completion.textEdit.newText, '["invalid-identifier-name"]');
|
|
215
185
|
server.didCloseTextDocument({ textDocument: doc });
|
|
216
|
-
})
|
|
217
|
-
it('includes detail field with package name for auto-imports', () =>
|
|
186
|
+
});
|
|
187
|
+
it('includes detail field with package name for auto-imports', async () => {
|
|
218
188
|
const doc = {
|
|
219
|
-
uri:
|
|
189
|
+
uri: uri('bar.ts'),
|
|
220
190
|
languageId: 'typescript',
|
|
221
191
|
version: 1,
|
|
222
|
-
text: 'readFile'
|
|
192
|
+
text: 'readFile',
|
|
223
193
|
};
|
|
224
194
|
server.didOpenTextDocument({ textDocument: doc });
|
|
225
|
-
const proposals =
|
|
195
|
+
const proposals = await server.completion({ textDocument: doc, position: positionAfter(doc, 'readFile') });
|
|
226
196
|
assert.isNotNull(proposals);
|
|
227
197
|
const completion = proposals.items.find(completion => completion.label === 'readFile');
|
|
228
198
|
assert.isDefined(completion);
|
|
229
199
|
assert.strictEqual(completion.detail, 'fs');
|
|
230
200
|
assert.strictEqual(completion.insertTextFormat, /* snippet */ 2);
|
|
231
201
|
server.didCloseTextDocument({ textDocument: doc });
|
|
232
|
-
})
|
|
233
|
-
it('resolves text edit for auto-import completion', () =>
|
|
202
|
+
});
|
|
203
|
+
it('resolves text edit for auto-import completion', async () => {
|
|
234
204
|
const doc = {
|
|
235
|
-
uri:
|
|
205
|
+
uri: uri('bar.ts'),
|
|
236
206
|
languageId: 'typescript',
|
|
237
207
|
version: 1,
|
|
238
|
-
text: 'readFile'
|
|
208
|
+
text: 'readFile',
|
|
239
209
|
};
|
|
240
210
|
server.didOpenTextDocument({ textDocument: doc });
|
|
241
|
-
const proposals =
|
|
211
|
+
const proposals = await server.completion({ textDocument: doc, position: positionAfter(doc, 'readFile') });
|
|
242
212
|
assert.isNotNull(proposals);
|
|
243
213
|
const completion = proposals.items.find(completion => completion.label === 'readFile');
|
|
244
214
|
assert.isDefined(completion);
|
|
245
|
-
const resolvedItem =
|
|
215
|
+
const resolvedItem = await server.completionResolve(completion);
|
|
246
216
|
assert.deepEqual(resolvedItem.additionalTextEdits, [
|
|
247
217
|
{
|
|
248
218
|
newText: 'import { readFile } from "fs";\n\n',
|
|
249
219
|
range: {
|
|
250
220
|
end: {
|
|
251
221
|
character: 0,
|
|
252
|
-
line: 0
|
|
222
|
+
line: 0,
|
|
253
223
|
},
|
|
254
224
|
start: {
|
|
255
225
|
character: 0,
|
|
256
|
-
line: 0
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
226
|
+
line: 0,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
},
|
|
260
230
|
]);
|
|
261
231
|
server.didCloseTextDocument({ textDocument: doc });
|
|
262
|
-
})
|
|
263
|
-
it('resolves text edit for auto-import completion in right format', () =>
|
|
232
|
+
});
|
|
233
|
+
it('resolves text edit for auto-import completion in right format', async () => {
|
|
264
234
|
server.didChangeConfiguration({
|
|
265
235
|
settings: {
|
|
266
236
|
typescript: {
|
|
267
237
|
format: {
|
|
268
238
|
semicolons: 'remove',
|
|
269
|
-
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: false
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
239
|
+
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: false,
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
},
|
|
273
243
|
});
|
|
274
244
|
const doc = {
|
|
275
|
-
uri:
|
|
245
|
+
uri: uri('bar.ts'),
|
|
276
246
|
languageId: 'typescript',
|
|
277
247
|
version: 1,
|
|
278
|
-
text: 'readFile'
|
|
248
|
+
text: 'readFile',
|
|
279
249
|
};
|
|
280
250
|
server.didOpenTextDocument({ textDocument: doc });
|
|
281
|
-
const proposals =
|
|
251
|
+
const proposals = await server.completion({ textDocument: doc, position: positionAfter(doc, 'readFile') });
|
|
282
252
|
assert.isNotNull(proposals);
|
|
283
253
|
const completion = proposals.items.find(completion => completion.label === 'readFile');
|
|
284
254
|
assert.isDefined(completion);
|
|
285
|
-
const resolvedItem =
|
|
255
|
+
const resolvedItem = await server.completionResolve(completion);
|
|
286
256
|
assert.deepEqual(resolvedItem.additionalTextEdits, [
|
|
287
257
|
{
|
|
288
258
|
newText: 'import {readFile} from "fs"\n\n',
|
|
289
259
|
range: {
|
|
290
260
|
end: {
|
|
291
261
|
character: 0,
|
|
292
|
-
line: 0
|
|
262
|
+
line: 0,
|
|
293
263
|
},
|
|
294
264
|
start: {
|
|
295
265
|
character: 0,
|
|
296
|
-
line: 0
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
266
|
+
line: 0,
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
300
270
|
]);
|
|
301
271
|
server.didCloseTextDocument({ textDocument: doc });
|
|
302
272
|
server.didChangeConfiguration({
|
|
303
273
|
settings: {
|
|
304
274
|
completions: {
|
|
305
|
-
completeFunctionCalls: true
|
|
275
|
+
completeFunctionCalls: true,
|
|
306
276
|
},
|
|
307
277
|
typescript: {
|
|
308
278
|
format: {
|
|
309
279
|
semicolons: 'ignore',
|
|
310
|
-
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
280
|
+
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
314
284
|
});
|
|
315
|
-
})
|
|
316
|
-
it('resolves a snippet for method completion', () =>
|
|
285
|
+
});
|
|
286
|
+
it('resolves a snippet for method completion', async () => {
|
|
317
287
|
const doc = {
|
|
318
|
-
uri:
|
|
288
|
+
uri: uri('bar.ts'),
|
|
319
289
|
languageId: 'typescript',
|
|
320
290
|
version: 1,
|
|
321
291
|
text: `
|
|
322
292
|
import fs from 'fs'
|
|
323
293
|
fs.readFile
|
|
324
|
-
|
|
294
|
+
`,
|
|
325
295
|
};
|
|
326
296
|
server.didOpenTextDocument({ textDocument: doc });
|
|
327
|
-
const proposals =
|
|
297
|
+
const proposals = await server.completion({ textDocument: doc, position: positionAfter(doc, 'readFile') });
|
|
328
298
|
assert.isNotNull(proposals);
|
|
329
299
|
const completion = proposals.items.find(completion => completion.label === 'readFile');
|
|
330
300
|
assert.strictEqual(completion.insertTextFormat, lsp.InsertTextFormat.Snippet);
|
|
331
301
|
assert.strictEqual(completion.label, 'readFile');
|
|
332
|
-
const resolvedItem =
|
|
302
|
+
const resolvedItem = await server.completionResolve(completion);
|
|
333
303
|
assert.strictEqual(resolvedItem.insertTextFormat, lsp.InsertTextFormat.Snippet);
|
|
334
304
|
// eslint-disable-next-line no-template-curly-in-string
|
|
335
305
|
assert.strictEqual(resolvedItem.insertText, 'readFile(${1:path}, ${2:options}, ${3:callback})$0');
|
|
336
306
|
server.didCloseTextDocument({ textDocument: doc });
|
|
337
|
-
})
|
|
338
|
-
it('includes textEdit for string completion', () =>
|
|
307
|
+
});
|
|
308
|
+
it('includes textEdit for string completion', async () => {
|
|
339
309
|
const doc = {
|
|
340
|
-
uri:
|
|
310
|
+
uri: uri('bar.ts'),
|
|
341
311
|
languageId: 'typescript',
|
|
342
312
|
version: 1,
|
|
343
313
|
text: `
|
|
344
314
|
function test(value: "fs/read" | "hello/world") {
|
|
345
315
|
return true;
|
|
346
316
|
}
|
|
347
|
-
|
|
317
|
+
|
|
348
318
|
test("fs/")
|
|
349
|
-
|
|
319
|
+
`,
|
|
350
320
|
};
|
|
351
321
|
server.didOpenTextDocument({ textDocument: doc });
|
|
352
|
-
const proposals =
|
|
322
|
+
const proposals = await server.completion({
|
|
353
323
|
textDocument: doc,
|
|
354
|
-
position:
|
|
324
|
+
position: positionAfter(doc, 'test("fs/'),
|
|
355
325
|
context: {
|
|
356
326
|
triggerCharacter: '/',
|
|
357
|
-
triggerKind: 2
|
|
358
|
-
}
|
|
327
|
+
triggerKind: 2,
|
|
328
|
+
},
|
|
359
329
|
});
|
|
360
330
|
assert.isNotNull(proposals);
|
|
361
331
|
const completion = proposals.items.find(completion => completion.label === 'fs/read');
|
|
@@ -363,38 +333,183 @@ describe('completion', () => {
|
|
|
363
333
|
assert.deepStrictEqual(completion.textEdit, {
|
|
364
334
|
range: {
|
|
365
335
|
start: { line: 5, character: 20 },
|
|
366
|
-
end: { line: 5, character: 23 }
|
|
336
|
+
end: { line: 5, character: 23 },
|
|
337
|
+
},
|
|
338
|
+
newText: 'fs/read',
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
it('includes labelDetails with useLabelDetailsInCompletionEntries enabled', async () => {
|
|
342
|
+
const doc = {
|
|
343
|
+
uri: uri('foo.ts'),
|
|
344
|
+
languageId: 'typescript',
|
|
345
|
+
version: 1,
|
|
346
|
+
text: `
|
|
347
|
+
interface IFoo {
|
|
348
|
+
bar(x: number): void;
|
|
349
|
+
}
|
|
350
|
+
const obj: IFoo = {
|
|
351
|
+
/*a*/
|
|
352
|
+
}
|
|
353
|
+
`,
|
|
354
|
+
};
|
|
355
|
+
server.didOpenTextDocument({ textDocument: doc });
|
|
356
|
+
const proposals = await server.completion({
|
|
357
|
+
textDocument: doc,
|
|
358
|
+
position: positionAfter(doc, '/*a*/'),
|
|
359
|
+
});
|
|
360
|
+
assert.isNotNull(proposals);
|
|
361
|
+
assert.lengthOf(proposals.items, 2);
|
|
362
|
+
assert.deepInclude(proposals.items[0], {
|
|
363
|
+
label: 'bar',
|
|
364
|
+
kind: 2,
|
|
365
|
+
insertTextFormat: 2,
|
|
366
|
+
});
|
|
367
|
+
assert.deepInclude(proposals.items[1], {
|
|
368
|
+
label: 'bar',
|
|
369
|
+
labelDetails: {
|
|
370
|
+
detail: '(x)',
|
|
367
371
|
},
|
|
368
|
-
|
|
372
|
+
kind: 2,
|
|
373
|
+
insertTextFormat: 2,
|
|
374
|
+
insertText: toPlatformEOL('bar(x) {\n $0\n},'),
|
|
369
375
|
});
|
|
370
|
-
})
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
describe('definition', () => {
|
|
379
|
+
it('goes to definition', async () => {
|
|
380
|
+
// NOTE: This test needs to reference files that physically exist for the feature to work.
|
|
381
|
+
const indexUri = uri('source-definition', 'index.ts');
|
|
382
|
+
const indexDoc = {
|
|
383
|
+
uri: indexUri,
|
|
384
|
+
languageId: 'typescript',
|
|
385
|
+
version: 1,
|
|
386
|
+
text: readContents(filePath('source-definition', 'index.ts')),
|
|
387
|
+
};
|
|
388
|
+
server.didOpenTextDocument({ textDocument: indexDoc });
|
|
389
|
+
const definitions = await server.definition({
|
|
390
|
+
textDocument: indexDoc,
|
|
391
|
+
position: position(indexDoc, 'a/*identifier*/'),
|
|
392
|
+
});
|
|
393
|
+
assert.isArray(definitions);
|
|
394
|
+
assert.equal(definitions.length, 1);
|
|
395
|
+
assert.deepEqual(definitions[0], {
|
|
396
|
+
uri: uri('source-definition', 'a.d.ts'),
|
|
397
|
+
range: {
|
|
398
|
+
start: {
|
|
399
|
+
line: 0,
|
|
400
|
+
character: 21,
|
|
401
|
+
},
|
|
402
|
+
end: {
|
|
403
|
+
line: 0,
|
|
404
|
+
character: 22,
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
describe('definition (definition link supported)', () => {
|
|
411
|
+
let localServer;
|
|
412
|
+
before(async () => {
|
|
413
|
+
const clientCapabilitiesOverride = {
|
|
414
|
+
textDocument: {
|
|
415
|
+
definition: {
|
|
416
|
+
linkSupport: true,
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
localServer = await createServer({
|
|
421
|
+
rootUri: uri('source-definition'),
|
|
422
|
+
publishDiagnostics: args => diagnostics.set(args.uri, args),
|
|
423
|
+
clientCapabilitiesOverride,
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
beforeEach(() => {
|
|
427
|
+
localServer.closeAll();
|
|
428
|
+
// "closeAll" triggers final publishDiagnostics with an empty list so clear last.
|
|
429
|
+
diagnostics.clear();
|
|
430
|
+
localServer.workspaceEdits = [];
|
|
431
|
+
});
|
|
432
|
+
after(() => {
|
|
433
|
+
localServer.closeAll();
|
|
434
|
+
localServer.shutdown();
|
|
435
|
+
});
|
|
436
|
+
it('goes to definition', async () => {
|
|
437
|
+
// NOTE: This test needs to reference files that physically exist for the feature to work.
|
|
438
|
+
const indexUri = uri('source-definition', 'index.ts');
|
|
439
|
+
const indexDoc = {
|
|
440
|
+
uri: indexUri,
|
|
441
|
+
languageId: 'typescript',
|
|
442
|
+
version: 1,
|
|
443
|
+
text: readContents(filePath('source-definition', 'index.ts')),
|
|
444
|
+
};
|
|
445
|
+
localServer.didOpenTextDocument({ textDocument: indexDoc });
|
|
446
|
+
const definitions = await localServer.definition({
|
|
447
|
+
textDocument: indexDoc,
|
|
448
|
+
position: position(indexDoc, 'a/*identifier*/'),
|
|
449
|
+
});
|
|
450
|
+
assert.isArray(definitions);
|
|
451
|
+
assert.equal(definitions.length, 1);
|
|
452
|
+
assert.deepEqual(definitions[0], {
|
|
453
|
+
originSelectionRange: {
|
|
454
|
+
start: {
|
|
455
|
+
line: 1,
|
|
456
|
+
character: 0,
|
|
457
|
+
},
|
|
458
|
+
end: {
|
|
459
|
+
line: 1,
|
|
460
|
+
character: 1,
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
targetRange: {
|
|
464
|
+
start: {
|
|
465
|
+
line: 0,
|
|
466
|
+
character: 0,
|
|
467
|
+
},
|
|
468
|
+
end: {
|
|
469
|
+
line: 0,
|
|
470
|
+
character: 30,
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
targetUri: uri('source-definition', 'a.d.ts'),
|
|
474
|
+
targetSelectionRange: {
|
|
475
|
+
start: {
|
|
476
|
+
line: 0,
|
|
477
|
+
character: 21,
|
|
478
|
+
},
|
|
479
|
+
end: {
|
|
480
|
+
line: 0,
|
|
481
|
+
character: 22,
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
});
|
|
485
|
+
});
|
|
371
486
|
});
|
|
372
487
|
describe('diagnostics', () => {
|
|
373
|
-
it('simple test', () =>
|
|
488
|
+
it('simple test', async () => {
|
|
374
489
|
const doc = {
|
|
375
|
-
uri:
|
|
490
|
+
uri: uri('diagnosticsBar.ts'),
|
|
376
491
|
languageId: 'typescript',
|
|
377
492
|
version: 1,
|
|
378
493
|
text: `
|
|
379
494
|
export function foo(): void {
|
|
380
495
|
missing('test')
|
|
381
496
|
}
|
|
382
|
-
|
|
497
|
+
`,
|
|
383
498
|
};
|
|
384
499
|
server.didOpenTextDocument({
|
|
385
|
-
textDocument: doc
|
|
500
|
+
textDocument: doc,
|
|
386
501
|
});
|
|
387
|
-
|
|
388
|
-
|
|
502
|
+
await server.requestDiagnostics();
|
|
503
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
389
504
|
const resultsForFile = diagnostics.get(doc.uri);
|
|
390
505
|
assert.isDefined(resultsForFile);
|
|
391
506
|
const fileDiagnostics = resultsForFile.diagnostics;
|
|
392
507
|
assert.equal(fileDiagnostics.length, 1);
|
|
393
508
|
assert.equal("Cannot find name 'missing'.", fileDiagnostics[0].message);
|
|
394
|
-
})
|
|
395
|
-
it('supports diagnostic tags', () =>
|
|
509
|
+
});
|
|
510
|
+
it('supports diagnostic tags', async () => {
|
|
396
511
|
const doc = {
|
|
397
|
-
uri:
|
|
512
|
+
uri: uri('diagnosticsBar.ts'),
|
|
398
513
|
languageId: 'typescript',
|
|
399
514
|
version: 1,
|
|
400
515
|
text: `
|
|
@@ -403,13 +518,13 @@ describe('diagnostics', () => {
|
|
|
403
518
|
/** @deprecated */
|
|
404
519
|
function foo(): void {}
|
|
405
520
|
foo();
|
|
406
|
-
|
|
521
|
+
`,
|
|
407
522
|
};
|
|
408
523
|
server.didOpenTextDocument({
|
|
409
|
-
textDocument: doc
|
|
524
|
+
textDocument: doc,
|
|
410
525
|
});
|
|
411
|
-
|
|
412
|
-
|
|
526
|
+
await server.requestDiagnostics();
|
|
527
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
413
528
|
const resultsForFile = diagnostics.get(doc.uri);
|
|
414
529
|
assert.isDefined(resultsForFile);
|
|
415
530
|
const fileDiagnostics = resultsForFile.diagnostics;
|
|
@@ -420,36 +535,36 @@ describe('diagnostics', () => {
|
|
|
420
535
|
const deprecatedDiagnostic = fileDiagnostics.find(d => d.code === 6387);
|
|
421
536
|
assert.isDefined(deprecatedDiagnostic);
|
|
422
537
|
assert.deepEqual(deprecatedDiagnostic.tags, [lsp.DiagnosticTag.Deprecated]);
|
|
423
|
-
})
|
|
424
|
-
it('multiple files test', () =>
|
|
538
|
+
});
|
|
539
|
+
it('multiple files test', async () => {
|
|
425
540
|
const doc = {
|
|
426
|
-
uri:
|
|
541
|
+
uri: uri('multipleFileDiagnosticsBar.ts'),
|
|
427
542
|
languageId: 'typescript',
|
|
428
543
|
version: 1,
|
|
429
544
|
text: `
|
|
430
545
|
export function bar(): void {
|
|
431
546
|
missing('test')
|
|
432
547
|
}
|
|
433
|
-
|
|
548
|
+
`,
|
|
434
549
|
};
|
|
435
550
|
const doc2 = {
|
|
436
|
-
uri:
|
|
551
|
+
uri: uri('multipleFileDiagnosticsFoo.ts'),
|
|
437
552
|
languageId: 'typescript',
|
|
438
553
|
version: 1,
|
|
439
554
|
text: `
|
|
440
555
|
export function foo(): void {
|
|
441
556
|
missing('test')
|
|
442
557
|
}
|
|
443
|
-
|
|
558
|
+
`,
|
|
444
559
|
};
|
|
445
560
|
server.didOpenTextDocument({
|
|
446
|
-
textDocument: doc
|
|
561
|
+
textDocument: doc,
|
|
447
562
|
});
|
|
448
563
|
server.didOpenTextDocument({
|
|
449
|
-
textDocument: doc2
|
|
564
|
+
textDocument: doc2,
|
|
450
565
|
});
|
|
451
|
-
|
|
452
|
-
|
|
566
|
+
await server.requestDiagnostics();
|
|
567
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
453
568
|
assert.equal(diagnostics.size, 2);
|
|
454
569
|
const diagnosticsForDoc = diagnostics.get(doc.uri);
|
|
455
570
|
const diagnosticsForDoc2 = diagnostics.get(doc2.uri);
|
|
@@ -457,17 +572,17 @@ describe('diagnostics', () => {
|
|
|
457
572
|
assert.isDefined(diagnosticsForDoc2);
|
|
458
573
|
assert.equal(diagnosticsForDoc.diagnostics.length, 1, JSON.stringify(diagnostics));
|
|
459
574
|
assert.equal(diagnosticsForDoc2.diagnostics.length, 1, JSON.stringify(diagnostics));
|
|
460
|
-
})
|
|
461
|
-
it('code 6133 (ununsed variable) is ignored', () =>
|
|
575
|
+
});
|
|
576
|
+
it('code 6133 (ununsed variable) is ignored', async () => {
|
|
462
577
|
server.didChangeConfiguration({
|
|
463
578
|
settings: {
|
|
464
579
|
diagnostics: {
|
|
465
|
-
ignoredCodes: [6133]
|
|
466
|
-
}
|
|
467
|
-
}
|
|
580
|
+
ignoredCodes: [6133],
|
|
581
|
+
},
|
|
582
|
+
},
|
|
468
583
|
});
|
|
469
584
|
const doc = {
|
|
470
|
-
uri:
|
|
585
|
+
uri: uri('diagnosticsBar2.ts'),
|
|
471
586
|
languageId: 'typescript',
|
|
472
587
|
version: 1,
|
|
473
588
|
text: `
|
|
@@ -475,23 +590,23 @@ describe('diagnostics', () => {
|
|
|
475
590
|
const x = 42;
|
|
476
591
|
return 1;
|
|
477
592
|
}
|
|
478
|
-
|
|
593
|
+
`,
|
|
479
594
|
};
|
|
480
595
|
server.didOpenTextDocument({
|
|
481
|
-
textDocument: doc
|
|
596
|
+
textDocument: doc,
|
|
482
597
|
});
|
|
483
|
-
|
|
484
|
-
|
|
598
|
+
await server.requestDiagnostics();
|
|
599
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
485
600
|
const diagnosticsForThisFile = diagnostics.get(doc.uri);
|
|
486
601
|
assert.isDefined(diagnosticsForThisFile);
|
|
487
602
|
const fileDiagnostics = diagnosticsForThisFile.diagnostics;
|
|
488
603
|
assert.equal(fileDiagnostics.length, 0, JSON.stringify(fileDiagnostics));
|
|
489
|
-
})
|
|
604
|
+
});
|
|
490
605
|
});
|
|
491
606
|
describe('document symbol', () => {
|
|
492
|
-
it('simple test', () =>
|
|
607
|
+
it('simple test', async () => {
|
|
493
608
|
const doc = {
|
|
494
|
-
uri:
|
|
609
|
+
uri: uri('bar.ts'),
|
|
495
610
|
languageId: 'typescript',
|
|
496
611
|
version: 1,
|
|
497
612
|
text: `
|
|
@@ -500,24 +615,21 @@ describe('document symbol', () => {
|
|
|
500
615
|
public myFunction(arg: string) {
|
|
501
616
|
}
|
|
502
617
|
}
|
|
503
|
-
|
|
618
|
+
`,
|
|
504
619
|
};
|
|
505
620
|
server.didOpenTextDocument({
|
|
506
|
-
textDocument: doc
|
|
507
|
-
});
|
|
508
|
-
const symbols = yield server.documentSymbol({
|
|
509
621
|
textDocument: doc,
|
|
510
|
-
position: lsp.Position.create(1, 1)
|
|
511
622
|
});
|
|
623
|
+
const symbols = await server.documentSymbol({ textDocument: doc });
|
|
512
624
|
assert.equal(`
|
|
513
625
|
Foo
|
|
514
626
|
foo
|
|
515
627
|
myFunction
|
|
516
628
|
`, symbolsAsString(symbols) + '\n');
|
|
517
|
-
})
|
|
518
|
-
it('merges interfaces correctly', () =>
|
|
629
|
+
});
|
|
630
|
+
it('merges interfaces correctly', async () => {
|
|
519
631
|
const doc = {
|
|
520
|
-
uri:
|
|
632
|
+
uri: uri('bar.ts'),
|
|
521
633
|
languageId: 'typescript',
|
|
522
634
|
version: 1,
|
|
523
635
|
text: `
|
|
@@ -528,15 +640,12 @@ interface Box {
|
|
|
528
640
|
|
|
529
641
|
interface Box {
|
|
530
642
|
scale: number;
|
|
531
|
-
}
|
|
643
|
+
}`,
|
|
532
644
|
};
|
|
533
645
|
server.didOpenTextDocument({
|
|
534
|
-
textDocument: doc
|
|
535
|
-
});
|
|
536
|
-
const symbols = yield server.documentSymbol({
|
|
537
646
|
textDocument: doc,
|
|
538
|
-
position: lsp.Position.create(1, 1)
|
|
539
647
|
});
|
|
648
|
+
const symbols = await server.documentSymbol({ textDocument: doc });
|
|
540
649
|
assert.equal(`
|
|
541
650
|
Box
|
|
542
651
|
height
|
|
@@ -544,10 +653,10 @@ Box
|
|
|
544
653
|
Box
|
|
545
654
|
scale
|
|
546
655
|
`, symbolsAsString(symbols) + '\n');
|
|
547
|
-
})
|
|
548
|
-
it('duplication test', () =>
|
|
656
|
+
});
|
|
657
|
+
it('duplication test', async () => {
|
|
549
658
|
const doc = {
|
|
550
|
-
uri:
|
|
659
|
+
uri: uri('bar.ts'),
|
|
551
660
|
languageId: 'typescript',
|
|
552
661
|
version: 1,
|
|
553
662
|
text: `
|
|
@@ -561,15 +670,12 @@ Box
|
|
|
561
670
|
public myFunction(arg: string) {
|
|
562
671
|
}
|
|
563
672
|
}
|
|
564
|
-
|
|
673
|
+
`,
|
|
565
674
|
};
|
|
566
675
|
server.didOpenTextDocument({
|
|
567
|
-
textDocument: doc
|
|
568
|
-
});
|
|
569
|
-
const symbols = yield server.documentSymbol({
|
|
570
676
|
textDocument: doc,
|
|
571
|
-
position: lsp.Position.create(1, 1)
|
|
572
677
|
});
|
|
678
|
+
const symbols = await server.documentSymbol({ textDocument: doc });
|
|
573
679
|
const expectation = `
|
|
574
680
|
Foo
|
|
575
681
|
foo
|
|
@@ -583,7 +689,7 @@ Foo
|
|
|
583
689
|
assert.deepEqual(symbols[0].range, { start: { line: 1, character: 8 }, end: { line: 5, character: 9 } });
|
|
584
690
|
assert.deepEqual(symbols[1].selectionRange, symbols[1].range);
|
|
585
691
|
assert.deepEqual(symbols[1].range, { start: { line: 6, character: 8 }, end: { line: 10, character: 9 } });
|
|
586
|
-
})
|
|
692
|
+
});
|
|
587
693
|
});
|
|
588
694
|
function symbolsAsString(symbols, indentation = '') {
|
|
589
695
|
return symbols.map(symbol => {
|
|
@@ -602,18 +708,18 @@ function symbolsAsString(symbols, indentation = '') {
|
|
|
602
708
|
}).join('');
|
|
603
709
|
}
|
|
604
710
|
describe('editing', () => {
|
|
605
|
-
it('open and change', () =>
|
|
711
|
+
it('open and change', async () => {
|
|
606
712
|
const doc = {
|
|
607
|
-
uri:
|
|
713
|
+
uri: uri('openAndChangeBar.ts'),
|
|
608
714
|
languageId: 'typescript',
|
|
609
715
|
version: 1,
|
|
610
716
|
text: `
|
|
611
717
|
export function foo(): void {
|
|
612
718
|
}
|
|
613
|
-
|
|
719
|
+
`,
|
|
614
720
|
};
|
|
615
721
|
server.didOpenTextDocument({
|
|
616
|
-
textDocument: doc
|
|
722
|
+
textDocument: doc,
|
|
617
723
|
});
|
|
618
724
|
server.didChangeTextDocument({
|
|
619
725
|
textDocument: doc,
|
|
@@ -623,142 +729,141 @@ describe('editing', () => {
|
|
|
623
729
|
export function foo(): void {
|
|
624
730
|
missing('test');
|
|
625
731
|
}
|
|
626
|
-
|
|
627
|
-
}
|
|
628
|
-
]
|
|
732
|
+
`,
|
|
733
|
+
},
|
|
734
|
+
],
|
|
629
735
|
});
|
|
630
|
-
|
|
631
|
-
|
|
736
|
+
await server.requestDiagnostics();
|
|
737
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
632
738
|
const resultsForFile = diagnostics.get(doc.uri);
|
|
633
739
|
assert.isDefined(resultsForFile);
|
|
634
740
|
const fileDiagnostics = resultsForFile.diagnostics;
|
|
635
741
|
assert.isTrue(fileDiagnostics.length >= 1, fileDiagnostics.map(d => d.message).join(','));
|
|
636
742
|
assert.equal("Cannot find name 'missing'.", fileDiagnostics[0].message);
|
|
637
|
-
})
|
|
743
|
+
});
|
|
638
744
|
});
|
|
639
745
|
describe('references', () => {
|
|
640
|
-
it('respects "includeDeclaration" in the request', () =>
|
|
746
|
+
it('respects "includeDeclaration" in the request', async () => {
|
|
641
747
|
const doc = {
|
|
642
|
-
uri:
|
|
748
|
+
uri: uri('foo.ts'),
|
|
643
749
|
languageId: 'typescript',
|
|
644
750
|
version: 1,
|
|
645
751
|
text: `
|
|
646
|
-
|
|
647
|
-
foo
|
|
648
|
-
|
|
649
|
-
`
|
|
752
|
+
function foo() {};
|
|
753
|
+
foo();
|
|
754
|
+
`,
|
|
650
755
|
};
|
|
651
756
|
server.didOpenTextDocument({
|
|
652
|
-
textDocument: doc
|
|
757
|
+
textDocument: doc,
|
|
653
758
|
});
|
|
654
759
|
// Without declaration/definition.
|
|
655
|
-
|
|
760
|
+
const position = lastPosition(doc, 'function foo()');
|
|
761
|
+
let references = await server.references({
|
|
656
762
|
context: { includeDeclaration: false },
|
|
657
763
|
textDocument: doc,
|
|
658
|
-
position
|
|
764
|
+
position,
|
|
659
765
|
});
|
|
660
|
-
assert.strictEqual(references.length,
|
|
766
|
+
assert.strictEqual(references.length, 1);
|
|
661
767
|
assert.strictEqual(references[0].range.start.line, 2);
|
|
662
|
-
assert.strictEqual(references[1].range.start.line, 3);
|
|
663
768
|
// With declaration/definition.
|
|
664
|
-
references =
|
|
769
|
+
references = await server.references({
|
|
665
770
|
context: { includeDeclaration: true },
|
|
666
771
|
textDocument: doc,
|
|
667
|
-
position
|
|
772
|
+
position,
|
|
668
773
|
});
|
|
669
|
-
assert.strictEqual(references.length,
|
|
670
|
-
})
|
|
671
|
-
});
|
|
672
|
-
describe('workspace configuration', () => {
|
|
673
|
-
it('receives workspace configuration notification', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
674
|
-
const doc = {
|
|
675
|
-
uri: (0, test_utils_1.uri)('bar.ts'),
|
|
676
|
-
languageId: 'typescript',
|
|
677
|
-
version: 1,
|
|
678
|
-
text: `
|
|
679
|
-
export function foo(): void {
|
|
680
|
-
console.log('test')
|
|
681
|
-
}
|
|
682
|
-
`
|
|
683
|
-
};
|
|
684
|
-
server.didOpenTextDocument({
|
|
685
|
-
textDocument: doc
|
|
686
|
-
});
|
|
687
|
-
server.didChangeConfiguration({
|
|
688
|
-
settings: {
|
|
689
|
-
typescript: {
|
|
690
|
-
format: {
|
|
691
|
-
insertSpaceAfterCommaDelimiter: true
|
|
692
|
-
}
|
|
693
|
-
},
|
|
694
|
-
javascript: {
|
|
695
|
-
format: {
|
|
696
|
-
insertSpaceAfterCommaDelimiter: false
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
const file = (0, test_utils_1.filePath)('bar.ts');
|
|
702
|
-
const settings = server.getWorkspacePreferencesForDocument(file);
|
|
703
|
-
assert.deepEqual(settings, { format: { insertSpaceAfterCommaDelimiter: true } });
|
|
704
|
-
}));
|
|
774
|
+
assert.strictEqual(references.length, 2);
|
|
775
|
+
});
|
|
705
776
|
});
|
|
777
|
+
// describe('workspace configuration', () => {
|
|
778
|
+
// it('receives workspace configuration notification', async ()=>{
|
|
779
|
+
// const doc = {
|
|
780
|
+
// uri: uri('bar.ts'),
|
|
781
|
+
// languageId: 'typescript',
|
|
782
|
+
// version: 1,
|
|
783
|
+
// text: `
|
|
784
|
+
// export function foo(): void {
|
|
785
|
+
// console.log('test')
|
|
786
|
+
// }
|
|
787
|
+
// `
|
|
788
|
+
// };
|
|
789
|
+
// server.didOpenTextDocument({
|
|
790
|
+
// textDocument: doc
|
|
791
|
+
// });
|
|
792
|
+
// server.didChangeConfiguration({
|
|
793
|
+
// settings: {
|
|
794
|
+
// typescript: {
|
|
795
|
+
// format: {
|
|
796
|
+
// insertSpaceAfterCommaDelimiter: true
|
|
797
|
+
// }
|
|
798
|
+
// },
|
|
799
|
+
// javascript: {
|
|
800
|
+
// format: {
|
|
801
|
+
// insertSpaceAfterCommaDelimiter: false
|
|
802
|
+
// }
|
|
803
|
+
// }
|
|
804
|
+
// }
|
|
805
|
+
// });
|
|
806
|
+
// const file = filePath('bar.ts');
|
|
807
|
+
// const settings = server.getWorkspacePreferencesForDocument(file);
|
|
808
|
+
// assert.deepEqual(settings, { format: { insertSpaceAfterCommaDelimiter: true } });
|
|
809
|
+
// });
|
|
810
|
+
// });
|
|
706
811
|
describe('formatting', () => {
|
|
707
|
-
const uriString =
|
|
812
|
+
const uriString = uri('bar.ts');
|
|
708
813
|
const languageId = 'typescript';
|
|
709
814
|
const version = 1;
|
|
710
|
-
it('full document formatting', () =>
|
|
815
|
+
it('full document formatting', async () => {
|
|
711
816
|
const text = 'export function foo ( ) : void { }';
|
|
712
817
|
const textDocument = {
|
|
713
|
-
uri: uriString, languageId, version, text
|
|
818
|
+
uri: uriString, languageId, version, text,
|
|
714
819
|
};
|
|
715
820
|
server.didOpenTextDocument({ textDocument });
|
|
716
|
-
const edits =
|
|
821
|
+
const edits = await server.documentFormatting({
|
|
717
822
|
textDocument,
|
|
718
823
|
options: {
|
|
719
824
|
tabSize: 4,
|
|
720
|
-
insertSpaces: true
|
|
721
|
-
}
|
|
825
|
+
insertSpaces: true,
|
|
826
|
+
},
|
|
722
827
|
});
|
|
723
|
-
const result =
|
|
828
|
+
const result = TextDocument.applyEdits(TextDocument.create(uriString, languageId, version, text), edits);
|
|
724
829
|
assert.equal('export function foo(): void { }', result);
|
|
725
|
-
})
|
|
726
|
-
it('indent settings (3 spaces)', () =>
|
|
830
|
+
});
|
|
831
|
+
it('indent settings (3 spaces)', async () => {
|
|
727
832
|
const text = 'function foo() {\n// some code\n}';
|
|
728
833
|
const textDocument = {
|
|
729
|
-
uri: uriString, languageId, version, text
|
|
834
|
+
uri: uriString, languageId, version, text,
|
|
730
835
|
};
|
|
731
836
|
server.didOpenTextDocument({ textDocument });
|
|
732
|
-
const edits =
|
|
837
|
+
const edits = await server.documentFormatting({
|
|
733
838
|
textDocument,
|
|
734
839
|
options: {
|
|
735
840
|
tabSize: 3,
|
|
736
|
-
insertSpaces: true
|
|
737
|
-
}
|
|
841
|
+
insertSpaces: true,
|
|
842
|
+
},
|
|
738
843
|
});
|
|
739
|
-
const result =
|
|
844
|
+
const result = TextDocument.applyEdits(TextDocument.create(uriString, languageId, version, text), edits);
|
|
740
845
|
assert.equal('function foo() {\n // some code\n}', result);
|
|
741
|
-
})
|
|
742
|
-
it('indent settings (tabs)', () =>
|
|
846
|
+
});
|
|
847
|
+
it('indent settings (tabs)', async () => {
|
|
743
848
|
const text = 'function foo() {\n// some code\n}';
|
|
744
849
|
const textDocument = {
|
|
745
|
-
uri: uriString, languageId, version, text
|
|
850
|
+
uri: uriString, languageId, version, text,
|
|
746
851
|
};
|
|
747
852
|
server.didOpenTextDocument({ textDocument });
|
|
748
|
-
const edits =
|
|
853
|
+
const edits = await server.documentFormatting({
|
|
749
854
|
textDocument,
|
|
750
855
|
options: {
|
|
751
856
|
tabSize: 4,
|
|
752
|
-
insertSpaces: false
|
|
753
|
-
}
|
|
857
|
+
insertSpaces: false,
|
|
858
|
+
},
|
|
754
859
|
});
|
|
755
|
-
const result =
|
|
860
|
+
const result = TextDocument.applyEdits(TextDocument.create(uriString, languageId, version, text), edits);
|
|
756
861
|
assert.equal('function foo() {\n\t// some code\n}', result);
|
|
757
|
-
})
|
|
758
|
-
it('formatting setting set through workspace configuration', () =>
|
|
862
|
+
});
|
|
863
|
+
it('formatting setting set through workspace configuration', async () => {
|
|
759
864
|
const text = 'function foo() {\n// some code\n}';
|
|
760
865
|
const textDocument = {
|
|
761
|
-
uri: uriString, languageId, version, text
|
|
866
|
+
uri: uriString, languageId, version, text,
|
|
762
867
|
};
|
|
763
868
|
server.didOpenTextDocument({ textDocument });
|
|
764
869
|
server.didChangeConfiguration({
|
|
@@ -766,104 +871,141 @@ describe('formatting', () => {
|
|
|
766
871
|
typescript: {
|
|
767
872
|
format: {
|
|
768
873
|
newLineCharacter: '\n',
|
|
769
|
-
placeOpenBraceOnNewLineForFunctions: true
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
874
|
+
placeOpenBraceOnNewLineForFunctions: true,
|
|
875
|
+
},
|
|
876
|
+
},
|
|
877
|
+
},
|
|
773
878
|
});
|
|
774
|
-
const edits =
|
|
879
|
+
const edits = await server.documentFormatting({
|
|
775
880
|
textDocument,
|
|
776
881
|
options: {
|
|
777
882
|
tabSize: 4,
|
|
778
|
-
insertSpaces: false
|
|
779
|
-
}
|
|
883
|
+
insertSpaces: false,
|
|
884
|
+
},
|
|
780
885
|
});
|
|
781
|
-
const result =
|
|
886
|
+
const result = TextDocument.applyEdits(TextDocument.create(uriString, languageId, version, text), edits);
|
|
782
887
|
assert.equal('function foo()\n{\n\t// some code\n}', result);
|
|
783
|
-
})
|
|
784
|
-
it('selected range', () =>
|
|
888
|
+
});
|
|
889
|
+
it('selected range', async () => {
|
|
785
890
|
const text = 'function foo() {\nconst first = 1;\nconst second = 2;\nconst val = foo( "something" );\n//const fourth = 4;\n}';
|
|
786
891
|
const textDocument = {
|
|
787
|
-
uri: uriString, languageId, version, text
|
|
892
|
+
uri: uriString, languageId, version, text,
|
|
788
893
|
};
|
|
789
894
|
server.didOpenTextDocument({ textDocument });
|
|
790
|
-
const edits =
|
|
895
|
+
const edits = await server.documentRangeFormatting({
|
|
791
896
|
textDocument,
|
|
792
897
|
range: {
|
|
793
898
|
start: {
|
|
794
899
|
line: 2,
|
|
795
|
-
character: 0
|
|
900
|
+
character: 0,
|
|
796
901
|
},
|
|
797
902
|
end: {
|
|
798
903
|
line: 3,
|
|
799
|
-
character: 30
|
|
800
|
-
}
|
|
904
|
+
character: 30,
|
|
905
|
+
},
|
|
801
906
|
},
|
|
802
907
|
options: {
|
|
803
908
|
tabSize: 4,
|
|
804
|
-
insertSpaces: true
|
|
805
|
-
}
|
|
909
|
+
insertSpaces: true,
|
|
910
|
+
},
|
|
806
911
|
});
|
|
807
|
-
const result =
|
|
912
|
+
const result = TextDocument.applyEdits(TextDocument.create(uriString, languageId, version, text), edits);
|
|
808
913
|
assert.equal('function foo() {\nconst first = 1;\n const second = 2;\n const val = foo("something");\n//const fourth = 4;\n}', result);
|
|
809
|
-
})
|
|
914
|
+
});
|
|
810
915
|
});
|
|
811
916
|
describe('signatureHelp', () => {
|
|
812
|
-
it('simple test', () =>
|
|
917
|
+
it('simple test', async () => {
|
|
813
918
|
const doc = {
|
|
814
|
-
uri:
|
|
919
|
+
uri: uri('bar.ts'),
|
|
815
920
|
languageId: 'typescript',
|
|
816
921
|
version: 1,
|
|
817
922
|
text: `
|
|
818
923
|
export function foo(bar: string, baz?:boolean): void {}
|
|
924
|
+
export function foo(n: number, baz?: boolean): void
|
|
819
925
|
foo(param1, param2)
|
|
820
|
-
|
|
926
|
+
`,
|
|
821
927
|
};
|
|
822
928
|
server.didOpenTextDocument({
|
|
823
|
-
textDocument: doc
|
|
929
|
+
textDocument: doc,
|
|
824
930
|
});
|
|
825
|
-
let result = (
|
|
931
|
+
let result = (await server.signatureHelp({
|
|
826
932
|
textDocument: doc,
|
|
827
|
-
position:
|
|
933
|
+
position: position(doc, 'param1'),
|
|
828
934
|
}));
|
|
935
|
+
assert.equal(result.signatures.length, 2);
|
|
829
936
|
assert.equal('bar: string', result.signatures[result.activeSignature].parameters[result.activeParameter].label);
|
|
830
|
-
result = (
|
|
937
|
+
result = (await server.signatureHelp({
|
|
831
938
|
textDocument: doc,
|
|
832
|
-
position:
|
|
939
|
+
position: position(doc, 'param2'),
|
|
833
940
|
}));
|
|
834
941
|
assert.equal('baz?: boolean', result.signatures[result.activeSignature].parameters[result.activeParameter].label);
|
|
835
|
-
})
|
|
942
|
+
});
|
|
943
|
+
it('retrigger with specific signature active', async () => {
|
|
944
|
+
const doc = {
|
|
945
|
+
uri: uri('bar.ts'),
|
|
946
|
+
languageId: 'typescript',
|
|
947
|
+
version: 1,
|
|
948
|
+
text: `
|
|
949
|
+
export function foo(bar: string, baz?: boolean): void {}
|
|
950
|
+
export function foo(n: number, baz?: boolean): void
|
|
951
|
+
foo(param1, param2)
|
|
952
|
+
`,
|
|
953
|
+
};
|
|
954
|
+
server.didOpenTextDocument({ textDocument: doc });
|
|
955
|
+
let result = await server.signatureHelp({
|
|
956
|
+
textDocument: doc,
|
|
957
|
+
position: position(doc, 'param1'),
|
|
958
|
+
});
|
|
959
|
+
assert.equal(result.signatures.length, 2);
|
|
960
|
+
result = (await server.signatureHelp({
|
|
961
|
+
textDocument: doc,
|
|
962
|
+
position: position(doc, 'param1'),
|
|
963
|
+
context: {
|
|
964
|
+
isRetrigger: true,
|
|
965
|
+
triggerKind: lsp.SignatureHelpTriggerKind.Invoked,
|
|
966
|
+
activeSignatureHelp: {
|
|
967
|
+
signatures: result.signatures,
|
|
968
|
+
activeSignature: 1, // select second signature
|
|
969
|
+
},
|
|
970
|
+
},
|
|
971
|
+
}));
|
|
972
|
+
const { activeSignature, signatures } = result;
|
|
973
|
+
assert.equal(activeSignature, 1);
|
|
974
|
+
assert.deepInclude(signatures[activeSignature], {
|
|
975
|
+
label: 'foo(n: number, baz?: boolean): void',
|
|
976
|
+
});
|
|
977
|
+
});
|
|
836
978
|
});
|
|
837
979
|
describe('code actions', () => {
|
|
838
980
|
const doc = {
|
|
839
|
-
uri:
|
|
981
|
+
uri: uri('bar.ts'),
|
|
840
982
|
languageId: 'typescript',
|
|
841
983
|
version: 1,
|
|
842
984
|
text: `import { something } from "something";
|
|
843
985
|
export function foo(bar: string, baz?:boolean): void {}
|
|
844
986
|
foo(param1, param2)
|
|
845
|
-
|
|
987
|
+
`,
|
|
846
988
|
};
|
|
847
|
-
it('can provide quickfix code actions', () =>
|
|
989
|
+
it('can provide quickfix code actions', async () => {
|
|
848
990
|
server.didOpenTextDocument({
|
|
849
|
-
textDocument: doc
|
|
991
|
+
textDocument: doc,
|
|
850
992
|
});
|
|
851
|
-
const result = (
|
|
993
|
+
const result = (await server.codeAction({
|
|
852
994
|
textDocument: doc,
|
|
853
995
|
range: {
|
|
854
996
|
start: { line: 1, character: 25 },
|
|
855
|
-
end: { line: 1, character: 49 }
|
|
997
|
+
end: { line: 1, character: 49 },
|
|
856
998
|
},
|
|
857
999
|
context: {
|
|
858
1000
|
diagnostics: [{
|
|
859
1001
|
range: {
|
|
860
1002
|
start: { line: 1, character: 25 },
|
|
861
|
-
end: { line: 1, character: 49 }
|
|
1003
|
+
end: { line: 1, character: 49 },
|
|
862
1004
|
},
|
|
863
1005
|
code: 6133,
|
|
864
|
-
message: 'unused arg'
|
|
865
|
-
}]
|
|
866
|
-
}
|
|
1006
|
+
message: 'unused arg',
|
|
1007
|
+
}],
|
|
1008
|
+
},
|
|
867
1009
|
}));
|
|
868
1010
|
assert.strictEqual(result.length, 2);
|
|
869
1011
|
const quickFixDiagnostic = result.find(diagnostic => diagnostic.kind === 'quickfix');
|
|
@@ -878,30 +1020,30 @@ describe('code actions', () => {
|
|
|
878
1020
|
documentChanges: [
|
|
879
1021
|
{
|
|
880
1022
|
textDocument: {
|
|
881
|
-
uri:
|
|
882
|
-
version: 1
|
|
1023
|
+
uri: uri('bar.ts'),
|
|
1024
|
+
version: 1,
|
|
883
1025
|
},
|
|
884
1026
|
edits: [
|
|
885
1027
|
{
|
|
886
1028
|
range: {
|
|
887
1029
|
start: {
|
|
888
1030
|
line: 1,
|
|
889
|
-
character: 24
|
|
1031
|
+
character: 24,
|
|
890
1032
|
},
|
|
891
1033
|
end: {
|
|
892
1034
|
line: 1,
|
|
893
|
-
character: 27
|
|
894
|
-
}
|
|
1035
|
+
character: 27,
|
|
1036
|
+
},
|
|
895
1037
|
},
|
|
896
|
-
newText: '_bar'
|
|
897
|
-
}
|
|
898
|
-
]
|
|
899
|
-
}
|
|
900
|
-
]
|
|
901
|
-
}
|
|
902
|
-
]
|
|
1038
|
+
newText: '_bar',
|
|
1039
|
+
},
|
|
1040
|
+
],
|
|
1041
|
+
},
|
|
1042
|
+
],
|
|
1043
|
+
},
|
|
1044
|
+
],
|
|
903
1045
|
},
|
|
904
|
-
kind: 'quickfix'
|
|
1046
|
+
kind: 'quickfix',
|
|
905
1047
|
});
|
|
906
1048
|
const refactorDiagnostic = result.find(diagnostic => diagnostic.kind === 'refactor');
|
|
907
1049
|
assert.isDefined(refactorDiagnostic);
|
|
@@ -912,40 +1054,40 @@ describe('code actions', () => {
|
|
|
912
1054
|
command: '_typescript.applyRefactoring',
|
|
913
1055
|
arguments: [
|
|
914
1056
|
{
|
|
915
|
-
file:
|
|
1057
|
+
file: filePath('bar.ts'),
|
|
916
1058
|
startLine: 2,
|
|
917
1059
|
startOffset: 26,
|
|
918
1060
|
endLine: 2,
|
|
919
1061
|
endOffset: 50,
|
|
920
1062
|
refactor: 'Convert parameters to destructured object',
|
|
921
|
-
action: 'Convert parameters to destructured object'
|
|
922
|
-
}
|
|
923
|
-
]
|
|
1063
|
+
action: 'Convert parameters to destructured object',
|
|
1064
|
+
},
|
|
1065
|
+
],
|
|
924
1066
|
},
|
|
925
|
-
kind: 'refactor'
|
|
1067
|
+
kind: 'refactor',
|
|
926
1068
|
});
|
|
927
|
-
})
|
|
928
|
-
it('can filter quickfix code actions filtered by only', () =>
|
|
1069
|
+
});
|
|
1070
|
+
it('can filter quickfix code actions filtered by only', async () => {
|
|
929
1071
|
server.didOpenTextDocument({
|
|
930
|
-
textDocument: doc
|
|
1072
|
+
textDocument: doc,
|
|
931
1073
|
});
|
|
932
|
-
const result = (
|
|
1074
|
+
const result = (await server.codeAction({
|
|
933
1075
|
textDocument: doc,
|
|
934
1076
|
range: {
|
|
935
1077
|
start: { line: 1, character: 25 },
|
|
936
|
-
end: { line: 1, character: 49 }
|
|
1078
|
+
end: { line: 1, character: 49 },
|
|
937
1079
|
},
|
|
938
1080
|
context: {
|
|
939
1081
|
diagnostics: [{
|
|
940
1082
|
range: {
|
|
941
1083
|
start: { line: 1, character: 25 },
|
|
942
|
-
end: { line: 1, character: 49 }
|
|
1084
|
+
end: { line: 1, character: 49 },
|
|
943
1085
|
},
|
|
944
1086
|
code: 6133,
|
|
945
|
-
message: 'unused arg'
|
|
1087
|
+
message: 'unused arg',
|
|
946
1088
|
}],
|
|
947
|
-
only: ['refactor', 'invalid-action']
|
|
948
|
-
}
|
|
1089
|
+
only: ['refactor', 'invalid-action'],
|
|
1090
|
+
},
|
|
949
1091
|
}));
|
|
950
1092
|
assert.deepEqual(result, [
|
|
951
1093
|
{
|
|
@@ -955,72 +1097,72 @@ describe('code actions', () => {
|
|
|
955
1097
|
action: 'Convert parameters to destructured object',
|
|
956
1098
|
endLine: 2,
|
|
957
1099
|
endOffset: 50,
|
|
958
|
-
file:
|
|
1100
|
+
file: filePath('bar.ts'),
|
|
959
1101
|
refactor: 'Convert parameters to destructured object',
|
|
960
1102
|
startLine: 2,
|
|
961
|
-
startOffset: 26
|
|
962
|
-
}
|
|
1103
|
+
startOffset: 26,
|
|
1104
|
+
},
|
|
963
1105
|
],
|
|
964
1106
|
command: '_typescript.applyRefactoring',
|
|
965
|
-
title: 'Convert parameters to destructured object'
|
|
1107
|
+
title: 'Convert parameters to destructured object',
|
|
966
1108
|
},
|
|
967
1109
|
kind: 'refactor',
|
|
968
|
-
title: 'Convert parameters to destructured object'
|
|
969
|
-
}
|
|
1110
|
+
title: 'Convert parameters to destructured object',
|
|
1111
|
+
},
|
|
970
1112
|
]);
|
|
971
|
-
})
|
|
972
|
-
it('does not provide organize imports when there are errors', () =>
|
|
1113
|
+
});
|
|
1114
|
+
it('does not provide organize imports when there are errors', async () => {
|
|
973
1115
|
server.didOpenTextDocument({
|
|
974
|
-
textDocument: doc
|
|
1116
|
+
textDocument: doc,
|
|
975
1117
|
});
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const result = (
|
|
1118
|
+
await server.requestDiagnostics();
|
|
1119
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
1120
|
+
const result = (await server.codeAction({
|
|
979
1121
|
textDocument: doc,
|
|
980
1122
|
range: {
|
|
981
1123
|
start: { line: 1, character: 29 },
|
|
982
|
-
end: { line: 1, character: 53 }
|
|
1124
|
+
end: { line: 1, character: 53 },
|
|
983
1125
|
},
|
|
984
1126
|
context: {
|
|
985
1127
|
diagnostics: [{
|
|
986
1128
|
range: {
|
|
987
1129
|
start: { line: 1, character: 25 },
|
|
988
|
-
end: { line: 1, character: 49 }
|
|
1130
|
+
end: { line: 1, character: 49 },
|
|
989
1131
|
},
|
|
990
1132
|
code: 6133,
|
|
991
|
-
message: 'unused arg'
|
|
1133
|
+
message: 'unused arg',
|
|
992
1134
|
}],
|
|
993
|
-
only: [
|
|
994
|
-
}
|
|
1135
|
+
only: [CodeActionKind.SourceOrganizeImportsTs.value],
|
|
1136
|
+
},
|
|
995
1137
|
}));
|
|
996
1138
|
assert.deepEqual(result, []);
|
|
997
|
-
})
|
|
998
|
-
it('provides "add missing imports" when explicitly requested in only', () =>
|
|
1139
|
+
});
|
|
1140
|
+
it('provides "add missing imports" when explicitly requested in only', async () => {
|
|
999
1141
|
const doc = {
|
|
1000
|
-
uri:
|
|
1142
|
+
uri: uri('bar.ts'),
|
|
1001
1143
|
languageId: 'typescript',
|
|
1002
1144
|
version: 1,
|
|
1003
|
-
text: 'existsSync(\'t\');'
|
|
1145
|
+
text: 'existsSync(\'t\');',
|
|
1004
1146
|
};
|
|
1005
1147
|
server.didOpenTextDocument({
|
|
1006
|
-
textDocument: doc
|
|
1148
|
+
textDocument: doc,
|
|
1007
1149
|
});
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
const result = (
|
|
1150
|
+
await server.requestDiagnostics();
|
|
1151
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
1152
|
+
const result = (await server.codeAction({
|
|
1011
1153
|
textDocument: doc,
|
|
1012
1154
|
range: {
|
|
1013
1155
|
start: { line: 1, character: 29 },
|
|
1014
|
-
end: { line: 1, character: 53 }
|
|
1156
|
+
end: { line: 1, character: 53 },
|
|
1015
1157
|
},
|
|
1016
1158
|
context: {
|
|
1017
1159
|
diagnostics: [],
|
|
1018
|
-
only: [
|
|
1019
|
-
}
|
|
1160
|
+
only: [CodeActionKind.SourceAddMissingImportsTs.value],
|
|
1161
|
+
},
|
|
1020
1162
|
}));
|
|
1021
1163
|
assert.deepEqual(result, [
|
|
1022
1164
|
{
|
|
1023
|
-
kind:
|
|
1165
|
+
kind: CodeActionKind.SourceAddMissingImportsTs.value,
|
|
1024
1166
|
title: 'Add all missing imports',
|
|
1025
1167
|
edit: {
|
|
1026
1168
|
documentChanges: [
|
|
@@ -1032,54 +1174,54 @@ describe('code actions', () => {
|
|
|
1032
1174
|
range: {
|
|
1033
1175
|
end: {
|
|
1034
1176
|
character: 0,
|
|
1035
|
-
line: 0
|
|
1177
|
+
line: 0,
|
|
1036
1178
|
},
|
|
1037
1179
|
start: {
|
|
1038
1180
|
character: 0,
|
|
1039
|
-
line: 0
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1181
|
+
line: 0,
|
|
1182
|
+
},
|
|
1183
|
+
},
|
|
1184
|
+
},
|
|
1043
1185
|
],
|
|
1044
1186
|
textDocument: {
|
|
1045
|
-
uri:
|
|
1046
|
-
version: 1
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
]
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1187
|
+
uri: uri('bar.ts'),
|
|
1188
|
+
version: 1,
|
|
1189
|
+
},
|
|
1190
|
+
},
|
|
1191
|
+
],
|
|
1192
|
+
},
|
|
1193
|
+
},
|
|
1052
1194
|
]);
|
|
1053
|
-
})
|
|
1054
|
-
it('provides "fix all" when explicitly requested in only', () =>
|
|
1195
|
+
});
|
|
1196
|
+
it('provides "fix all" when explicitly requested in only', async () => {
|
|
1055
1197
|
const doc = {
|
|
1056
|
-
uri:
|
|
1198
|
+
uri: uri('bar.ts'),
|
|
1057
1199
|
languageId: 'typescript',
|
|
1058
1200
|
version: 1,
|
|
1059
1201
|
text: `function foo() {
|
|
1060
1202
|
return
|
|
1061
1203
|
setTimeout(() => {})
|
|
1062
|
-
}
|
|
1204
|
+
}`,
|
|
1063
1205
|
};
|
|
1064
1206
|
server.didOpenTextDocument({
|
|
1065
|
-
textDocument: doc
|
|
1207
|
+
textDocument: doc,
|
|
1066
1208
|
});
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
const result = (
|
|
1209
|
+
await server.requestDiagnostics();
|
|
1210
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
1211
|
+
const result = (await server.codeAction({
|
|
1070
1212
|
textDocument: doc,
|
|
1071
1213
|
range: {
|
|
1072
1214
|
start: { line: 0, character: 0 },
|
|
1073
|
-
end: { line: 4, character: 0 }
|
|
1215
|
+
end: { line: 4, character: 0 },
|
|
1074
1216
|
},
|
|
1075
1217
|
context: {
|
|
1076
1218
|
diagnostics: [],
|
|
1077
|
-
only: [
|
|
1078
|
-
}
|
|
1219
|
+
only: [CodeActionKind.SourceFixAllTs.value],
|
|
1220
|
+
},
|
|
1079
1221
|
}));
|
|
1080
1222
|
assert.deepEqual(result, [
|
|
1081
1223
|
{
|
|
1082
|
-
kind:
|
|
1224
|
+
kind: CodeActionKind.SourceFixAllTs.value,
|
|
1083
1225
|
title: 'Fix all',
|
|
1084
1226
|
edit: {
|
|
1085
1227
|
documentChanges: [
|
|
@@ -1090,58 +1232,58 @@ describe('code actions', () => {
|
|
|
1090
1232
|
range: {
|
|
1091
1233
|
end: {
|
|
1092
1234
|
character: 0,
|
|
1093
|
-
line: 3
|
|
1235
|
+
line: 3,
|
|
1094
1236
|
},
|
|
1095
1237
|
start: {
|
|
1096
1238
|
character: 0,
|
|
1097
|
-
line: 2
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1239
|
+
line: 2,
|
|
1240
|
+
},
|
|
1241
|
+
},
|
|
1242
|
+
},
|
|
1101
1243
|
],
|
|
1102
1244
|
textDocument: {
|
|
1103
|
-
uri:
|
|
1104
|
-
version: 1
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
]
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1245
|
+
uri: uri('bar.ts'),
|
|
1246
|
+
version: 1,
|
|
1247
|
+
},
|
|
1248
|
+
},
|
|
1249
|
+
],
|
|
1250
|
+
},
|
|
1251
|
+
},
|
|
1110
1252
|
]);
|
|
1111
|
-
})
|
|
1112
|
-
it('provides organize imports when explicitly requested in only', () =>
|
|
1253
|
+
});
|
|
1254
|
+
it('provides organize imports when explicitly requested in only', async () => {
|
|
1113
1255
|
const doc = {
|
|
1114
|
-
uri:
|
|
1256
|
+
uri: uri('bar.ts'),
|
|
1115
1257
|
languageId: 'typescript',
|
|
1116
1258
|
version: 1,
|
|
1117
1259
|
text: `import { existsSync } from 'fs';
|
|
1118
1260
|
import { accessSync } from 'fs';
|
|
1119
|
-
existsSync('t')
|
|
1261
|
+
existsSync('t');`,
|
|
1120
1262
|
};
|
|
1121
1263
|
server.didOpenTextDocument({
|
|
1122
|
-
textDocument: doc
|
|
1264
|
+
textDocument: doc,
|
|
1123
1265
|
});
|
|
1124
|
-
const result = (
|
|
1266
|
+
const result = (await server.codeAction({
|
|
1125
1267
|
textDocument: doc,
|
|
1126
1268
|
range: {
|
|
1127
1269
|
start: { line: 0, character: 0 },
|
|
1128
|
-
end: { line: 3, character: 0 }
|
|
1270
|
+
end: { line: 3, character: 0 },
|
|
1129
1271
|
},
|
|
1130
1272
|
context: {
|
|
1131
1273
|
diagnostics: [{
|
|
1132
1274
|
range: {
|
|
1133
1275
|
start: { line: 1, character: 25 },
|
|
1134
|
-
end: { line: 1, character: 49 }
|
|
1276
|
+
end: { line: 1, character: 49 },
|
|
1135
1277
|
},
|
|
1136
1278
|
code: 6133,
|
|
1137
|
-
message: 'unused arg'
|
|
1279
|
+
message: 'unused arg',
|
|
1138
1280
|
}],
|
|
1139
|
-
only: [
|
|
1140
|
-
}
|
|
1281
|
+
only: [CodeActionKind.SourceOrganizeImportsTs.value],
|
|
1282
|
+
},
|
|
1141
1283
|
}));
|
|
1142
1284
|
assert.deepEqual(result, [
|
|
1143
1285
|
{
|
|
1144
|
-
kind:
|
|
1286
|
+
kind: CodeActionKind.SourceOrganizeImportsTs.value,
|
|
1145
1287
|
title: 'Organize imports',
|
|
1146
1288
|
edit: {
|
|
1147
1289
|
documentChanges: [
|
|
@@ -1152,64 +1294,64 @@ existsSync('t');`
|
|
|
1152
1294
|
range: {
|
|
1153
1295
|
end: {
|
|
1154
1296
|
character: 0,
|
|
1155
|
-
line: 1
|
|
1297
|
+
line: 1,
|
|
1156
1298
|
},
|
|
1157
1299
|
start: {
|
|
1158
1300
|
character: 0,
|
|
1159
|
-
line: 0
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1301
|
+
line: 0,
|
|
1302
|
+
},
|
|
1303
|
+
},
|
|
1162
1304
|
},
|
|
1163
1305
|
{
|
|
1164
1306
|
newText: '',
|
|
1165
1307
|
range: {
|
|
1166
1308
|
end: {
|
|
1167
1309
|
character: 0,
|
|
1168
|
-
line: 2
|
|
1310
|
+
line: 2,
|
|
1169
1311
|
},
|
|
1170
1312
|
start: {
|
|
1171
1313
|
character: 0,
|
|
1172
|
-
line: 1
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1314
|
+
line: 1,
|
|
1315
|
+
},
|
|
1316
|
+
},
|
|
1317
|
+
},
|
|
1176
1318
|
],
|
|
1177
1319
|
textDocument: {
|
|
1178
|
-
uri:
|
|
1179
|
-
version: 1
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
]
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1320
|
+
uri: uri('bar.ts'),
|
|
1321
|
+
version: 1,
|
|
1322
|
+
},
|
|
1323
|
+
},
|
|
1324
|
+
],
|
|
1325
|
+
},
|
|
1326
|
+
},
|
|
1185
1327
|
]);
|
|
1186
|
-
})
|
|
1187
|
-
it('provides "remove unused" when explicitly requested in only', () =>
|
|
1328
|
+
});
|
|
1329
|
+
it('provides "remove unused" when explicitly requested in only', async () => {
|
|
1188
1330
|
const doc = {
|
|
1189
|
-
uri:
|
|
1331
|
+
uri: uri('bar.ts'),
|
|
1190
1332
|
languageId: 'typescript',
|
|
1191
1333
|
version: 1,
|
|
1192
|
-
text: 'import { existsSync } from \'fs\';'
|
|
1334
|
+
text: 'import { existsSync } from \'fs\';',
|
|
1193
1335
|
};
|
|
1194
1336
|
server.didOpenTextDocument({
|
|
1195
|
-
textDocument: doc
|
|
1337
|
+
textDocument: doc,
|
|
1196
1338
|
});
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
const result = (
|
|
1339
|
+
await server.requestDiagnostics();
|
|
1340
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
1341
|
+
const result = (await server.codeAction({
|
|
1200
1342
|
textDocument: doc,
|
|
1201
1343
|
range: {
|
|
1202
|
-
start:
|
|
1203
|
-
end:
|
|
1344
|
+
start: position(doc, 'existsSync'),
|
|
1345
|
+
end: positionAfter(doc, 'existsSync'),
|
|
1204
1346
|
},
|
|
1205
1347
|
context: {
|
|
1206
1348
|
diagnostics: [],
|
|
1207
|
-
only: [
|
|
1208
|
-
}
|
|
1349
|
+
only: [CodeActionKind.SourceRemoveUnusedTs.value],
|
|
1350
|
+
},
|
|
1209
1351
|
}));
|
|
1210
1352
|
assert.deepEqual(result, [
|
|
1211
1353
|
{
|
|
1212
|
-
kind:
|
|
1354
|
+
kind: CodeActionKind.SourceRemoveUnusedTs.value,
|
|
1213
1355
|
title: 'Remove all unused code',
|
|
1214
1356
|
edit: {
|
|
1215
1357
|
documentChanges: [
|
|
@@ -1220,28 +1362,28 @@ existsSync('t');`
|
|
|
1220
1362
|
range: {
|
|
1221
1363
|
end: {
|
|
1222
1364
|
character: 32,
|
|
1223
|
-
line: 0
|
|
1365
|
+
line: 0,
|
|
1224
1366
|
},
|
|
1225
1367
|
start: {
|
|
1226
1368
|
character: 0,
|
|
1227
|
-
line: 0
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1369
|
+
line: 0,
|
|
1370
|
+
},
|
|
1371
|
+
},
|
|
1372
|
+
},
|
|
1231
1373
|
],
|
|
1232
1374
|
textDocument: {
|
|
1233
|
-
uri:
|
|
1234
|
-
version: 1
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
]
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1375
|
+
uri: uri('bar.ts'),
|
|
1376
|
+
version: 1,
|
|
1377
|
+
},
|
|
1378
|
+
},
|
|
1379
|
+
],
|
|
1380
|
+
},
|
|
1381
|
+
},
|
|
1240
1382
|
]);
|
|
1241
|
-
})
|
|
1242
|
-
it('only provides the "source.fixAll" kind if requested in only', () =>
|
|
1383
|
+
});
|
|
1384
|
+
it('only provides the "source.fixAll" kind if requested in only', async () => {
|
|
1243
1385
|
const doc = {
|
|
1244
|
-
uri:
|
|
1386
|
+
uri: uri('bar.ts'),
|
|
1245
1387
|
languageId: 'typescript',
|
|
1246
1388
|
version: 1,
|
|
1247
1389
|
text: `
|
|
@@ -1250,28 +1392,28 @@ existsSync('t');`
|
|
|
1250
1392
|
return
|
|
1251
1393
|
setTimeout(() => {})
|
|
1252
1394
|
}
|
|
1253
|
-
|
|
1395
|
+
`,
|
|
1254
1396
|
};
|
|
1255
1397
|
server.didOpenTextDocument({
|
|
1256
|
-
textDocument: doc
|
|
1398
|
+
textDocument: doc,
|
|
1257
1399
|
});
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
const result = (
|
|
1400
|
+
await server.requestDiagnostics();
|
|
1401
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
1402
|
+
const result = (await server.codeAction({
|
|
1261
1403
|
textDocument: doc,
|
|
1262
1404
|
range: {
|
|
1263
1405
|
start: { line: 0, character: 0 },
|
|
1264
|
-
end:
|
|
1406
|
+
end: lastPosition(doc, '}'),
|
|
1265
1407
|
},
|
|
1266
1408
|
context: {
|
|
1267
1409
|
diagnostics: [],
|
|
1268
|
-
only: [
|
|
1269
|
-
}
|
|
1410
|
+
only: [CodeActionKind.SourceFixAllTs.value],
|
|
1411
|
+
},
|
|
1270
1412
|
}));
|
|
1271
1413
|
assert.strictEqual(result.length, 1, JSON.stringify(result, null, 2));
|
|
1272
1414
|
assert.deepEqual(result, [
|
|
1273
1415
|
{
|
|
1274
|
-
kind:
|
|
1416
|
+
kind: CodeActionKind.SourceFixAllTs.value,
|
|
1275
1417
|
title: 'Fix all',
|
|
1276
1418
|
edit: {
|
|
1277
1419
|
documentChanges: [
|
|
@@ -1282,60 +1424,165 @@ existsSync('t');`
|
|
|
1282
1424
|
range: {
|
|
1283
1425
|
start: {
|
|
1284
1426
|
line: 4,
|
|
1285
|
-
character: 0
|
|
1427
|
+
character: 0,
|
|
1286
1428
|
},
|
|
1287
1429
|
end: {
|
|
1288
1430
|
line: 5,
|
|
1289
|
-
character: 0
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1431
|
+
character: 0,
|
|
1432
|
+
},
|
|
1433
|
+
},
|
|
1434
|
+
},
|
|
1293
1435
|
],
|
|
1294
1436
|
textDocument: {
|
|
1295
|
-
uri:
|
|
1296
|
-
version: 1
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
]
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1437
|
+
uri: uri('bar.ts'),
|
|
1438
|
+
version: 1,
|
|
1439
|
+
},
|
|
1440
|
+
},
|
|
1441
|
+
],
|
|
1442
|
+
},
|
|
1443
|
+
},
|
|
1302
1444
|
]);
|
|
1303
|
-
})
|
|
1445
|
+
});
|
|
1446
|
+
});
|
|
1447
|
+
describe('executeCommand', () => {
|
|
1448
|
+
it('apply refactoring (move to new file)', async () => {
|
|
1449
|
+
const fooUri = uri('foo.ts');
|
|
1450
|
+
const doc = {
|
|
1451
|
+
uri: fooUri,
|
|
1452
|
+
languageId: 'typescript',
|
|
1453
|
+
version: 1,
|
|
1454
|
+
text: 'export function fn(): void {}\nexport function newFn(): void {}',
|
|
1455
|
+
};
|
|
1456
|
+
server.didOpenTextDocument({
|
|
1457
|
+
textDocument: doc,
|
|
1458
|
+
});
|
|
1459
|
+
const codeActions = (await server.codeAction({
|
|
1460
|
+
textDocument: doc,
|
|
1461
|
+
range: {
|
|
1462
|
+
start: position(doc, 'newFn'),
|
|
1463
|
+
end: position(doc, 'newFn'),
|
|
1464
|
+
},
|
|
1465
|
+
context: {
|
|
1466
|
+
diagnostics: [],
|
|
1467
|
+
},
|
|
1468
|
+
}));
|
|
1469
|
+
// Find refactoring code action.
|
|
1470
|
+
const applyRefactoringAction = codeActions.find(action => action.command?.command === Commands.APPLY_REFACTORING);
|
|
1471
|
+
assert.isDefined(applyRefactoringAction);
|
|
1472
|
+
// Execute refactoring action.
|
|
1473
|
+
await server.executeCommand({
|
|
1474
|
+
command: applyRefactoringAction.command.command,
|
|
1475
|
+
arguments: applyRefactoringAction.command.arguments,
|
|
1476
|
+
});
|
|
1477
|
+
assert.equal(1, server.workspaceEdits.length);
|
|
1478
|
+
const { changes } = server.workspaceEdits[0].edit;
|
|
1479
|
+
assert.isDefined(changes);
|
|
1480
|
+
assert.equal(2, Object.keys(changes).length);
|
|
1481
|
+
const change1 = changes[fooUri];
|
|
1482
|
+
assert.isDefined(change1);
|
|
1483
|
+
const change2 = changes[uri('newFn.ts')];
|
|
1484
|
+
assert.isDefined(change2);
|
|
1485
|
+
// Clean up file that is created on applying edit.
|
|
1486
|
+
fs.unlinkSync(filePath('newFn.ts'));
|
|
1487
|
+
assert.deepEqual(change1, [
|
|
1488
|
+
{
|
|
1489
|
+
range: {
|
|
1490
|
+
start: {
|
|
1491
|
+
line: 1,
|
|
1492
|
+
character: 0,
|
|
1493
|
+
},
|
|
1494
|
+
end: {
|
|
1495
|
+
line: 1,
|
|
1496
|
+
character: 32,
|
|
1497
|
+
},
|
|
1498
|
+
},
|
|
1499
|
+
newText: '',
|
|
1500
|
+
},
|
|
1501
|
+
]);
|
|
1502
|
+
assert.deepEqual(change2, [
|
|
1503
|
+
{
|
|
1504
|
+
range: {
|
|
1505
|
+
start: {
|
|
1506
|
+
line: 0,
|
|
1507
|
+
character: 0,
|
|
1508
|
+
},
|
|
1509
|
+
end: {
|
|
1510
|
+
line: 0,
|
|
1511
|
+
character: 0,
|
|
1512
|
+
},
|
|
1513
|
+
},
|
|
1514
|
+
newText: 'export function newFn(): void { }\n',
|
|
1515
|
+
},
|
|
1516
|
+
]);
|
|
1517
|
+
});
|
|
1518
|
+
it('go to source definition', async () => {
|
|
1519
|
+
// NOTE: This test needs to reference files that physically exist for the feature to work.
|
|
1520
|
+
const indexUri = uri('source-definition', 'index.ts');
|
|
1521
|
+
const indexDoc = {
|
|
1522
|
+
uri: indexUri,
|
|
1523
|
+
languageId: 'typescript',
|
|
1524
|
+
version: 1,
|
|
1525
|
+
text: readContents(filePath('source-definition', 'index.ts')),
|
|
1526
|
+
};
|
|
1527
|
+
server.didOpenTextDocument({ textDocument: indexDoc });
|
|
1528
|
+
const result = await server.executeCommand({
|
|
1529
|
+
command: Commands.SOURCE_DEFINITION,
|
|
1530
|
+
arguments: [
|
|
1531
|
+
indexUri,
|
|
1532
|
+
position(indexDoc, '/*identifier*/'),
|
|
1533
|
+
],
|
|
1534
|
+
});
|
|
1535
|
+
assert.isNotNull(result);
|
|
1536
|
+
assert.equal(result.length, 1);
|
|
1537
|
+
assert.deepEqual(result[0], {
|
|
1538
|
+
uri: uri('source-definition', 'a.js'),
|
|
1539
|
+
range: {
|
|
1540
|
+
start: {
|
|
1541
|
+
line: 0,
|
|
1542
|
+
character: 13,
|
|
1543
|
+
},
|
|
1544
|
+
end: {
|
|
1545
|
+
line: 0,
|
|
1546
|
+
character: 14,
|
|
1547
|
+
},
|
|
1548
|
+
},
|
|
1549
|
+
});
|
|
1550
|
+
});
|
|
1304
1551
|
});
|
|
1305
1552
|
describe('documentHighlight', () => {
|
|
1306
|
-
it('simple test', () =>
|
|
1553
|
+
it('simple test', async () => {
|
|
1307
1554
|
const barDoc = {
|
|
1308
|
-
uri:
|
|
1555
|
+
uri: uri('bar.d.ts'),
|
|
1309
1556
|
languageId: 'typescript',
|
|
1310
1557
|
version: 1,
|
|
1311
1558
|
text: `
|
|
1312
1559
|
export declare const Bar: unique symbol;
|
|
1313
1560
|
export interface Bar {
|
|
1314
1561
|
}
|
|
1315
|
-
|
|
1562
|
+
`,
|
|
1316
1563
|
};
|
|
1317
1564
|
server.didOpenTextDocument({
|
|
1318
|
-
textDocument: barDoc
|
|
1565
|
+
textDocument: barDoc,
|
|
1319
1566
|
});
|
|
1320
1567
|
const fooDoc = {
|
|
1321
|
-
uri:
|
|
1568
|
+
uri: uri('bar.ts'),
|
|
1322
1569
|
languageId: 'typescript',
|
|
1323
1570
|
version: 1,
|
|
1324
1571
|
text: `
|
|
1325
1572
|
import { Bar } from './bar';
|
|
1326
1573
|
export class Foo implements Bar {
|
|
1327
1574
|
}
|
|
1328
|
-
|
|
1575
|
+
`,
|
|
1329
1576
|
};
|
|
1330
1577
|
server.didOpenTextDocument({
|
|
1331
|
-
textDocument: fooDoc
|
|
1578
|
+
textDocument: fooDoc,
|
|
1332
1579
|
});
|
|
1333
|
-
const result =
|
|
1580
|
+
const result = await server.documentHighlight({
|
|
1334
1581
|
textDocument: fooDoc,
|
|
1335
|
-
position:
|
|
1582
|
+
position: lastPosition(fooDoc, 'Bar'),
|
|
1336
1583
|
});
|
|
1337
1584
|
assert.equal(2, result.length, JSON.stringify(result, undefined, 2));
|
|
1338
|
-
})
|
|
1585
|
+
});
|
|
1339
1586
|
});
|
|
1340
1587
|
describe('calls', () => {
|
|
1341
1588
|
function resultToString(callsResult, direction) {
|
|
@@ -1355,7 +1602,7 @@ describe('calls', () => {
|
|
|
1355
1602
|
return out.join('\n');
|
|
1356
1603
|
}
|
|
1357
1604
|
const doDoc = {
|
|
1358
|
-
uri:
|
|
1605
|
+
uri: uri('do.ts'),
|
|
1359
1606
|
languageId: 'typescript',
|
|
1360
1607
|
version: 1,
|
|
1361
1608
|
text: `
|
|
@@ -1370,10 +1617,10 @@ export function two() {
|
|
|
1370
1617
|
export function three() {
|
|
1371
1618
|
return "".toString();
|
|
1372
1619
|
}
|
|
1373
|
-
|
|
1620
|
+
`,
|
|
1374
1621
|
};
|
|
1375
1622
|
const fooDoc = {
|
|
1376
|
-
uri:
|
|
1623
|
+
uri: uri('foo.ts'),
|
|
1377
1624
|
languageId: 'typescript',
|
|
1378
1625
|
version: 1,
|
|
1379
1626
|
text: `import { doStuff } from './do';
|
|
@@ -1387,21 +1634,17 @@ class MyClass {
|
|
|
1387
1634
|
export function factory() {
|
|
1388
1635
|
new MyClass().doSomething();
|
|
1389
1636
|
}
|
|
1390
|
-
|
|
1637
|
+
`,
|
|
1391
1638
|
};
|
|
1392
1639
|
function openDocuments() {
|
|
1393
|
-
server.didOpenTextDocument({
|
|
1394
|
-
|
|
1395
|
-
});
|
|
1396
|
-
server.didOpenTextDocument({
|
|
1397
|
-
textDocument: fooDoc
|
|
1398
|
-
});
|
|
1640
|
+
server.didOpenTextDocument({ textDocument: doDoc });
|
|
1641
|
+
server.didOpenTextDocument({ textDocument: fooDoc });
|
|
1399
1642
|
}
|
|
1400
|
-
it('callers: first step', () =>
|
|
1643
|
+
it('callers: first step', async () => {
|
|
1401
1644
|
openDocuments();
|
|
1402
|
-
const callsResult =
|
|
1645
|
+
const callsResult = await server.calls({
|
|
1403
1646
|
textDocument: fooDoc,
|
|
1404
|
-
position:
|
|
1647
|
+
position: position(fooDoc, 'doStuff();'),
|
|
1405
1648
|
});
|
|
1406
1649
|
assert.equal(resultToString(callsResult, lspcalls.CallDirection.Incoming), `
|
|
1407
1650
|
↘ doStuff (do.ts#1)
|
|
@@ -1409,175 +1652,282 @@ export function factory() {
|
|
|
1409
1652
|
↘ doSomething (foo.ts#2) - foo.ts#3
|
|
1410
1653
|
↘ x (foo.ts#4) - foo.ts#4
|
|
1411
1654
|
`.trim());
|
|
1412
|
-
})
|
|
1413
|
-
it('callers: second step', () =>
|
|
1655
|
+
});
|
|
1656
|
+
it('callers: second step', async () => {
|
|
1414
1657
|
openDocuments();
|
|
1415
|
-
const callsResult =
|
|
1658
|
+
const callsResult = await server.calls({
|
|
1416
1659
|
textDocument: fooDoc,
|
|
1417
|
-
position:
|
|
1660
|
+
position: position(fooDoc, 'doSomething() {'),
|
|
1418
1661
|
});
|
|
1419
1662
|
assert.equal(resultToString(callsResult, lspcalls.CallDirection.Incoming), `
|
|
1420
1663
|
↘ doSomething (foo.ts#2)
|
|
1421
1664
|
↘ factory (foo.ts#8) - foo.ts#9
|
|
1422
1665
|
`.trim());
|
|
1423
|
-
})
|
|
1424
|
-
it('callees: first step', () =>
|
|
1666
|
+
});
|
|
1667
|
+
it.skip('callees: first step', async () => {
|
|
1425
1668
|
openDocuments();
|
|
1426
1669
|
const direction = lspcalls.CallDirection.Outgoing;
|
|
1427
|
-
const callsResult =
|
|
1670
|
+
const callsResult = await server.calls({
|
|
1428
1671
|
direction,
|
|
1429
1672
|
textDocument: fooDoc,
|
|
1430
|
-
position:
|
|
1673
|
+
position: position(fooDoc, 'doStuff()'),
|
|
1431
1674
|
});
|
|
1432
1675
|
assert.equal(resultToString(callsResult, direction), `
|
|
1433
1676
|
↖ doStuff (do.ts#1)
|
|
1434
1677
|
↖ two (do.ts#4) - do.ts#2
|
|
1435
1678
|
`.trim());
|
|
1436
|
-
})
|
|
1437
|
-
it('callees: second step', () =>
|
|
1679
|
+
});
|
|
1680
|
+
it.skip('callees: second step', async () => {
|
|
1438
1681
|
openDocuments();
|
|
1439
1682
|
const direction = lspcalls.CallDirection.Outgoing;
|
|
1440
|
-
const callsResult =
|
|
1683
|
+
const callsResult = await server.calls({
|
|
1441
1684
|
direction,
|
|
1442
1685
|
textDocument: doDoc,
|
|
1443
|
-
position:
|
|
1686
|
+
position: position(doDoc, 'function two()'),
|
|
1444
1687
|
});
|
|
1445
1688
|
assert.equal(resultToString(callsResult, direction), `
|
|
1446
1689
|
↖ two (do.ts#4)
|
|
1447
1690
|
↖ three (do.ts#9) - do.ts#5
|
|
1448
1691
|
↖ ttt (do.ts#6) - do.ts#7
|
|
1449
1692
|
`.trim());
|
|
1450
|
-
})
|
|
1693
|
+
});
|
|
1451
1694
|
});
|
|
1452
1695
|
describe('diagnostics (no client support)', () => {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1696
|
+
let localServer;
|
|
1697
|
+
before(async () => {
|
|
1698
|
+
const clientCapabilitiesOverride = {
|
|
1699
|
+
textDocument: {
|
|
1700
|
+
publishDiagnostics: undefined,
|
|
1701
|
+
},
|
|
1702
|
+
};
|
|
1703
|
+
localServer = await createServer({
|
|
1459
1704
|
rootUri: null,
|
|
1460
1705
|
publishDiagnostics: args => diagnostics.set(args.uri, args),
|
|
1461
|
-
clientCapabilitiesOverride
|
|
1706
|
+
clientCapabilitiesOverride,
|
|
1462
1707
|
});
|
|
1463
|
-
})
|
|
1464
|
-
|
|
1708
|
+
});
|
|
1709
|
+
beforeEach(() => {
|
|
1710
|
+
localServer.closeAll();
|
|
1711
|
+
// "closeAll" triggers final publishDiagnostics with an empty list so clear last.
|
|
1712
|
+
diagnostics.clear();
|
|
1713
|
+
localServer.workspaceEdits = [];
|
|
1714
|
+
});
|
|
1715
|
+
after(() => {
|
|
1716
|
+
localServer.closeAll();
|
|
1717
|
+
localServer.shutdown();
|
|
1718
|
+
});
|
|
1719
|
+
it('diagnostic tags are not returned', async () => {
|
|
1465
1720
|
const doc = {
|
|
1466
|
-
uri:
|
|
1721
|
+
uri: uri('diagnosticsBar.ts'),
|
|
1467
1722
|
languageId: 'typescript',
|
|
1468
1723
|
version: 1,
|
|
1469
1724
|
text: `
|
|
1470
1725
|
export function foo(): void {
|
|
1471
1726
|
missing('test')
|
|
1472
1727
|
}
|
|
1473
|
-
|
|
1728
|
+
`,
|
|
1474
1729
|
};
|
|
1475
|
-
|
|
1476
|
-
textDocument: doc
|
|
1730
|
+
localServer.didOpenTextDocument({
|
|
1731
|
+
textDocument: doc,
|
|
1477
1732
|
});
|
|
1478
|
-
|
|
1479
|
-
|
|
1733
|
+
await localServer.requestDiagnostics();
|
|
1734
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
1480
1735
|
const resultsForFile = diagnostics.get(doc.uri);
|
|
1481
1736
|
assert.isDefined(resultsForFile);
|
|
1482
|
-
assert.strictEqual(resultsForFile
|
|
1483
|
-
|
|
1737
|
+
assert.strictEqual(resultsForFile.diagnostics.length, 1);
|
|
1738
|
+
assert.notProperty(resultsForFile.diagnostics[0], 'tags');
|
|
1739
|
+
});
|
|
1484
1740
|
});
|
|
1485
1741
|
describe('jsx/tsx project', () => {
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1742
|
+
let localServer;
|
|
1743
|
+
before(async () => {
|
|
1744
|
+
localServer = await createServer({
|
|
1745
|
+
rootUri: uri('jsx'),
|
|
1746
|
+
publishDiagnostics: args => diagnostics.set(args.uri, args),
|
|
1490
1747
|
});
|
|
1491
|
-
})
|
|
1492
|
-
|
|
1748
|
+
});
|
|
1749
|
+
beforeEach(() => {
|
|
1750
|
+
localServer.closeAll();
|
|
1751
|
+
// "closeAll" triggers final publishDiagnostics with an empty list so clear last.
|
|
1752
|
+
diagnostics.clear();
|
|
1753
|
+
localServer.workspaceEdits = [];
|
|
1754
|
+
});
|
|
1755
|
+
after(() => {
|
|
1756
|
+
localServer.closeAll();
|
|
1757
|
+
localServer.shutdown();
|
|
1758
|
+
});
|
|
1759
|
+
it('includes snippet completion for element prop', async () => {
|
|
1493
1760
|
const doc = {
|
|
1494
|
-
uri:
|
|
1761
|
+
uri: uri('jsx', 'app.tsx'),
|
|
1495
1762
|
languageId: 'typescriptreact',
|
|
1496
1763
|
version: 1,
|
|
1497
|
-
text:
|
|
1764
|
+
text: readContents(filePath('jsx', 'app.tsx')),
|
|
1498
1765
|
};
|
|
1499
|
-
|
|
1500
|
-
textDocument: doc
|
|
1766
|
+
localServer.didOpenTextDocument({
|
|
1767
|
+
textDocument: doc,
|
|
1501
1768
|
});
|
|
1502
|
-
const completion =
|
|
1769
|
+
const completion = await localServer.completion({ textDocument: doc, position: position(doc, 'title') });
|
|
1503
1770
|
assert.isNotNull(completion);
|
|
1504
1771
|
const item = completion.items.find(i => i.label === 'title');
|
|
1505
1772
|
assert.isDefined(item);
|
|
1506
|
-
assert.strictEqual(item
|
|
1507
|
-
})
|
|
1773
|
+
assert.strictEqual(item?.insertTextFormat, 2);
|
|
1774
|
+
});
|
|
1508
1775
|
});
|
|
1509
1776
|
describe('inlayHints', () => {
|
|
1510
|
-
|
|
1777
|
+
before(async () => {
|
|
1778
|
+
server.didChangeConfiguration({
|
|
1779
|
+
settings: {
|
|
1780
|
+
typescript: {
|
|
1781
|
+
inlayHints: {
|
|
1782
|
+
includeInlayFunctionLikeReturnTypeHints: true,
|
|
1783
|
+
},
|
|
1784
|
+
},
|
|
1785
|
+
},
|
|
1786
|
+
});
|
|
1787
|
+
});
|
|
1788
|
+
after(() => {
|
|
1789
|
+
server.didChangeConfiguration({
|
|
1790
|
+
settings: {
|
|
1791
|
+
typescript: {
|
|
1792
|
+
inlayHints: {
|
|
1793
|
+
includeInlayFunctionLikeReturnTypeHints: false,
|
|
1794
|
+
},
|
|
1795
|
+
},
|
|
1796
|
+
},
|
|
1797
|
+
});
|
|
1798
|
+
});
|
|
1799
|
+
it('inlayHints', async () => {
|
|
1511
1800
|
const doc = {
|
|
1512
|
-
uri:
|
|
1801
|
+
uri: uri('module.ts'),
|
|
1513
1802
|
languageId: 'typescript',
|
|
1514
1803
|
version: 1,
|
|
1515
1804
|
text: `
|
|
1516
1805
|
export function foo() {
|
|
1517
1806
|
return 3
|
|
1518
1807
|
}
|
|
1519
|
-
|
|
1808
|
+
`,
|
|
1520
1809
|
};
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
preferences: {
|
|
1524
|
-
includeInlayFunctionLikeReturnTypeHints: true
|
|
1525
|
-
}
|
|
1526
|
-
},
|
|
1527
|
-
processId: null,
|
|
1528
|
-
capabilities: (0, test_utils_1.getDefaultClientCapabilities)(),
|
|
1529
|
-
workspaceFolders: [],
|
|
1530
|
-
rootUri: ''
|
|
1531
|
-
});
|
|
1532
|
-
server.didOpenTextDocument({
|
|
1533
|
-
textDocument: doc
|
|
1534
|
-
});
|
|
1535
|
-
const { inlayHints } = yield server.inlayHints({
|
|
1536
|
-
textDocument: doc
|
|
1537
|
-
});
|
|
1810
|
+
server.didOpenTextDocument({ textDocument: doc });
|
|
1811
|
+
const inlayHints = await server.inlayHints({ textDocument: doc, range: lsp.Range.create(0, 0, 4, 0) });
|
|
1538
1812
|
assert.isDefined(inlayHints);
|
|
1539
1813
|
assert.strictEqual(inlayHints.length, 1);
|
|
1540
|
-
assert.
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1814
|
+
assert.deepEqual(inlayHints[0], {
|
|
1815
|
+
label: ': number',
|
|
1816
|
+
position: { line: 1, character: 29 },
|
|
1817
|
+
kind: lsp.InlayHintKind.Type,
|
|
1818
|
+
paddingLeft: true,
|
|
1819
|
+
});
|
|
1820
|
+
});
|
|
1821
|
+
it('inlayHints (legacy)', async () => {
|
|
1545
1822
|
const doc = {
|
|
1546
|
-
uri:
|
|
1823
|
+
uri: uri('module.ts'),
|
|
1547
1824
|
languageId: 'typescript',
|
|
1548
1825
|
version: 1,
|
|
1549
1826
|
text: `
|
|
1550
1827
|
export function foo() {
|
|
1551
1828
|
return 3
|
|
1552
1829
|
}
|
|
1553
|
-
|
|
1830
|
+
`,
|
|
1554
1831
|
};
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
capabilities: (0, test_utils_1.getDefaultClientCapabilities)(),
|
|
1558
|
-
workspaceFolders: [],
|
|
1559
|
-
rootUri: ''
|
|
1560
|
-
});
|
|
1561
|
-
server.didChangeConfiguration({
|
|
1562
|
-
settings: {
|
|
1563
|
-
typescript: {
|
|
1564
|
-
inlayHints: {
|
|
1565
|
-
includeInlayFunctionLikeReturnTypeHints: true
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
});
|
|
1570
|
-
server.didOpenTextDocument({
|
|
1571
|
-
textDocument: doc
|
|
1572
|
-
});
|
|
1573
|
-
const { inlayHints } = yield server.inlayHints({
|
|
1574
|
-
textDocument: doc
|
|
1575
|
-
});
|
|
1832
|
+
server.didOpenTextDocument({ textDocument: doc });
|
|
1833
|
+
const { inlayHints } = await server.inlayHintsLegacy({ textDocument: doc });
|
|
1576
1834
|
assert.isDefined(inlayHints);
|
|
1577
1835
|
assert.strictEqual(inlayHints.length, 1);
|
|
1578
1836
|
assert.strictEqual(inlayHints[0].text, ': number');
|
|
1579
1837
|
assert.strictEqual(inlayHints[0].kind, 'Type');
|
|
1580
1838
|
assert.deepStrictEqual(inlayHints[0].position, { line: 1, character: 29 });
|
|
1581
|
-
})
|
|
1839
|
+
});
|
|
1840
|
+
});
|
|
1841
|
+
describe('completions without client snippet support', () => {
|
|
1842
|
+
let localServer;
|
|
1843
|
+
before(async () => {
|
|
1844
|
+
const clientCapabilitiesOverride = {
|
|
1845
|
+
textDocument: {
|
|
1846
|
+
completion: {
|
|
1847
|
+
completionItem: {
|
|
1848
|
+
snippetSupport: false,
|
|
1849
|
+
},
|
|
1850
|
+
},
|
|
1851
|
+
},
|
|
1852
|
+
};
|
|
1853
|
+
localServer = await createServer({
|
|
1854
|
+
rootUri: null,
|
|
1855
|
+
publishDiagnostics: args => diagnostics.set(args.uri, args),
|
|
1856
|
+
clientCapabilitiesOverride,
|
|
1857
|
+
});
|
|
1858
|
+
});
|
|
1859
|
+
beforeEach(() => {
|
|
1860
|
+
localServer.closeAll();
|
|
1861
|
+
// "closeAll" triggers final publishDiagnostics with an empty list so clear last.
|
|
1862
|
+
diagnostics.clear();
|
|
1863
|
+
localServer.workspaceEdits = [];
|
|
1864
|
+
});
|
|
1865
|
+
after(() => {
|
|
1866
|
+
localServer.closeAll();
|
|
1867
|
+
localServer.shutdown();
|
|
1868
|
+
});
|
|
1869
|
+
it('resolves completion for method completion does not contain snippet', async () => {
|
|
1870
|
+
const doc = {
|
|
1871
|
+
uri: uri('bar.ts'),
|
|
1872
|
+
languageId: 'typescript',
|
|
1873
|
+
version: 1,
|
|
1874
|
+
text: `
|
|
1875
|
+
import fs from 'fs'
|
|
1876
|
+
fs.readFile
|
|
1877
|
+
`,
|
|
1878
|
+
};
|
|
1879
|
+
localServer.didOpenTextDocument({ textDocument: doc });
|
|
1880
|
+
const proposals = await localServer.completion({ textDocument: doc, position: positionAfter(doc, 'readFile') });
|
|
1881
|
+
assert.isNotNull(proposals);
|
|
1882
|
+
const completion = proposals.items.find(completion => completion.label === 'readFile');
|
|
1883
|
+
assert.notEqual(completion.insertTextFormat, lsp.InsertTextFormat.Snippet);
|
|
1884
|
+
assert.strictEqual(completion.label, 'readFile');
|
|
1885
|
+
const resolvedItem = await localServer.completionResolve(completion);
|
|
1886
|
+
assert.strictEqual(resolvedItem.label, 'readFile');
|
|
1887
|
+
assert.strictEqual(resolvedItem.insertText, undefined);
|
|
1888
|
+
assert.strictEqual(resolvedItem.insertTextFormat, undefined);
|
|
1889
|
+
localServer.didCloseTextDocument({ textDocument: doc });
|
|
1890
|
+
});
|
|
1891
|
+
it('does not include snippet completions for element prop', async () => {
|
|
1892
|
+
const doc = {
|
|
1893
|
+
uri: uri('jsx', 'app.tsx'),
|
|
1894
|
+
languageId: 'typescriptreact',
|
|
1895
|
+
version: 1,
|
|
1896
|
+
text: readContents(filePath('jsx', 'app.tsx')),
|
|
1897
|
+
};
|
|
1898
|
+
localServer.didOpenTextDocument({
|
|
1899
|
+
textDocument: doc,
|
|
1900
|
+
});
|
|
1901
|
+
const completion = await localServer.completion({ textDocument: doc, position: position(doc, 'title') });
|
|
1902
|
+
assert.isNotNull(completion);
|
|
1903
|
+
const item = completion.items.find(i => i.label === 'title');
|
|
1904
|
+
assert.isUndefined(item);
|
|
1905
|
+
});
|
|
1906
|
+
it('does not include snippet completions for object methods', async () => {
|
|
1907
|
+
const doc = {
|
|
1908
|
+
uri: uri('foo.ts'),
|
|
1909
|
+
languageId: 'typescript',
|
|
1910
|
+
version: 1,
|
|
1911
|
+
text: `
|
|
1912
|
+
interface IFoo {
|
|
1913
|
+
bar(x: number): void;
|
|
1914
|
+
}
|
|
1915
|
+
const obj: IFoo = {
|
|
1916
|
+
/*a*/
|
|
1917
|
+
}
|
|
1918
|
+
`,
|
|
1919
|
+
};
|
|
1920
|
+
localServer.didOpenTextDocument({ textDocument: doc });
|
|
1921
|
+
const proposals = await localServer.completion({
|
|
1922
|
+
textDocument: doc,
|
|
1923
|
+
position: positionAfter(doc, '/*a*/'),
|
|
1924
|
+
});
|
|
1925
|
+
assert.isNotNull(proposals);
|
|
1926
|
+
assert.lengthOf(proposals.items, 1);
|
|
1927
|
+
assert.deepInclude(proposals.items[0], {
|
|
1928
|
+
label: 'bar',
|
|
1929
|
+
kind: 2,
|
|
1930
|
+
});
|
|
1931
|
+
});
|
|
1582
1932
|
});
|
|
1583
1933
|
//# sourceMappingURL=lsp-server.spec.js.map
|