volar-service-typescript 0.0.34 → 0.0.35
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/index.d.ts +1 -1
- package/lib/plugins/directiveComment.d.ts +1 -1
- package/lib/plugins/directiveComment.js +2 -1
- package/lib/plugins/docCommentTemplate.d.ts +1 -1
- package/lib/plugins/docCommentTemplate.js +7 -4
- package/lib/plugins/semantic.d.ts +4 -4
- package/lib/plugins/semantic.js +76 -49
- package/lib/plugins/syntactic.d.ts +4 -4
- package/lib/plugins/syntactic.js +14 -7
- package/lib/semanticFeatures/codeAction.js +2 -1
- package/lib/semanticFeatures/semanticTokens.js +4 -2
- package/lib/utils/lspConverters.js +20 -10
- package/lib/utils/snippetForFunctionCall.js +46 -44
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Provide } from './lib/plugins/semantic';
|
|
2
2
|
import { create as createSemanticServicePlugin } from './lib/plugins/semantic';
|
|
3
3
|
import { create as createSyntacticServicePlugin } from './lib/plugins/syntactic';
|
|
4
|
-
export declare function create(ts: typeof import('typescript'), options?: Parameters<typeof createSemanticServicePlugin>[1] & Parameters<typeof createSyntacticServicePlugin>[1]): import("@volar/language-service").
|
|
4
|
+
export declare function create(ts: typeof import('typescript'), options?: Parameters<typeof createSemanticServicePlugin>[1] & Parameters<typeof createSyntacticServicePlugin>[1]): import("@volar/language-service").LanguageServicePlugin<any>[];
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -26,8 +26,9 @@ function create() {
|
|
|
26
26
|
create() {
|
|
27
27
|
return {
|
|
28
28
|
provideCompletionItems(document, position) {
|
|
29
|
-
if (!(0, shared_1.isTsDocument)(document))
|
|
29
|
+
if (!(0, shared_1.isTsDocument)(document)) {
|
|
30
30
|
return;
|
|
31
|
+
}
|
|
31
32
|
const prefix = document.getText({
|
|
32
33
|
start: { line: position.line, character: 0 },
|
|
33
34
|
end: position,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type * as vscode from '@volar/language-service';
|
|
2
|
-
export declare function create(ts: typeof import('typescript')): vscode.
|
|
2
|
+
export declare function create(ts: typeof import('typescript')): vscode.LanguageServicePlugin;
|
|
3
3
|
//# sourceMappingURL=docCommentTemplate.d.ts.map
|
|
@@ -14,15 +14,18 @@ function create(ts) {
|
|
|
14
14
|
create() {
|
|
15
15
|
return {
|
|
16
16
|
provideCompletionItems(document, position) {
|
|
17
|
-
if (!(0, shared_1.isTsDocument)(document))
|
|
17
|
+
if (!(0, shared_1.isTsDocument)(document)) {
|
|
18
18
|
return;
|
|
19
|
-
|
|
19
|
+
}
|
|
20
|
+
if (!isPotentiallyValidDocCompletionPosition(document, position)) {
|
|
20
21
|
return;
|
|
22
|
+
}
|
|
21
23
|
const { languageService, fileName } = (0, syntacticLanguageService_1.getLanguageService)(ts, document);
|
|
22
24
|
const offset = document.offsetAt(position);
|
|
23
25
|
const docCommentTemplate = languageService.getDocCommentTemplateAtPosition(fileName, offset);
|
|
24
|
-
if (!docCommentTemplate)
|
|
26
|
+
if (!docCommentTemplate) {
|
|
25
27
|
return;
|
|
28
|
+
}
|
|
26
29
|
let insertText;
|
|
27
30
|
// Workaround for #43619
|
|
28
31
|
// docCommentTemplate previously returned undefined for empty jsdoc templates.
|
|
@@ -76,7 +79,7 @@ function templateToSnippet(template) {
|
|
|
76
79
|
let snippetIndex = 1;
|
|
77
80
|
template = template.replace(/\$/g, '\\$');
|
|
78
81
|
template = template.replace(/^[ \t]*(?=(\/|[ ]\*))/gm, '');
|
|
79
|
-
template = template.replace(/^(\/\*\*\s*\*[ ]*)$/m,
|
|
82
|
+
template = template.replace(/^(\/\*\*\s*\*[ ]*)$/m, x => x + `\$0`);
|
|
80
83
|
template = template.replace(/\* @param([ ]\{\S+\})?\s+(\S+)[ \t]*$/gm, (_param, type, post) => {
|
|
81
84
|
let out = '* @param ';
|
|
82
85
|
if (type === ' {any}' || type === ' {*}') {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ProviderResult, ServiceContext, LanguageServicePlugin } from '@volar/language-service';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
3
|
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
4
4
|
export interface Provide {
|
|
@@ -17,7 +17,7 @@ export interface CompletionItemData {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
export declare function create(ts: typeof import('typescript'), { isValidationEnabled, isSuggestionsEnabled, }?: {
|
|
20
|
-
isValidationEnabled?(document: TextDocument, context: ServiceContext):
|
|
21
|
-
isSuggestionsEnabled?(document: TextDocument, context: ServiceContext):
|
|
22
|
-
}):
|
|
20
|
+
isValidationEnabled?(document: TextDocument, context: ServiceContext): ProviderResult<boolean>;
|
|
21
|
+
isSuggestionsEnabled?(document: TextDocument, context: ServiceContext): ProviderResult<boolean>;
|
|
22
|
+
}): LanguageServicePlugin;
|
|
23
23
|
//# sourceMappingURL=semantic.d.ts.map
|
package/lib/plugins/semantic.js
CHANGED
|
@@ -35,7 +35,8 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
35
35
|
if (!context.language.typescript) {
|
|
36
36
|
return {};
|
|
37
37
|
}
|
|
38
|
-
const {
|
|
38
|
+
const { projectHost, languageServiceHost } = context.language.typescript;
|
|
39
|
+
const sys = projectHost;
|
|
39
40
|
const created = tsWithImportCache.createLanguageService(ts, sys, languageServiceHost, proxiedHost => ts.createLanguageService(proxiedHost, getDocumentRegistry(ts, sys.useCaseSensitiveFileNames, languageServiceHost.getCurrentDirectory())));
|
|
40
41
|
const { languageService } = created;
|
|
41
42
|
if (created.setPreferences && context.env.getConfiguration) {
|
|
@@ -54,7 +55,7 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
54
55
|
? (id) => id
|
|
55
56
|
: (id) => id.toLowerCase();
|
|
56
57
|
updateSourceScriptFileNames();
|
|
57
|
-
context.env.onDidChangeWatchedFiles?.(
|
|
58
|
+
context.env.onDidChangeWatchedFiles?.(params => {
|
|
58
59
|
const someFileCreateOrDeiete = params.changes.some(change => change.type !== 2);
|
|
59
60
|
if (someFileCreateOrDeiete) {
|
|
60
61
|
updateSourceScriptFileNames();
|
|
@@ -70,14 +71,14 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
70
71
|
sourceScriptNames.clear();
|
|
71
72
|
for (const fileName of languageServiceHost.getScriptFileNames()) {
|
|
72
73
|
const uri = context.env.typescript.fileNameToUri(fileName);
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
75
|
-
const tsCode =
|
|
74
|
+
const sourceScript = context.language.scripts.get(uri);
|
|
75
|
+
if (sourceScript?.generated) {
|
|
76
|
+
const tsCode = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
|
|
76
77
|
if (tsCode) {
|
|
77
78
|
sourceScriptNames.add(normalizeFileName(fileName));
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
|
-
else if (
|
|
81
|
+
else if (sourceScript) {
|
|
81
82
|
sourceScriptNames.add(normalizeFileName(fileName));
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -96,29 +97,34 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
96
97
|
},
|
|
97
98
|
fileNameToUri(fileName) {
|
|
98
99
|
const uri = context.env.typescript.fileNameToUri(fileName);
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
let virtualCode =
|
|
102
|
-
if (!virtualCode &&
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
105
|
-
virtualCode =
|
|
100
|
+
const sourceScript = context.language.scripts.get(uri);
|
|
101
|
+
const extraServiceScript = context.language.typescript.getExtraServiceScript(fileName);
|
|
102
|
+
let virtualCode = extraServiceScript?.code;
|
|
103
|
+
if (!virtualCode && sourceScript?.generated?.languagePlugin.typescript) {
|
|
104
|
+
const serviceScript = sourceScript.generated.languagePlugin.typescript.getServiceScript(sourceScript.generated.root);
|
|
105
|
+
if (serviceScript) {
|
|
106
|
+
virtualCode = serviceScript.code;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
|
-
if (virtualCode) {
|
|
109
|
-
|
|
110
|
-
return context.documents.getVirtualCodeUri(sourceFile.id, virtualCode.id);
|
|
109
|
+
if (sourceScript && virtualCode) {
|
|
110
|
+
return context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id);
|
|
111
111
|
}
|
|
112
112
|
return uri;
|
|
113
113
|
},
|
|
114
114
|
getTextDocument(uri) {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
|
|
115
|
+
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
116
|
+
if (decoded) {
|
|
117
|
+
const sourceScript = context.language.scripts.get(decoded[0]);
|
|
118
|
+
const virtualCode = sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
119
|
+
if (virtualCode) {
|
|
120
|
+
return context.documents.get(uri, virtualCode.languageId, virtualCode.snapshot);
|
|
121
|
+
}
|
|
118
122
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
else {
|
|
124
|
+
const sourceFile = context.language.scripts.get(uri);
|
|
125
|
+
if (sourceFile) {
|
|
126
|
+
return context.documents.get(uri, sourceFile.languageId, sourceFile.snapshot);
|
|
127
|
+
}
|
|
122
128
|
}
|
|
123
129
|
throw new Error(`getTextDocument: uri not found: ${uri}`);
|
|
124
130
|
},
|
|
@@ -137,10 +143,12 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
137
143
|
languageService.dispose();
|
|
138
144
|
},
|
|
139
145
|
async provideCompletionItems(document, position, completeContext, token) {
|
|
140
|
-
if (!isSemanticDocument(document))
|
|
146
|
+
if (!isSemanticDocument(document)) {
|
|
141
147
|
return;
|
|
142
|
-
|
|
148
|
+
}
|
|
149
|
+
if (!await isSuggestionsEnabled(document, context)) {
|
|
143
150
|
return;
|
|
151
|
+
}
|
|
144
152
|
return await worker(token, async () => {
|
|
145
153
|
const preferences = await (0, getUserPreferences_1.getUserPreferences)(ctx, document);
|
|
146
154
|
const fileName = ctx.uriToFileName(document.uri);
|
|
@@ -244,8 +252,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
244
252
|
}) ?? item;
|
|
245
253
|
},
|
|
246
254
|
provideRenameRange(document, position, token) {
|
|
247
|
-
if (!isSemanticDocument(document))
|
|
255
|
+
if (!isSemanticDocument(document)) {
|
|
248
256
|
return;
|
|
257
|
+
}
|
|
249
258
|
return worker(token, () => {
|
|
250
259
|
const fileName = ctx.uriToFileName(document.uri);
|
|
251
260
|
const offset = document.offsetAt(position);
|
|
@@ -260,8 +269,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
260
269
|
});
|
|
261
270
|
},
|
|
262
271
|
provideRenameEdits(document, position, newName, token) {
|
|
263
|
-
if (!isSemanticDocument(document, true))
|
|
272
|
+
if (!isSemanticDocument(document, true)) {
|
|
264
273
|
return;
|
|
274
|
+
}
|
|
265
275
|
return worker(token, async () => {
|
|
266
276
|
const fileName = ctx.uriToFileName(document.uri);
|
|
267
277
|
const offset = document.offsetAt(position);
|
|
@@ -307,8 +317,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
307
317
|
});
|
|
308
318
|
},
|
|
309
319
|
provideCodeActions(document, range, context, token) {
|
|
310
|
-
if (!isSemanticDocument(document))
|
|
320
|
+
if (!isSemanticDocument(document)) {
|
|
311
321
|
return;
|
|
322
|
+
}
|
|
312
323
|
return worker(token, () => {
|
|
313
324
|
return getCodeActions(document, range, context);
|
|
314
325
|
});
|
|
@@ -319,8 +330,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
319
330
|
}) ?? codeAction;
|
|
320
331
|
},
|
|
321
332
|
provideInlayHints(document, range, token) {
|
|
322
|
-
if (!isSemanticDocument(document))
|
|
333
|
+
if (!isSemanticDocument(document)) {
|
|
323
334
|
return;
|
|
335
|
+
}
|
|
324
336
|
return worker(token, async () => {
|
|
325
337
|
const preferences = await (0, getUserPreferences_1.getUserPreferences)(ctx, document);
|
|
326
338
|
const fileName = ctx.uriToFileName(document.uri);
|
|
@@ -336,8 +348,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
336
348
|
});
|
|
337
349
|
},
|
|
338
350
|
provideCallHierarchyItems(document, position, token) {
|
|
339
|
-
if (!isSemanticDocument(document))
|
|
351
|
+
if (!isSemanticDocument(document)) {
|
|
340
352
|
return;
|
|
353
|
+
}
|
|
341
354
|
return worker(token, () => {
|
|
342
355
|
const fileName = ctx.uriToFileName(document.uri);
|
|
343
356
|
const offset = document.offsetAt(position);
|
|
@@ -376,8 +389,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
376
389
|
}) ?? [];
|
|
377
390
|
},
|
|
378
391
|
provideDefinition(document, position, token) {
|
|
379
|
-
if (!isSemanticDocument(document))
|
|
392
|
+
if (!isSemanticDocument(document)) {
|
|
380
393
|
return;
|
|
394
|
+
}
|
|
381
395
|
return worker(token, () => {
|
|
382
396
|
const fileName = ctx.uriToFileName(document.uri);
|
|
383
397
|
const offset = document.offsetAt(position);
|
|
@@ -389,8 +403,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
389
403
|
});
|
|
390
404
|
},
|
|
391
405
|
provideTypeDefinition(document, position, token) {
|
|
392
|
-
if (!isSemanticDocument(document))
|
|
406
|
+
if (!isSemanticDocument(document)) {
|
|
393
407
|
return;
|
|
408
|
+
}
|
|
394
409
|
return worker(token, () => {
|
|
395
410
|
const fileName = ctx.uriToFileName(document.uri);
|
|
396
411
|
const offset = document.offsetAt(position);
|
|
@@ -408,8 +423,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
408
423
|
return provideDiagnosticsWorker(document, token, 'semantic');
|
|
409
424
|
},
|
|
410
425
|
provideHover(document, position, token) {
|
|
411
|
-
if (!isSemanticDocument(document))
|
|
426
|
+
if (!isSemanticDocument(document)) {
|
|
412
427
|
return;
|
|
428
|
+
}
|
|
413
429
|
return worker(token, () => {
|
|
414
430
|
const fileName = ctx.uriToFileName(document.uri);
|
|
415
431
|
const offset = document.offsetAt(position);
|
|
@@ -421,8 +437,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
421
437
|
});
|
|
422
438
|
},
|
|
423
439
|
provideImplementation(document, position, token) {
|
|
424
|
-
if (!isSemanticDocument(document))
|
|
440
|
+
if (!isSemanticDocument(document)) {
|
|
425
441
|
return;
|
|
442
|
+
}
|
|
426
443
|
return worker(token, () => {
|
|
427
444
|
const fileName = ctx.uriToFileName(document.uri);
|
|
428
445
|
const offset = document.offsetAt(position);
|
|
@@ -434,8 +451,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
434
451
|
});
|
|
435
452
|
},
|
|
436
453
|
provideReferences(document, position, referenceContext, token) {
|
|
437
|
-
if (!isSemanticDocument(document, true))
|
|
454
|
+
if (!isSemanticDocument(document, true)) {
|
|
438
455
|
return;
|
|
456
|
+
}
|
|
439
457
|
return worker(token, () => {
|
|
440
458
|
const fileName = ctx.uriToFileName(document.uri);
|
|
441
459
|
const offset = document.offsetAt(position);
|
|
@@ -462,8 +480,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
462
480
|
});
|
|
463
481
|
},
|
|
464
482
|
provideFileReferences(document, token) {
|
|
465
|
-
if (!isSemanticDocument(document, true))
|
|
483
|
+
if (!isSemanticDocument(document, true)) {
|
|
466
484
|
return;
|
|
485
|
+
}
|
|
467
486
|
return worker(token, () => {
|
|
468
487
|
const fileName = ctx.uriToFileName(document.uri);
|
|
469
488
|
const entries = (0, shared_1.safeCall)(() => ctx.languageService.getFileReferences(fileName));
|
|
@@ -474,8 +493,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
474
493
|
});
|
|
475
494
|
},
|
|
476
495
|
provideDocumentHighlights(document, position, token) {
|
|
477
|
-
if (!isSemanticDocument(document))
|
|
496
|
+
if (!isSemanticDocument(document)) {
|
|
478
497
|
return;
|
|
498
|
+
}
|
|
479
499
|
return worker(token, () => {
|
|
480
500
|
const fileName = ctx.uriToFileName(document.uri);
|
|
481
501
|
const offset = document.offsetAt(position);
|
|
@@ -493,8 +513,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
493
513
|
});
|
|
494
514
|
},
|
|
495
515
|
provideDocumentSemanticTokens(document, range, legend, token) {
|
|
496
|
-
if (!isSemanticDocument(document))
|
|
516
|
+
if (!isSemanticDocument(document)) {
|
|
497
517
|
return;
|
|
518
|
+
}
|
|
498
519
|
return worker(token, () => {
|
|
499
520
|
return getDocumentSemanticTokens(document, range, legend);
|
|
500
521
|
});
|
|
@@ -528,8 +549,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
528
549
|
});
|
|
529
550
|
},
|
|
530
551
|
provideSelectionRanges(document, positions, token) {
|
|
531
|
-
if (!isSemanticDocument(document))
|
|
552
|
+
if (!isSemanticDocument(document)) {
|
|
532
553
|
return;
|
|
554
|
+
}
|
|
533
555
|
return worker(token, () => {
|
|
534
556
|
return positions
|
|
535
557
|
.map(position => {
|
|
@@ -545,8 +567,9 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
545
567
|
});
|
|
546
568
|
},
|
|
547
569
|
provideSignatureHelp(document, position, context, token) {
|
|
548
|
-
if (!isSemanticDocument(document))
|
|
570
|
+
if (!isSemanticDocument(document)) {
|
|
549
571
|
return;
|
|
572
|
+
}
|
|
550
573
|
return worker(token, () => {
|
|
551
574
|
const options = {};
|
|
552
575
|
if (context?.triggerKind === 1) {
|
|
@@ -602,10 +625,12 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
602
625
|
},
|
|
603
626
|
};
|
|
604
627
|
async function provideDiagnosticsWorker(document, token, mode) {
|
|
605
|
-
if (!isSemanticDocument(document))
|
|
628
|
+
if (!isSemanticDocument(document)) {
|
|
606
629
|
return;
|
|
607
|
-
|
|
630
|
+
}
|
|
631
|
+
if (!await isValidationEnabled(document, context)) {
|
|
608
632
|
return;
|
|
633
|
+
}
|
|
609
634
|
return await worker(token, () => {
|
|
610
635
|
const fileName = ctx.uriToFileName(document.uri);
|
|
611
636
|
const program = ctx.languageService.getProgram();
|
|
@@ -653,7 +678,7 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
653
678
|
async function worker(token, fn) {
|
|
654
679
|
let result;
|
|
655
680
|
let oldSysVersion;
|
|
656
|
-
let newSysVersion = await
|
|
681
|
+
let newSysVersion = await projectHost.syncSystem?.();
|
|
657
682
|
do {
|
|
658
683
|
oldSysVersion = newSysVersion;
|
|
659
684
|
try {
|
|
@@ -663,22 +688,24 @@ function create(ts, { isValidationEnabled = async (document, context) => {
|
|
|
663
688
|
console.warn(err);
|
|
664
689
|
break;
|
|
665
690
|
}
|
|
666
|
-
newSysVersion = await
|
|
691
|
+
newSysVersion = await projectHost.syncSystem?.();
|
|
667
692
|
} while (newSysVersion !== oldSysVersion && !token.isCancellationRequested);
|
|
668
693
|
return result;
|
|
669
694
|
}
|
|
670
695
|
function getVirtualScriptByUri(uri) {
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
696
|
+
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
697
|
+
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
698
|
+
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
699
|
+
if (virtualCode && sourceScript?.generated?.languagePlugin.typescript) {
|
|
700
|
+
const { getServiceScript, getExtraServiceScripts } = sourceScript.generated?.languagePlugin.typescript;
|
|
701
|
+
const sourceFileName = context.env.typescript.uriToFileName(sourceScript.id);
|
|
702
|
+
if (getServiceScript(sourceScript.generated.root)?.code === virtualCode) {
|
|
676
703
|
return {
|
|
677
704
|
fileName: sourceFileName,
|
|
678
705
|
code: virtualCode,
|
|
679
706
|
};
|
|
680
707
|
}
|
|
681
|
-
for (const extraScript of
|
|
708
|
+
for (const extraScript of getExtraServiceScripts?.(sourceFileName, sourceScript.generated.root) ?? []) {
|
|
682
709
|
if (extraScript.code === virtualCode) {
|
|
683
710
|
return extraScript;
|
|
684
711
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ProviderResult, ServiceContext, LanguageServicePlugin } from '@volar/language-service';
|
|
2
2
|
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
3
3
|
export declare function create(ts: typeof import('typescript'), { isFormattingEnabled, isAutoClosingTagsEnabled, }?: {
|
|
4
|
-
isFormattingEnabled?(document: TextDocument, context: ServiceContext):
|
|
5
|
-
isAutoClosingTagsEnabled?(document: TextDocument, context: ServiceContext):
|
|
6
|
-
}):
|
|
4
|
+
isFormattingEnabled?(document: TextDocument, context: ServiceContext): ProviderResult<boolean>;
|
|
5
|
+
isAutoClosingTagsEnabled?(document: TextDocument, context: ServiceContext): ProviderResult<boolean>;
|
|
6
|
+
}): LanguageServicePlugin;
|
|
7
7
|
//# sourceMappingURL=syntactic.d.ts.map
|
package/lib/plugins/syntactic.js
CHANGED
|
@@ -28,8 +28,9 @@ function create(ts, { isFormattingEnabled = async (document, context) => {
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
provideFoldingRanges(document) {
|
|
31
|
-
if (!(0, shared_1.isTsDocument)(document))
|
|
31
|
+
if (!(0, shared_1.isTsDocument)(document)) {
|
|
32
32
|
return;
|
|
33
|
+
}
|
|
33
34
|
const { languageService, fileName } = (0, syntacticLanguageService_1.getLanguageService)(ts, document);
|
|
34
35
|
const outliningSpans = (0, shared_1.safeCall)(() => languageService.getOutliningSpans(fileName));
|
|
35
36
|
if (!outliningSpans) {
|
|
@@ -38,12 +39,14 @@ function create(ts, { isFormattingEnabled = async (document, context) => {
|
|
|
38
39
|
return outliningSpans.map(span => (0, lspConverters_1.convertOutliningSpan)(span, document));
|
|
39
40
|
},
|
|
40
41
|
provideDocumentSymbols(document) {
|
|
41
|
-
if (!(0, shared_1.isTsDocument)(document))
|
|
42
|
+
if (!(0, shared_1.isTsDocument)(document)) {
|
|
42
43
|
return;
|
|
44
|
+
}
|
|
43
45
|
const { languageService, fileName } = (0, syntacticLanguageService_1.getLanguageService)(ts, document);
|
|
44
46
|
const barItems = (0, shared_1.safeCall)(() => languageService.getNavigationTree(fileName));
|
|
45
|
-
if (!barItems)
|
|
47
|
+
if (!barItems) {
|
|
46
48
|
return [];
|
|
49
|
+
}
|
|
47
50
|
// The root represents the file. Ignore this when showing in the UI
|
|
48
51
|
return barItems.childItems
|
|
49
52
|
?.map(item => (0, lspConverters_1.convertNavTree)(item, document))
|
|
@@ -51,10 +54,12 @@ function create(ts, { isFormattingEnabled = async (document, context) => {
|
|
|
51
54
|
?? [];
|
|
52
55
|
},
|
|
53
56
|
async provideDocumentFormattingEdits(document, range, options, codeOptions) {
|
|
54
|
-
if (!(0, shared_1.isTsDocument)(document))
|
|
57
|
+
if (!(0, shared_1.isTsDocument)(document)) {
|
|
55
58
|
return;
|
|
56
|
-
|
|
59
|
+
}
|
|
60
|
+
if (!await isFormattingEnabled(document, context)) {
|
|
57
61
|
return;
|
|
62
|
+
}
|
|
58
63
|
const tsOptions = await (0, getFormatCodeSettings_1.getFormatCodeSettings)(context, document, options);
|
|
59
64
|
if (codeOptions) {
|
|
60
65
|
tsOptions.baseIndentSize = codeOptions.initialIndentLevel * options.tabSize;
|
|
@@ -69,10 +74,12 @@ function create(ts, { isFormattingEnabled = async (document, context) => {
|
|
|
69
74
|
return scriptEdits.map(edit => (0, lspConverters_1.convertTextChange)(edit, document));
|
|
70
75
|
},
|
|
71
76
|
async provideOnTypeFormattingEdits(document, position, key, options, codeOptions) {
|
|
72
|
-
if (!(0, shared_1.isTsDocument)(document))
|
|
77
|
+
if (!(0, shared_1.isTsDocument)(document)) {
|
|
73
78
|
return;
|
|
74
|
-
|
|
79
|
+
}
|
|
80
|
+
if (!await isFormattingEnabled(document, context)) {
|
|
75
81
|
return;
|
|
82
|
+
}
|
|
76
83
|
const tsOptions = await (0, getFormatCodeSettings_1.getFormatCodeSettings)(context, document, options);
|
|
77
84
|
if (codeOptions) {
|
|
78
85
|
tsOptions.baseIndentSize = codeOptions.initialIndentLevel * options.tabSize;
|
|
@@ -7,11 +7,13 @@ function register(ts, ctx) {
|
|
|
7
7
|
const fileName = ctx.uriToFileName(document.uri);
|
|
8
8
|
const start = range ? document.offsetAt(range.start) : 0;
|
|
9
9
|
const length = range ? (document.offsetAt(range.end) - start) : document.getText().length;
|
|
10
|
-
if (ctx.language.typescript?.languageServiceHost.getCancellationToken?.().isCancellationRequested())
|
|
10
|
+
if (ctx.language.typescript?.languageServiceHost.getCancellationToken?.().isCancellationRequested()) {
|
|
11
11
|
return;
|
|
12
|
+
}
|
|
12
13
|
const response = (0, shared_1.safeCall)(() => ctx.languageService.getEncodedSemanticClassifications(fileName, { start, length }, ts.SemanticClassificationFormat.TwentyTwenty));
|
|
13
|
-
if (!response)
|
|
14
|
+
if (!response) {
|
|
14
15
|
return;
|
|
16
|
+
}
|
|
15
17
|
let tokenModifiersTable = [];
|
|
16
18
|
tokenModifiersTable[2 /* TokenModifier.async */] = 1 << legend.tokenModifiers.indexOf('async');
|
|
17
19
|
tokenModifiersTable[0 /* TokenModifier.declaration */] = 1 << legend.tokenModifiers.indexOf('declaration');
|
|
@@ -10,10 +10,12 @@ const typeConverters = require("../utils/typeConverters");
|
|
|
10
10
|
const semver = require("semver");
|
|
11
11
|
// diagnostics
|
|
12
12
|
function convertDiagnostic(diag, document, fileNameToUri, getTextDocument) {
|
|
13
|
-
if (diag.start === undefined)
|
|
13
|
+
if (diag.start === undefined) {
|
|
14
14
|
return;
|
|
15
|
-
|
|
15
|
+
}
|
|
16
|
+
if (diag.length === undefined) {
|
|
16
17
|
return;
|
|
18
|
+
}
|
|
17
19
|
const diagnostic = {
|
|
18
20
|
range: {
|
|
19
21
|
start: document.positionAt(diag.start),
|
|
@@ -30,29 +32,34 @@ function convertDiagnostic(diag, document, fileNameToUri, getTextDocument) {
|
|
|
30
32
|
.filter((v) => !!v);
|
|
31
33
|
}
|
|
32
34
|
if (diag.reportsUnnecessary) {
|
|
33
|
-
if (diagnostic.tags === undefined)
|
|
35
|
+
if (diagnostic.tags === undefined) {
|
|
34
36
|
diagnostic.tags = [];
|
|
37
|
+
}
|
|
35
38
|
diagnostic.tags.push(1);
|
|
36
39
|
}
|
|
37
40
|
if (diag.reportsDeprecated) {
|
|
38
|
-
if (diagnostic.tags === undefined)
|
|
41
|
+
if (diagnostic.tags === undefined) {
|
|
39
42
|
diagnostic.tags = [];
|
|
43
|
+
}
|
|
40
44
|
diagnostic.tags.push(2);
|
|
41
45
|
}
|
|
42
46
|
return diagnostic;
|
|
43
47
|
}
|
|
44
48
|
exports.convertDiagnostic = convertDiagnostic;
|
|
45
49
|
function convertDiagnosticRelatedInformation(diag, fileNameToUri, getTextDocument) {
|
|
46
|
-
if (diag.start === undefined)
|
|
50
|
+
if (diag.start === undefined) {
|
|
47
51
|
return;
|
|
48
|
-
|
|
52
|
+
}
|
|
53
|
+
if (diag.length === undefined) {
|
|
49
54
|
return;
|
|
55
|
+
}
|
|
50
56
|
let document;
|
|
51
57
|
if (diag.file) {
|
|
52
58
|
document = getTextDocument(fileNameToUri(diag.file.fileName));
|
|
53
59
|
}
|
|
54
|
-
if (!document)
|
|
60
|
+
if (!document) {
|
|
55
61
|
return;
|
|
62
|
+
}
|
|
56
63
|
const diagnostic = {
|
|
57
64
|
location: {
|
|
58
65
|
uri: document.uri,
|
|
@@ -215,8 +222,9 @@ function convertCompletionInfo(ts, completionContext, document, position, create
|
|
|
215
222
|
function getDotAccessorContext(document) {
|
|
216
223
|
let dotAccessorContext;
|
|
217
224
|
if (gte_300) {
|
|
218
|
-
if (!completionContext)
|
|
225
|
+
if (!completionContext) {
|
|
219
226
|
return;
|
|
227
|
+
}
|
|
220
228
|
const isMemberCompletion = completionContext.isMemberCompletion;
|
|
221
229
|
if (isMemberCompletion) {
|
|
222
230
|
const dotMatch = line.slice(0, position.character).match(/\??\.\s*$/) || undefined;
|
|
@@ -529,10 +537,12 @@ function convertRenameLocations(newText, locations, fileNameToUri, getTextDocume
|
|
|
529
537
|
workspaceEdit.changes[uri] = [];
|
|
530
538
|
}
|
|
531
539
|
let _newText = newText;
|
|
532
|
-
if (location.prefixText)
|
|
540
|
+
if (location.prefixText) {
|
|
533
541
|
_newText = location.prefixText + _newText;
|
|
534
|
-
|
|
542
|
+
}
|
|
543
|
+
if (location.suffixText) {
|
|
535
544
|
_newText = _newText + location.suffixText;
|
|
545
|
+
}
|
|
536
546
|
workspaceEdit.changes[uri].push({
|
|
537
547
|
newText: _newText,
|
|
538
548
|
range: convertTextSpan(location.textSpan, doc),
|
|
@@ -35,53 +35,55 @@ function getParameterListParts(displayParts) {
|
|
|
35
35
|
let hasOptionalParameters = false;
|
|
36
36
|
let parenCount = 0;
|
|
37
37
|
let braceCount = 0;
|
|
38
|
-
outer:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
break;
|
|
49
|
-
case PConst.DisplayPartKind.parameterName:
|
|
50
|
-
if (parenCount === 1 && braceCount === 0 && isInMethod) {
|
|
51
|
-
// Only take top level paren names
|
|
52
|
-
const next = displayParts[i + 1];
|
|
53
|
-
// Skip optional parameters
|
|
54
|
-
const nameIsFollowedByOptionalIndicator = next && next.text === '?';
|
|
55
|
-
// Skip this parameter
|
|
56
|
-
const nameIsThis = part.text === 'this';
|
|
57
|
-
if (!nameIsFollowedByOptionalIndicator && !nameIsThis) {
|
|
58
|
-
parts.push(part);
|
|
38
|
+
outer: {
|
|
39
|
+
for (let i = 0; i < displayParts.length; ++i) {
|
|
40
|
+
const part = displayParts[i];
|
|
41
|
+
switch (part.kind) {
|
|
42
|
+
case PConst.DisplayPartKind.methodName:
|
|
43
|
+
case PConst.DisplayPartKind.functionName:
|
|
44
|
+
case PConst.DisplayPartKind.text:
|
|
45
|
+
case PConst.DisplayPartKind.propertyName:
|
|
46
|
+
if (parenCount === 0 && braceCount === 0) {
|
|
47
|
+
isInMethod = true;
|
|
59
48
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
break;
|
|
50
|
+
case PConst.DisplayPartKind.parameterName:
|
|
51
|
+
if (parenCount === 1 && braceCount === 0 && isInMethod) {
|
|
52
|
+
// Only take top level paren names
|
|
53
|
+
const next = displayParts[i + 1];
|
|
54
|
+
// Skip optional parameters
|
|
55
|
+
const nameIsFollowedByOptionalIndicator = next && next.text === '?';
|
|
56
|
+
// Skip this parameter
|
|
57
|
+
const nameIsThis = part.text === 'this';
|
|
58
|
+
if (!nameIsFollowedByOptionalIndicator && !nameIsThis) {
|
|
59
|
+
parts.push(part);
|
|
60
|
+
}
|
|
61
|
+
hasOptionalParameters = hasOptionalParameters || nameIsFollowedByOptionalIndicator;
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
case PConst.DisplayPartKind.punctuation:
|
|
65
|
+
if (part.text === '(') {
|
|
66
|
+
++parenCount;
|
|
67
|
+
}
|
|
68
|
+
else if (part.text === ')') {
|
|
69
|
+
--parenCount;
|
|
70
|
+
if (parenCount <= 0 && isInMethod) {
|
|
71
|
+
break outer;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (part.text === '...' && parenCount === 1) {
|
|
75
|
+
// Found rest parmeter. Do not fill in any further arguments
|
|
76
|
+
hasOptionalParameters = true;
|
|
70
77
|
break outer;
|
|
71
78
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
else if (part.text === '}') {
|
|
82
|
-
--braceCount;
|
|
83
|
-
}
|
|
84
|
-
break;
|
|
79
|
+
else if (part.text === '{') {
|
|
80
|
+
++braceCount;
|
|
81
|
+
}
|
|
82
|
+
else if (part.text === '}') {
|
|
83
|
+
--braceCount;
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
return { hasOptionalParameters, parts };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "volar-service-typescript",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.35",
|
|
4
4
|
"description": "Integrate TypeScript into Volar",
|
|
5
5
|
"homepage": "https://github.com/volarjs/services/tree/master/packages/typescript",
|
|
6
6
|
"bugs": "https://github.com/volarjs/services/issues",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"vscode-nls": "^5.2.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@volar/language-service": "~2.
|
|
38
|
+
"@volar/language-service": "~2.2.0-alpha.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@volar/language-service": {
|
|
42
42
|
"optional": true
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "cbd8ef0ada6eae9656286535599c9b289134d1e3"
|
|
46
46
|
}
|