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