@volar/typescript 2.2.0-alpha.9 → 2.2.1
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/lib/common.d.ts +2 -0
- package/lib/common.js +20 -0
- package/lib/node/decorateLanguageService.js +134 -85
- package/lib/node/decorateLanguageServiceHost.js +13 -1
- package/lib/node/decorateProgram.js +5 -5
- package/lib/node/dedupe.d.ts +0 -1
- package/lib/node/dedupe.js +1 -9
- package/lib/node/proxyCreateProgram.d.ts +1 -1
- package/lib/node/proxyCreateProgram.js +7 -3
- package/lib/node/transform.d.ts +2 -1
- package/lib/node/transform.js +16 -12
- package/lib/protocol/createProject.js +6 -2
- package/lib/quickstart/createAsyncLanguageServicePlugin.d.ts +1 -1
- package/lib/quickstart/createAsyncLanguageServicePlugin.js +13 -3
- package/lib/quickstart/createLanguageServicePlugin.d.ts +1 -1
- package/lib/quickstart/createLanguageServicePlugin.js +14 -3
- package/lib/quickstart/runTsc.d.ts +1 -2
- package/lib/quickstart/runTsc.js +2 -6
- package/lib/resolveModuleName.js +29 -14
- package/package.json +4 -4
- package/lib/documentRegistry.d.ts +0 -2
- package/lib/documentRegistry.js +0 -14
package/lib/common.d.ts
ADDED
package/lib/common.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fileLanguageIdProviderPlugin = void 0;
|
|
4
|
+
exports.fileLanguageIdProviderPlugin = {
|
|
5
|
+
getLanguageId(scriptId) {
|
|
6
|
+
const ext = scriptId.split('.').pop();
|
|
7
|
+
switch (ext) {
|
|
8
|
+
case 'js': return 'javascript';
|
|
9
|
+
case 'cjs': return 'javascript';
|
|
10
|
+
case 'mjs': return 'javascript';
|
|
11
|
+
case 'ts': return 'typescript';
|
|
12
|
+
case 'cts': return 'typescript';
|
|
13
|
+
case 'mts': return 'typescript';
|
|
14
|
+
case 'jsx': return 'javascriptreact';
|
|
15
|
+
case 'tsx': return 'typescriptreact';
|
|
16
|
+
case 'json': return 'json';
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -5,10 +5,12 @@ const language_core_1 = require("@volar/language-core");
|
|
|
5
5
|
const dedupe_1 = require("./dedupe");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const transform_1 = require("./transform");
|
|
8
|
+
const windowsPathReg = /\\/g;
|
|
8
9
|
function decorateLanguageService(language, languageService) {
|
|
9
10
|
// ignored methods
|
|
10
11
|
const { getNavigationTree, getOutliningSpans, } = languageService;
|
|
11
|
-
languageService.getNavigationTree =
|
|
12
|
+
languageService.getNavigationTree = filePath => {
|
|
13
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
12
14
|
const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
13
15
|
if (serviceScript) {
|
|
14
16
|
const tree = getNavigationTree(fileName);
|
|
@@ -19,7 +21,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
19
21
|
return getNavigationTree(fileName);
|
|
20
22
|
}
|
|
21
23
|
};
|
|
22
|
-
languageService.getOutliningSpans =
|
|
24
|
+
languageService.getOutliningSpans = filePath => {
|
|
25
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
23
26
|
const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
24
27
|
if (serviceScript) {
|
|
25
28
|
return [];
|
|
@@ -29,8 +32,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
29
32
|
}
|
|
30
33
|
};
|
|
31
34
|
// methods
|
|
32
|
-
const { findReferences, findRenameLocations, getCompletionEntryDetails, getCompletionsAtPosition, getDefinitionAndBoundSpan, getDefinitionAtPosition, getFileReferences, getFormattingEditsForDocument, getFormattingEditsForRange, getFormattingEditsAfterKeystroke, getImplementationAtPosition, getLinkedEditingRangeAtPosition, getQuickInfoAtPosition, getReferencesAtPosition, getSemanticDiagnostics, getSyntacticDiagnostics, getSuggestionDiagnostics, getTypeDefinitionAtPosition, getEncodedSemanticClassifications, getDocumentHighlights, getApplicableRefactors, getEditsForFileRename, getEditsForRefactor, getRenameInfo, getCodeFixesAtPosition, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, organizeImports, } = languageService;
|
|
33
|
-
languageService.getFormattingEditsForDocument = (
|
|
35
|
+
const { findReferences, findRenameLocations, getCompletionEntryDetails, getCompletionsAtPosition, getDefinitionAndBoundSpan, getDefinitionAtPosition, getFileReferences, getFormattingEditsForDocument, getFormattingEditsForRange, getFormattingEditsAfterKeystroke, getImplementationAtPosition, getLinkedEditingRangeAtPosition, getQuickInfoAtPosition, getSignatureHelpItems, getReferencesAtPosition, getSemanticDiagnostics, getSyntacticDiagnostics, getSuggestionDiagnostics, getTypeDefinitionAtPosition, getEncodedSemanticClassifications, getDocumentHighlights, getApplicableRefactors, getEditsForFileRename, getEditsForRefactor, getRenameInfo, getCodeFixesAtPosition, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, organizeImports, } = languageService;
|
|
36
|
+
languageService.getFormattingEditsForDocument = (filePath, options) => {
|
|
37
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
34
38
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
35
39
|
if (serviceScript) {
|
|
36
40
|
if (!map.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) {
|
|
@@ -45,7 +49,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
45
49
|
return getFormattingEditsForDocument(fileName, options);
|
|
46
50
|
}
|
|
47
51
|
};
|
|
48
|
-
languageService.getFormattingEditsForRange = (
|
|
52
|
+
languageService.getFormattingEditsForRange = (filePath, start, end, options) => {
|
|
53
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
49
54
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
50
55
|
if (serviceScript) {
|
|
51
56
|
const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isFormattingEnabled);
|
|
@@ -62,7 +67,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
62
67
|
return getFormattingEditsForRange(fileName, start, end, options);
|
|
63
68
|
}
|
|
64
69
|
};
|
|
65
|
-
languageService.getFormattingEditsAfterKeystroke = (
|
|
70
|
+
languageService.getFormattingEditsAfterKeystroke = (filePath, position, key, options) => {
|
|
71
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
66
72
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
67
73
|
if (serviceScript) {
|
|
68
74
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isFormattingEnabled);
|
|
@@ -84,7 +90,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
84
90
|
.map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isRenameEnabled))
|
|
85
91
|
.filter(utils_1.notEmpty);
|
|
86
92
|
};
|
|
87
|
-
languageService.getLinkedEditingRangeAtPosition = (
|
|
93
|
+
languageService.getLinkedEditingRangeAtPosition = (filePath, position) => {
|
|
94
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
88
95
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
89
96
|
if (serviceScript) {
|
|
90
97
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isLinkedEditingEnabled);
|
|
@@ -104,7 +111,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
104
111
|
return getLinkedEditingRangeAtPosition(fileName, position);
|
|
105
112
|
}
|
|
106
113
|
};
|
|
107
|
-
languageService.prepareCallHierarchy = (
|
|
114
|
+
languageService.prepareCallHierarchy = (filePath, position) => {
|
|
115
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
108
116
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
109
117
|
if (serviceScript) {
|
|
110
118
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled);
|
|
@@ -122,8 +130,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
122
130
|
return prepareCallHierarchy(fileName, position);
|
|
123
131
|
}
|
|
124
132
|
};
|
|
125
|
-
languageService.provideCallHierarchyIncomingCalls = (
|
|
133
|
+
languageService.provideCallHierarchyIncomingCalls = (filePath, position) => {
|
|
126
134
|
let calls = [];
|
|
135
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
127
136
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
128
137
|
if (serviceScript) {
|
|
129
138
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled);
|
|
@@ -146,8 +155,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
146
155
|
};
|
|
147
156
|
});
|
|
148
157
|
};
|
|
149
|
-
languageService.provideCallHierarchyOutgoingCalls = (
|
|
158
|
+
languageService.provideCallHierarchyOutgoingCalls = (filePath, position) => {
|
|
150
159
|
let calls = [];
|
|
160
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
151
161
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
152
162
|
if (serviceScript) {
|
|
153
163
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled);
|
|
@@ -179,7 +189,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
179
189
|
.filter(utils_1.notEmpty);
|
|
180
190
|
return resolved;
|
|
181
191
|
};
|
|
182
|
-
languageService.getQuickInfoAtPosition = (
|
|
192
|
+
languageService.getQuickInfoAtPosition = (filePath, position) => {
|
|
193
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
183
194
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
184
195
|
if (serviceScript) {
|
|
185
196
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isHoverEnabled);
|
|
@@ -200,7 +211,30 @@ function decorateLanguageService(language, languageService) {
|
|
|
200
211
|
return getQuickInfoAtPosition(fileName, position);
|
|
201
212
|
}
|
|
202
213
|
};
|
|
203
|
-
languageService.
|
|
214
|
+
languageService.getSignatureHelpItems = (filePath, position, options) => {
|
|
215
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
216
|
+
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
217
|
+
if (serviceScript) {
|
|
218
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isSignatureHelpEnabled);
|
|
219
|
+
if (generatePosition !== undefined) {
|
|
220
|
+
const result = getSignatureHelpItems(fileName, generatePosition, options);
|
|
221
|
+
if (result) {
|
|
222
|
+
const applicableSpan = (0, transform_1.transformTextSpan)(sourceScript, map, result.applicableSpan, language_core_1.isSignatureHelpEnabled);
|
|
223
|
+
if (applicableSpan) {
|
|
224
|
+
return {
|
|
225
|
+
...result,
|
|
226
|
+
applicableSpan,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
return getSignatureHelpItems(fileName, position, options);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
languageService.getDocumentHighlights = (filePath, position, filesToSearch) => {
|
|
237
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
204
238
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isHighlightEnabled, position => getDocumentHighlights(fileName, position, filesToSearch), function* (result) {
|
|
205
239
|
for (const ref of result) {
|
|
206
240
|
for (const reference of ref.highlightSpans) {
|
|
@@ -229,7 +263,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
229
263
|
});
|
|
230
264
|
return resolved;
|
|
231
265
|
};
|
|
232
|
-
languageService.getApplicableRefactors = (
|
|
266
|
+
languageService.getApplicableRefactors = (filePath, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
|
|
267
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
233
268
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
234
269
|
if (serviceScript) {
|
|
235
270
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos, language_core_1.isCodeActionsEnabled);
|
|
@@ -248,8 +283,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
248
283
|
return getApplicableRefactors(fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions);
|
|
249
284
|
}
|
|
250
285
|
};
|
|
251
|
-
languageService.getEditsForRefactor = (
|
|
286
|
+
languageService.getEditsForRefactor = (filePath, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
|
|
252
287
|
let edits;
|
|
288
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
253
289
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
254
290
|
if (serviceScript) {
|
|
255
291
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, typeof positionOrRange === 'number'
|
|
@@ -275,12 +311,16 @@ function decorateLanguageService(language, languageService) {
|
|
|
275
311
|
return edits;
|
|
276
312
|
}
|
|
277
313
|
};
|
|
278
|
-
languageService.getRenameInfo = (
|
|
314
|
+
languageService.getRenameInfo = (filePath, position, options) => {
|
|
315
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
279
316
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
280
317
|
if (serviceScript) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
318
|
+
let failed;
|
|
319
|
+
for (const [generateOffset, mapping] of (0, transform_1.toGeneratedOffsets)(sourceScript, map, position)) {
|
|
320
|
+
if (!(0, language_core_1.isRenameEnabled)(mapping.data)) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
const info = getRenameInfo(fileName, generateOffset, options);
|
|
284
324
|
if (info.canRename) {
|
|
285
325
|
const span = (0, transform_1.transformTextSpan)(sourceScript, map, info.triggerSpan, language_core_1.isRenameEnabled);
|
|
286
326
|
if (span) {
|
|
@@ -289,9 +329,12 @@ function decorateLanguageService(language, languageService) {
|
|
|
289
329
|
}
|
|
290
330
|
}
|
|
291
331
|
else {
|
|
292
|
-
|
|
332
|
+
failed = info;
|
|
293
333
|
}
|
|
294
334
|
}
|
|
335
|
+
if (failed) {
|
|
336
|
+
return failed;
|
|
337
|
+
}
|
|
295
338
|
return {
|
|
296
339
|
canRename: false,
|
|
297
340
|
localizedErrorMessage: 'Failed to get rename locations',
|
|
@@ -301,8 +344,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
301
344
|
return getRenameInfo(fileName, position, options);
|
|
302
345
|
}
|
|
303
346
|
};
|
|
304
|
-
languageService.getCodeFixesAtPosition = (
|
|
347
|
+
languageService.getCodeFixesAtPosition = (filePath, start, end, errorCodes, formatOptions, preferences) => {
|
|
305
348
|
let fixes = [];
|
|
349
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
306
350
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
307
351
|
if (serviceScript) {
|
|
308
352
|
const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isCodeActionsEnabled);
|
|
@@ -320,7 +364,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
320
364
|
});
|
|
321
365
|
return fixes;
|
|
322
366
|
};
|
|
323
|
-
languageService.getEncodedSemanticClassifications = (
|
|
367
|
+
languageService.getEncodedSemanticClassifications = (filePath, span, format) => {
|
|
368
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
324
369
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
325
370
|
if (serviceScript) {
|
|
326
371
|
let start;
|
|
@@ -354,22 +399,26 @@ function decorateLanguageService(language, languageService) {
|
|
|
354
399
|
return getEncodedSemanticClassifications(fileName, span, format);
|
|
355
400
|
}
|
|
356
401
|
};
|
|
357
|
-
languageService.getSyntacticDiagnostics =
|
|
402
|
+
languageService.getSyntacticDiagnostics = filePath => {
|
|
403
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
358
404
|
return getSyntacticDiagnostics(fileName)
|
|
359
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
405
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, false))
|
|
360
406
|
.filter(utils_1.notEmpty);
|
|
361
407
|
};
|
|
362
|
-
languageService.getSemanticDiagnostics =
|
|
408
|
+
languageService.getSemanticDiagnostics = filePath => {
|
|
409
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
363
410
|
return getSemanticDiagnostics(fileName)
|
|
364
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
411
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, false))
|
|
365
412
|
.filter(utils_1.notEmpty);
|
|
366
413
|
};
|
|
367
|
-
languageService.getSuggestionDiagnostics =
|
|
414
|
+
languageService.getSuggestionDiagnostics = filePath => {
|
|
415
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
368
416
|
return getSuggestionDiagnostics(fileName)
|
|
369
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
417
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, false))
|
|
370
418
|
.filter(utils_1.notEmpty);
|
|
371
419
|
};
|
|
372
|
-
languageService.getDefinitionAndBoundSpan = (
|
|
420
|
+
languageService.getDefinitionAndBoundSpan = (filePath, position) => {
|
|
421
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
373
422
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAndBoundSpan(fileName, position), function* (result) {
|
|
374
423
|
for (const ref of result.definitions ?? []) {
|
|
375
424
|
yield [ref.fileName, ref.textSpan.start];
|
|
@@ -392,7 +441,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
392
441
|
definitions: (0, dedupe_1.dedupeDocumentSpans)(definitions),
|
|
393
442
|
};
|
|
394
443
|
};
|
|
395
|
-
languageService.findReferences = (
|
|
444
|
+
languageService.findReferences = (filePath, position) => {
|
|
445
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
396
446
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => findReferences(fileName, position), function* (result) {
|
|
397
447
|
for (const ref of result) {
|
|
398
448
|
for (const reference of ref.references) {
|
|
@@ -403,20 +453,18 @@ function decorateLanguageService(language, languageService) {
|
|
|
403
453
|
const resolved = unresolved
|
|
404
454
|
.flat()
|
|
405
455
|
.map(symbol => {
|
|
406
|
-
const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
})
|
|
416
|
-
.filter(utils_1.notEmpty);
|
|
417
|
-
return (0, dedupe_1.dedupeReferencedSymbols)(resolved);
|
|
456
|
+
const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled, true);
|
|
457
|
+
return {
|
|
458
|
+
definition,
|
|
459
|
+
references: symbol.references
|
|
460
|
+
.map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled))
|
|
461
|
+
.filter(utils_1.notEmpty),
|
|
462
|
+
};
|
|
463
|
+
});
|
|
464
|
+
return resolved;
|
|
418
465
|
};
|
|
419
|
-
languageService.getDefinitionAtPosition = (
|
|
466
|
+
languageService.getDefinitionAtPosition = (filePath, position) => {
|
|
467
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
420
468
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAtPosition(fileName, position), function* (result) {
|
|
421
469
|
for (const ref of result) {
|
|
422
470
|
yield [ref.fileName, ref.textSpan.start];
|
|
@@ -428,7 +476,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
428
476
|
.filter(utils_1.notEmpty);
|
|
429
477
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
430
478
|
};
|
|
431
|
-
languageService.getTypeDefinitionAtPosition = (
|
|
479
|
+
languageService.getTypeDefinitionAtPosition = (filePath, position) => {
|
|
480
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
432
481
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, position => getTypeDefinitionAtPosition(fileName, position), function* (result) {
|
|
433
482
|
for (const ref of result) {
|
|
434
483
|
yield [ref.fileName, ref.textSpan.start];
|
|
@@ -440,7 +489,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
440
489
|
.filter(utils_1.notEmpty);
|
|
441
490
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
442
491
|
};
|
|
443
|
-
languageService.getImplementationAtPosition = (
|
|
492
|
+
languageService.getImplementationAtPosition = (filePath, position) => {
|
|
493
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
444
494
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, position => getImplementationAtPosition(fileName, position), function* (result) {
|
|
445
495
|
for (const ref of result) {
|
|
446
496
|
yield [ref.fileName, ref.textSpan.start];
|
|
@@ -452,7 +502,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
452
502
|
.filter(utils_1.notEmpty);
|
|
453
503
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
454
504
|
};
|
|
455
|
-
languageService.findRenameLocations = (
|
|
505
|
+
languageService.findRenameLocations = (filePath, position, findInStrings, findInComments, preferences) => {
|
|
506
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
456
507
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, position => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) {
|
|
457
508
|
for (const ref of result) {
|
|
458
509
|
yield [ref.fileName, ref.textSpan.start];
|
|
@@ -464,7 +515,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
464
515
|
.filter(utils_1.notEmpty);
|
|
465
516
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
466
517
|
};
|
|
467
|
-
languageService.getReferencesAtPosition = (
|
|
518
|
+
languageService.getReferencesAtPosition = (filePath, position) => {
|
|
519
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
468
520
|
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => getReferencesAtPosition(fileName, position), function* (result) {
|
|
469
521
|
for (const ref of result) {
|
|
470
522
|
yield [ref.fileName, ref.textSpan.start];
|
|
@@ -476,47 +528,41 @@ function decorateLanguageService(language, languageService) {
|
|
|
476
528
|
.filter(utils_1.notEmpty);
|
|
477
529
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
478
530
|
};
|
|
479
|
-
languageService.getCompletionsAtPosition = (
|
|
531
|
+
languageService.getCompletionsAtPosition = (filePath, position, options, formattingSettings) => {
|
|
532
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
480
533
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
481
534
|
if (serviceScript) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
if (!(0, language_core_1.isCompletionEnabled)(data)) {
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
isAdditional = typeof data.completion === 'object' && data.completion.isAdditional;
|
|
490
|
-
if (!isAdditional && mainResult) {
|
|
491
|
-
return false;
|
|
535
|
+
const results = [];
|
|
536
|
+
for (const [generatedOffset, mapping] of (0, transform_1.toGeneratedOffsets)(sourceScript, map, position)) {
|
|
537
|
+
if (!(0, language_core_1.isCompletionEnabled)(mapping.data)) {
|
|
538
|
+
continue;
|
|
492
539
|
}
|
|
493
|
-
return true;
|
|
494
|
-
});
|
|
495
|
-
if (generatedOffset !== undefined) {
|
|
496
540
|
const result = getCompletionsAtPosition(fileName, generatedOffset, options, formattingSettings);
|
|
497
|
-
if (result) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
result.
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
541
|
+
if (!result || !result.entries.length) {
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
if (typeof mapping.data.completion === 'object' && mapping.data.completion.onlyImport) {
|
|
545
|
+
result.entries = result.entries.filter(entry => !!entry.sourceDisplay);
|
|
546
|
+
}
|
|
547
|
+
for (const entry of result.entries) {
|
|
548
|
+
entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(sourceScript, map, entry.replacementSpan, language_core_1.isCompletionEnabled);
|
|
549
|
+
}
|
|
550
|
+
result.optionalReplacementSpan = result.optionalReplacementSpan
|
|
551
|
+
&& (0, transform_1.transformTextSpan)(sourceScript, map, result.optionalReplacementSpan, language_core_1.isCompletionEnabled);
|
|
552
|
+
const isAdditional = typeof mapping.data.completion === 'object' && mapping.data.completion.isAdditional;
|
|
553
|
+
if (isAdditional) {
|
|
554
|
+
results.push(result);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
results.splice(0, 0, result);
|
|
508
558
|
}
|
|
509
559
|
}
|
|
510
|
-
if (
|
|
511
|
-
mainResult = additionalResults.shift();
|
|
512
|
-
}
|
|
513
|
-
if (mainResult) {
|
|
560
|
+
if (results.length) {
|
|
514
561
|
return {
|
|
515
|
-
...
|
|
516
|
-
entries:
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
],
|
|
562
|
+
...results[0],
|
|
563
|
+
entries: results
|
|
564
|
+
.map(additionalResult => additionalResult.entries)
|
|
565
|
+
.flat(),
|
|
520
566
|
};
|
|
521
567
|
}
|
|
522
568
|
}
|
|
@@ -524,8 +570,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
524
570
|
return getCompletionsAtPosition(fileName, position, options, formattingSettings);
|
|
525
571
|
}
|
|
526
572
|
};
|
|
527
|
-
languageService.getCompletionEntryDetails = (
|
|
573
|
+
languageService.getCompletionEntryDetails = (filePath, position, entryName, formatOptions, source, preferences, data) => {
|
|
528
574
|
let details;
|
|
575
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
529
576
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
530
577
|
if (serviceScript) {
|
|
531
578
|
const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCompletionEnabled);
|
|
@@ -543,7 +590,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
543
590
|
}
|
|
544
591
|
return details;
|
|
545
592
|
};
|
|
546
|
-
languageService.provideInlayHints = (
|
|
593
|
+
languageService.provideInlayHints = (filePath, span, preferences) => {
|
|
594
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
547
595
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
548
596
|
if (serviceScript) {
|
|
549
597
|
let start;
|
|
@@ -579,7 +627,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
579
627
|
return provideInlayHints(fileName, span, preferences);
|
|
580
628
|
}
|
|
581
629
|
};
|
|
582
|
-
languageService.getFileReferences =
|
|
630
|
+
languageService.getFileReferences = filePath => {
|
|
631
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
583
632
|
const unresolved = getFileReferences(fileName);
|
|
584
633
|
const resolved = unresolved
|
|
585
634
|
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
|
|
@@ -587,7 +636,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
587
636
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
588
637
|
};
|
|
589
638
|
function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
|
|
590
|
-
|
|
639
|
+
const results = [];
|
|
591
640
|
const processedFilePositions = new Set();
|
|
592
641
|
const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
|
|
593
642
|
if (serviceScript) {
|
|
@@ -610,7 +659,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
610
659
|
if (!result) {
|
|
611
660
|
return;
|
|
612
661
|
}
|
|
613
|
-
results
|
|
662
|
+
results.push(result);
|
|
614
663
|
for (const ref of getLinkedCodes(result)) {
|
|
615
664
|
processedFilePositions.add(ref[0] + ':' + ref[1]);
|
|
616
665
|
const [virtualFile, sourceScript] = (0, utils_1.getServiceScript)(language, ref[0]);
|
|
@@ -7,6 +7,7 @@ function decorateLanguageServiceHost(ts, language, languageServiceHost) {
|
|
|
7
7
|
.map(plugin => plugin.typescript?.extraFileExtensions.map(ext => '.' + ext.extension) ?? [])
|
|
8
8
|
.flat();
|
|
9
9
|
const scripts = new Map();
|
|
10
|
+
const crashFileNames = new Set();
|
|
10
11
|
const readDirectory = languageServiceHost.readDirectory?.bind(languageServiceHost);
|
|
11
12
|
const resolveModuleNameLiterals = languageServiceHost.resolveModuleNameLiterals?.bind(languageServiceHost);
|
|
12
13
|
const resolveModuleNames = languageServiceHost.resolveModuleNames?.bind(languageServiceHost);
|
|
@@ -69,8 +70,19 @@ function decorateLanguageServiceHost(ts, language, languageServiceHost) {
|
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
function updateVirtualScript(fileName) {
|
|
72
|
-
|
|
73
|
+
if (crashFileNames.has(fileName)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let version;
|
|
77
|
+
try {
|
|
78
|
+
version = languageServiceHost.getScriptVersion(fileName);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// fix https://github.com/vuejs/language-tools/issues/4278
|
|
82
|
+
crashFileNames.add(fileName);
|
|
83
|
+
}
|
|
73
84
|
if (version === undefined) {
|
|
85
|
+
// somehow getScriptVersion returns undefined
|
|
74
86
|
return;
|
|
75
87
|
}
|
|
76
88
|
let script = scripts.get(fileName);
|
|
@@ -18,29 +18,29 @@ function decorateProgram(language, program) {
|
|
|
18
18
|
return {
|
|
19
19
|
...result,
|
|
20
20
|
diagnostics: result.diagnostics
|
|
21
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
21
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
22
22
|
.filter(utils_1.notEmpty),
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
program.getSyntacticDiagnostics = (sourceFile, cancellationToken) => {
|
|
26
26
|
return getSyntacticDiagnostics(sourceFile, cancellationToken)
|
|
27
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
27
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
28
28
|
.filter(utils_1.notEmpty);
|
|
29
29
|
};
|
|
30
30
|
program.getSemanticDiagnostics = (sourceFile, cancellationToken) => {
|
|
31
31
|
return getSemanticDiagnostics(sourceFile, cancellationToken)
|
|
32
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
32
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
33
33
|
.filter(utils_1.notEmpty);
|
|
34
34
|
};
|
|
35
35
|
program.getGlobalDiagnostics = cancellationToken => {
|
|
36
36
|
return getGlobalDiagnostics(cancellationToken)
|
|
37
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
37
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
38
38
|
.filter(utils_1.notEmpty);
|
|
39
39
|
};
|
|
40
40
|
// @ts-ignore
|
|
41
41
|
program.getBindAndCheckDiagnostics = (sourceFile, cancellationToken) => {
|
|
42
42
|
return getBindAndCheckDiagnostics(sourceFile, cancellationToken)
|
|
43
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d))
|
|
43
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
44
44
|
.filter(utils_1.notEmpty);
|
|
45
45
|
};
|
|
46
46
|
// fix https://github.com/vuejs/language-tools/issues/4099 with `incremental`
|
package/lib/node/dedupe.d.ts
CHANGED
package/lib/node/dedupe.js
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dedupeDocumentSpans =
|
|
4
|
-
function dedupeReferencedSymbols(items) {
|
|
5
|
-
return dedupe(items, item => [
|
|
6
|
-
item.definition.fileName,
|
|
7
|
-
item.definition.textSpan.start,
|
|
8
|
-
item.definition.textSpan.length,
|
|
9
|
-
].join(':'));
|
|
10
|
-
}
|
|
11
|
-
exports.dedupeReferencedSymbols = dedupeReferencedSymbols;
|
|
3
|
+
exports.dedupeDocumentSpans = void 0;
|
|
12
4
|
function dedupeDocumentSpans(items) {
|
|
13
5
|
return dedupe(items, item => [
|
|
14
6
|
item.fileName,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { LanguagePlugin } from '@volar/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
export declare function proxyCreateProgram(ts: typeof import('typescript'), original: typeof ts['createProgram'], getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[]
|
|
3
|
+
export declare function proxyCreateProgram(ts: typeof import('typescript'), original: typeof ts['createProgram'], getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[]): typeof import("typescript").createProgram;
|
|
@@ -4,6 +4,7 @@ exports.proxyCreateProgram = void 0;
|
|
|
4
4
|
const language_core_1 = require("@volar/language-core");
|
|
5
5
|
const resolveModuleName_1 = require("../resolveModuleName");
|
|
6
6
|
const decorateProgram_1 = require("./decorateProgram");
|
|
7
|
+
const common_1 = require("../common");
|
|
7
8
|
const arrayEqual = (a, b) => {
|
|
8
9
|
if (a.length !== b.length) {
|
|
9
10
|
return false;
|
|
@@ -28,7 +29,7 @@ const objectEqual = (a, b) => {
|
|
|
28
29
|
}
|
|
29
30
|
return true;
|
|
30
31
|
};
|
|
31
|
-
function proxyCreateProgram(ts, original, getLanguagePlugins
|
|
32
|
+
function proxyCreateProgram(ts, original, getLanguagePlugins) {
|
|
32
33
|
const sourceFileSnapshots = new Map();
|
|
33
34
|
const parsedSourceFiles = new WeakMap();
|
|
34
35
|
let lastOptions;
|
|
@@ -47,7 +48,10 @@ function proxyCreateProgram(ts, original, getLanguagePlugins, getLanguageId) {
|
|
|
47
48
|
moduleResolutionCache = ts.createModuleResolutionCache(options.host.getCurrentDirectory(), options.host.getCanonicalFileName, options.options);
|
|
48
49
|
lastOptions = options;
|
|
49
50
|
languagePlugins = getLanguagePlugins(ts, options);
|
|
50
|
-
language = (0, language_core_1.createLanguage)(
|
|
51
|
+
language = (0, language_core_1.createLanguage)([
|
|
52
|
+
...languagePlugins,
|
|
53
|
+
common_1.fileLanguageIdProviderPlugin,
|
|
54
|
+
], ts.sys.useCaseSensitiveFileNames, fileName => {
|
|
51
55
|
if (!sourceFileSnapshots.has(fileName)) {
|
|
52
56
|
const sourceFileText = originalHost.readFile(fileName);
|
|
53
57
|
if (sourceFileText !== undefined) {
|
|
@@ -69,7 +73,7 @@ function proxyCreateProgram(ts, original, getLanguagePlugins, getLanguageId) {
|
|
|
69
73
|
}
|
|
70
74
|
const snapshot = sourceFileSnapshots.get(fileName)?.[1];
|
|
71
75
|
if (snapshot) {
|
|
72
|
-
language.scripts.set(fileName,
|
|
76
|
+
language.scripts.set(fileName, snapshot);
|
|
73
77
|
}
|
|
74
78
|
else {
|
|
75
79
|
language.scripts.delete(fileName);
|
package/lib/node/transform.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Language, CodeInformation, SourceMap, SourceScript } from '@volar/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
3
|
export declare function transformCallHierarchyItem(language: Language, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem;
|
|
4
|
-
export declare function transformDiagnostic<T extends ts.Diagnostic>(language: Language, diagnostic: T): T | undefined;
|
|
4
|
+
export declare function transformDiagnostic<T extends ts.Diagnostic>(language: Language, diagnostic: T, isTsc: boolean): T | undefined;
|
|
5
5
|
export declare function fillSourceFileText(language: Language, sourceFile: ts.SourceFile): void;
|
|
6
6
|
export declare function transformFileTextChanges(language: Language, changes: ts.FileTextChanges, filter: (data: CodeInformation) => boolean): ts.FileTextChanges | undefined;
|
|
7
7
|
export declare function transformDocumentSpan<T extends ts.DocumentSpan>(language: Language, documentSpan: T, filter: (data: CodeInformation) => boolean, shouldFallback?: boolean): T | undefined;
|
|
@@ -13,3 +13,4 @@ export declare function transformTextChange(sourceScript: SourceScript, map: Sou
|
|
|
13
13
|
export declare function transformTextSpan(sourceScript: SourceScript, map: SourceMap<CodeInformation>, textSpan: ts.TextSpan, filter: (data: CodeInformation) => boolean): ts.TextSpan | undefined;
|
|
14
14
|
export declare function toSourceOffset(sourceScript: SourceScript, map: SourceMap, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
|
|
15
15
|
export declare function toGeneratedOffset(sourceScript: SourceScript, map: SourceMap, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
|
|
16
|
+
export declare function toGeneratedOffsets(sourceScript: SourceScript, map: SourceMap<CodeInformation>, position: number): Generator<readonly [number, import("@volar/language-core").Mapping<CodeInformation>], void, unknown>;
|
package/lib/node/transform.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toGeneratedOffset = exports.toSourceOffset = exports.transformTextSpan = exports.transformTextChange = exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = exports.fillSourceFileText = exports.transformDiagnostic = exports.transformCallHierarchyItem = void 0;
|
|
3
|
+
exports.toGeneratedOffsets = exports.toGeneratedOffset = exports.toSourceOffset = exports.transformTextSpan = exports.transformTextChange = exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = exports.fillSourceFileText = exports.transformDiagnostic = exports.transformCallHierarchyItem = void 0;
|
|
4
4
|
const language_core_1 = require("@volar/language-core");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
const transformedDiagnostics = new WeakMap();
|
|
@@ -15,13 +15,13 @@ function transformCallHierarchyItem(language, item, filter) {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
exports.transformCallHierarchyItem = transformCallHierarchyItem;
|
|
18
|
-
function transformDiagnostic(language, diagnostic) {
|
|
18
|
+
function transformDiagnostic(language, diagnostic, isTsc) {
|
|
19
19
|
if (!transformedDiagnostics.has(diagnostic)) {
|
|
20
20
|
transformedDiagnostics.set(diagnostic, undefined);
|
|
21
21
|
const { relatedInformation } = diagnostic;
|
|
22
22
|
if (relatedInformation) {
|
|
23
23
|
diagnostic.relatedInformation = relatedInformation
|
|
24
|
-
.map(d => transformDiagnostic(language, d))
|
|
24
|
+
.map(d => transformDiagnostic(language, d, isTsc))
|
|
25
25
|
.filter(utils_1.notEmpty);
|
|
26
26
|
}
|
|
27
27
|
if (diagnostic.file !== undefined
|
|
@@ -31,7 +31,9 @@ function transformDiagnostic(language, diagnostic) {
|
|
|
31
31
|
if (serviceScript) {
|
|
32
32
|
const sourceSpan = transformTextSpan(sourceScript, map, { start: diagnostic.start, length: diagnostic.length }, language_core_1.shouldReportDiagnostics);
|
|
33
33
|
if (sourceSpan) {
|
|
34
|
-
|
|
34
|
+
if (isTsc) {
|
|
35
|
+
fillSourceFileText(language, diagnostic.file);
|
|
36
|
+
}
|
|
35
37
|
transformedDiagnostics.set(diagnostic, {
|
|
36
38
|
...diagnostic,
|
|
37
39
|
start: sourceSpan.start,
|
|
@@ -61,7 +63,6 @@ function fillSourceFileText(language, sourceFile) {
|
|
|
61
63
|
sourceFile.text = sourceScript.snapshot.getText(0, sourceScript.snapshot.getLength())
|
|
62
64
|
+ sourceFile.text.substring(sourceScript.snapshot.getLength());
|
|
63
65
|
}
|
|
64
|
-
return;
|
|
65
66
|
}
|
|
66
67
|
exports.fillSourceFileText = fillSourceFileText;
|
|
67
68
|
function transformFileTextChanges(language, changes, filter) {
|
|
@@ -88,13 +89,10 @@ exports.transformFileTextChanges = transformFileTextChanges;
|
|
|
88
89
|
function transformDocumentSpan(language, documentSpan, filter, shouldFallback) {
|
|
89
90
|
let textSpan = transformSpan(language, documentSpan.fileName, documentSpan.textSpan, filter);
|
|
90
91
|
if (!textSpan && shouldFallback) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
textSpan
|
|
94
|
-
|
|
95
|
-
textSpan: { start: 0, length: 0 },
|
|
96
|
-
};
|
|
97
|
-
}
|
|
92
|
+
textSpan = {
|
|
93
|
+
fileName: documentSpan.fileName,
|
|
94
|
+
textSpan: { start: 0, length: 0 },
|
|
95
|
+
};
|
|
98
96
|
}
|
|
99
97
|
if (!textSpan) {
|
|
100
98
|
return;
|
|
@@ -174,4 +172,10 @@ function toGeneratedOffset(sourceScript, map, position, filter) {
|
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
exports.toGeneratedOffset = toGeneratedOffset;
|
|
175
|
+
function* toGeneratedOffsets(sourceScript, map, position) {
|
|
176
|
+
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
177
|
+
yield [generateOffset + sourceScript.snapshot.getLength(), mapping];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.toGeneratedOffsets = toGeneratedOffsets;
|
|
177
181
|
//# sourceMappingURL=transform.js.map
|
|
@@ -5,10 +5,14 @@ const language_core_1 = require("@volar/language-core");
|
|
|
5
5
|
const language_core_2 = require("@volar/language-core");
|
|
6
6
|
const path = require("path-browserify");
|
|
7
7
|
const resolveModuleName_1 = require("../resolveModuleName");
|
|
8
|
+
const common_1 = require("../common");
|
|
8
9
|
const scriptVersions = new Map();
|
|
9
10
|
const fsFileSnapshots = new Map();
|
|
10
11
|
function createTypeScriptLanguage(ts, languagePlugins, projectHost) {
|
|
11
|
-
const language = (0, language_core_1.createLanguage)(
|
|
12
|
+
const language = (0, language_core_1.createLanguage)([
|
|
13
|
+
...languagePlugins,
|
|
14
|
+
common_1.fileLanguageIdProviderPlugin,
|
|
15
|
+
], projectHost.useCaseSensitiveFileNames, scriptId => {
|
|
12
16
|
const fileName = projectHost.scriptIdToFileName(scriptId);
|
|
13
17
|
// opened files
|
|
14
18
|
let snapshot = projectHost.getScriptSnapshot(fileName);
|
|
@@ -29,7 +33,7 @@ function createTypeScriptLanguage(ts, languagePlugins, projectHost) {
|
|
|
29
33
|
snapshot = fsFileSnapshots.get(fileName)?.[1];
|
|
30
34
|
}
|
|
31
35
|
if (snapshot) {
|
|
32
|
-
language.scripts.set(scriptId,
|
|
36
|
+
language.scripts.set(scriptId, snapshot);
|
|
33
37
|
}
|
|
34
38
|
else {
|
|
35
39
|
language.scripts.delete(scriptId);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
2
|
import { LanguagePlugin } from '@volar/language-core';
|
|
3
|
-
export declare function createAsyncLanguageServicePlugin(extensions: string[], scriptKind: ts.ScriptKind, loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => Promise<LanguagePlugin[]
|
|
3
|
+
export declare function createAsyncLanguageServicePlugin(extensions: string[], scriptKind: ts.ScriptKind, loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => Promise<LanguagePlugin[]>): ts.server.PluginModuleFactory;
|
|
@@ -5,10 +5,11 @@ const decorateLanguageService_1 = require("../node/decorateLanguageService");
|
|
|
5
5
|
const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
|
|
6
6
|
const language_core_1 = require("@volar/language-core");
|
|
7
7
|
const createLanguageServicePlugin_1 = require("./createLanguageServicePlugin");
|
|
8
|
+
const common_1 = require("../common");
|
|
8
9
|
const externalFiles = new WeakMap();
|
|
9
10
|
const decoratedLanguageServices = new WeakSet();
|
|
10
11
|
const decoratedLanguageServiceHosts = new WeakSet();
|
|
11
|
-
function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePlugins
|
|
12
|
+
function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePlugins) {
|
|
12
13
|
return modules => {
|
|
13
14
|
const { typescript: ts } = modules;
|
|
14
15
|
const pluginModule = {
|
|
@@ -52,10 +53,19 @@ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePl
|
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
loadLanguagePlugins(ts, info).then(languagePlugins => {
|
|
55
|
-
const
|
|
56
|
+
const syncedScriptVersions = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
|
|
57
|
+
const language = (0, language_core_1.createLanguage)([
|
|
58
|
+
...languagePlugins,
|
|
59
|
+
common_1.fileLanguageIdProviderPlugin,
|
|
60
|
+
], ts.sys.useCaseSensitiveFileNames, fileName => {
|
|
61
|
+
const version = getScriptVersion(fileName);
|
|
62
|
+
if (syncedScriptVersions.get(fileName) === version) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
syncedScriptVersions.set(fileName, version);
|
|
56
66
|
const snapshot = getScriptSnapshot(fileName);
|
|
57
67
|
if (snapshot) {
|
|
58
|
-
language.scripts.set(fileName,
|
|
68
|
+
language.scripts.set(fileName, snapshot);
|
|
59
69
|
}
|
|
60
70
|
else {
|
|
61
71
|
language.scripts.delete(fileName);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
2
|
import { LanguagePlugin } from '@volar/language-core';
|
|
3
|
-
export declare function createLanguageServicePlugin(loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => LanguagePlugin[]
|
|
3
|
+
export declare function createLanguageServicePlugin(loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => LanguagePlugin[]): ts.server.PluginModuleFactory;
|
|
4
4
|
export declare function arrayItemsEqual(a: string[], b: string[]): boolean;
|
|
@@ -4,11 +4,12 @@ exports.arrayItemsEqual = exports.createLanguageServicePlugin = void 0;
|
|
|
4
4
|
const decorateLanguageService_1 = require("../node/decorateLanguageService");
|
|
5
5
|
const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
|
|
6
6
|
const language_core_1 = require("@volar/language-core");
|
|
7
|
+
const common_1 = require("../common");
|
|
7
8
|
const externalFiles = new WeakMap();
|
|
8
9
|
const projectExternalFileExtensions = new WeakMap();
|
|
9
10
|
const decoratedLanguageServices = new WeakSet();
|
|
10
11
|
const decoratedLanguageServiceHosts = new WeakSet();
|
|
11
|
-
function createLanguageServicePlugin(loadLanguagePlugins
|
|
12
|
+
function createLanguageServicePlugin(loadLanguagePlugins) {
|
|
12
13
|
return modules => {
|
|
13
14
|
const { typescript: ts } = modules;
|
|
14
15
|
const pluginModule = {
|
|
@@ -23,10 +24,20 @@ function createLanguageServicePlugin(loadLanguagePlugins, getLanguageId) {
|
|
|
23
24
|
.flat();
|
|
24
25
|
projectExternalFileExtensions.set(info.project, extensions);
|
|
25
26
|
const getScriptSnapshot = info.languageServiceHost.getScriptSnapshot.bind(info.languageServiceHost);
|
|
26
|
-
const
|
|
27
|
+
const getScriptVersion = info.languageServiceHost.getScriptVersion.bind(info.languageServiceHost);
|
|
28
|
+
const syncedScriptVersions = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
|
|
29
|
+
const language = (0, language_core_1.createLanguage)([
|
|
30
|
+
...languagePlugins,
|
|
31
|
+
common_1.fileLanguageIdProviderPlugin,
|
|
32
|
+
], ts.sys.useCaseSensitiveFileNames, fileName => {
|
|
33
|
+
const version = getScriptVersion(fileName);
|
|
34
|
+
if (syncedScriptVersions.get(fileName) === version) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
syncedScriptVersions.set(fileName, version);
|
|
27
38
|
const snapshot = getScriptSnapshot(fileName);
|
|
28
39
|
if (snapshot) {
|
|
29
|
-
language.scripts.set(fileName,
|
|
40
|
+
language.scripts.set(fileName, snapshot);
|
|
30
41
|
}
|
|
31
42
|
else {
|
|
32
43
|
language.scripts.delete(fileName);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
2
|
import type { LanguagePlugin } from '@volar/language-core';
|
|
3
3
|
export declare let getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[];
|
|
4
|
-
export declare
|
|
5
|
-
export declare function runTsc(tscPath: string, extensions: string[], _getLanguagePlugins: typeof getLanguagePlugins, _getLanguageId: typeof getLanguageId): void;
|
|
4
|
+
export declare function runTsc(tscPath: string, extensions: string[], _getLanguagePlugins: typeof getLanguagePlugins): void;
|
package/lib/quickstart/runTsc.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runTsc = exports.
|
|
3
|
+
exports.runTsc = exports.getLanguagePlugins = void 0;
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
let getLanguagePlugins = () => [];
|
|
6
6
|
exports.getLanguagePlugins = getLanguagePlugins;
|
|
7
|
-
|
|
8
|
-
exports.getLanguageId = getLanguageId;
|
|
9
|
-
function runTsc(tscPath, extensions, _getLanguagePlugins, _getLanguageId) {
|
|
7
|
+
function runTsc(tscPath, extensions, _getLanguagePlugins) {
|
|
10
8
|
exports.getLanguagePlugins = _getLanguagePlugins;
|
|
11
|
-
exports.getLanguageId = _getLanguageId;
|
|
12
9
|
const proxyApiPath = require.resolve('../node/proxyCreateProgram');
|
|
13
10
|
const readFileSync = fs.readFileSync;
|
|
14
11
|
fs.readFileSync = (...args) => {
|
|
@@ -25,7 +22,6 @@ function runTsc(tscPath, extensions, _getLanguagePlugins, _getLanguageId) {
|
|
|
25
22
|
`new Proxy({}, { get(_target, p, _receiver) { return eval(p); } } )`,
|
|
26
23
|
`_createProgram`,
|
|
27
24
|
`require(${JSON.stringify(__filename)}).getLanguagePlugins`,
|
|
28
|
-
`require(${JSON.stringify(__filename)}).getLanguageId`,
|
|
29
25
|
].join(', ')
|
|
30
26
|
+ `);\n`
|
|
31
27
|
+ s.replace('createProgram', '_createProgram'));
|
package/lib/resolveModuleName.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createResolveModuleName = void 0;
|
|
4
4
|
function createResolveModuleName(ts, host, languagePlugins, getSourceScript) {
|
|
5
|
-
const
|
|
5
|
+
const toSourceFileInfo = new Map();
|
|
6
6
|
const moduleResolutionHost = {
|
|
7
7
|
readFile: host.readFile.bind(host),
|
|
8
8
|
directoryExists: host.directoryExists?.bind(host),
|
|
@@ -19,10 +19,28 @@ function createResolveModuleName(ts, host, languagePlugins, getSourceScript) {
|
|
|
19
19
|
}
|
|
20
20
|
for (const { extension } of typescript.extraFileExtensions) {
|
|
21
21
|
if (fileName.endsWith(`.d.${extension}.ts`)) {
|
|
22
|
-
const
|
|
23
|
-
if (fileExists(
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const sourceFileName = fileName.slice(0, -`.d.${extension}.ts`.length) + `.${extension}`;
|
|
23
|
+
if (fileExists(sourceFileName)) {
|
|
24
|
+
const sourceScript = getSourceScript(sourceFileName);
|
|
25
|
+
if (sourceScript?.generated) {
|
|
26
|
+
const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
|
|
27
|
+
if (serviceScript) {
|
|
28
|
+
const dtsPath = sourceFileName + '.d.ts';
|
|
29
|
+
if ((serviceScript.extension === '.js' || serviceScript.extension === '.jsx') && fileExists(dtsPath)) {
|
|
30
|
+
toSourceFileInfo.set(fileName, {
|
|
31
|
+
sourceFileName: dtsPath,
|
|
32
|
+
extension: '.ts',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
toSourceFileInfo.set(fileName, {
|
|
37
|
+
sourceFileName,
|
|
38
|
+
extension: serviceScript.extension,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
26
44
|
}
|
|
27
45
|
}
|
|
28
46
|
}
|
|
@@ -32,17 +50,14 @@ function createResolveModuleName(ts, host, languagePlugins, getSourceScript) {
|
|
|
32
50
|
};
|
|
33
51
|
return (moduleName, containingFile, compilerOptions, cache, redirectedReference, resolutionMode) => {
|
|
34
52
|
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost, cache, redirectedReference, resolutionMode);
|
|
35
|
-
if (result.resolvedModule
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (serviceScript) {
|
|
41
|
-
result.resolvedModule.extension = serviceScript.extension;
|
|
42
|
-
}
|
|
53
|
+
if (result.resolvedModule) {
|
|
54
|
+
const sourceFileInfo = toSourceFileInfo.get(result.resolvedModule.resolvedFileName);
|
|
55
|
+
if (sourceFileInfo) {
|
|
56
|
+
result.resolvedModule.resolvedFileName = sourceFileInfo.sourceFileName;
|
|
57
|
+
result.resolvedModule.extension = sourceFileInfo.extension;
|
|
43
58
|
}
|
|
44
59
|
}
|
|
45
|
-
|
|
60
|
+
toSourceFileInfo.clear();
|
|
46
61
|
return result;
|
|
47
62
|
};
|
|
48
63
|
// fix https://github.com/vuejs/language-tools/issues/3332
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volar/typescript",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
"directory": "packages/typescript"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@volar/language-core": "2.2.
|
|
15
|
+
"@volar/language-core": "2.2.1",
|
|
16
16
|
"path-browserify": "^1.0.1"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/node": "latest",
|
|
20
20
|
"@types/path-browserify": "latest",
|
|
21
|
-
"@volar/language-service": "2.2.
|
|
21
|
+
"@volar/language-service": "2.2.1"
|
|
22
22
|
},
|
|
23
|
-
"gitHead": "
|
|
23
|
+
"gitHead": "629f686bda694077b236a0bcd0304437bb2eabf5"
|
|
24
24
|
}
|
package/lib/documentRegistry.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDocumentRegistry = void 0;
|
|
4
|
-
const documentRegistries = [];
|
|
5
|
-
function getDocumentRegistry(ts, useCaseSensitiveFileNames, currentDirectory) {
|
|
6
|
-
let documentRegistry = documentRegistries.find(item => item[0] === useCaseSensitiveFileNames && item[1] === currentDirectory)?.[2];
|
|
7
|
-
if (!documentRegistry) {
|
|
8
|
-
documentRegistry = ts.createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory);
|
|
9
|
-
documentRegistries.push([useCaseSensitiveFileNames, currentDirectory, documentRegistry]);
|
|
10
|
-
}
|
|
11
|
-
return documentRegistry;
|
|
12
|
-
}
|
|
13
|
-
exports.getDocumentRegistry = getDocumentRegistry;
|
|
14
|
-
//# sourceMappingURL=documentRegistry.js.map
|