@volar/typescript 2.3.0-alpha.9 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/node/decorateLanguageService.js +102 -99
- package/lib/node/decorateProgram.js +35 -20
- package/lib/node/transform.d.ts +9 -9
- package/lib/node/transform.js +31 -33
- package/lib/node/utils.d.ts +1 -1
- package/lib/node/utils.js +4 -4
- package/lib/quickstart/createAsyncLanguageServicePlugin.d.ts +5 -2
- package/lib/quickstart/createAsyncLanguageServicePlugin.js +11 -13
- package/lib/quickstart/createLanguageServicePlugin.d.ts +9 -2
- package/lib/quickstart/createLanguageServicePlugin.js +18 -17
- package/package.json +4 -4
|
@@ -11,9 +11,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
11
11
|
const { getNavigationTree, getOutliningSpans, } = languageService;
|
|
12
12
|
languageService.getNavigationTree = filePath => {
|
|
13
13
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
14
|
-
const [serviceScript,
|
|
15
|
-
if (serviceScript ||
|
|
16
|
-
const tree = getNavigationTree(
|
|
14
|
+
const [serviceScript, targetScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
15
|
+
if (serviceScript || targetScript?.associatedOnly) {
|
|
16
|
+
const tree = getNavigationTree(targetScript.id);
|
|
17
17
|
tree.childItems = undefined;
|
|
18
18
|
return tree;
|
|
19
19
|
}
|
|
@@ -23,8 +23,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
23
23
|
};
|
|
24
24
|
languageService.getOutliningSpans = filePath => {
|
|
25
25
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
26
|
-
const [serviceScript,
|
|
27
|
-
if (serviceScript ||
|
|
26
|
+
const [serviceScript, targetScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
27
|
+
if (serviceScript || targetScript?.associatedOnly) {
|
|
28
28
|
return [];
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
@@ -35,16 +35,16 @@ function decorateLanguageService(language, languageService) {
|
|
|
35
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
36
|
languageService.getFormattingEditsForDocument = (filePath, options) => {
|
|
37
37
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
38
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
39
|
-
if (
|
|
38
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
39
|
+
if (targetScript?.associatedOnly) {
|
|
40
40
|
return [];
|
|
41
41
|
}
|
|
42
42
|
if (serviceScript) {
|
|
43
|
-
const map = language.maps.get(serviceScript.code,
|
|
43
|
+
const map = language.maps.get(serviceScript.code, targetScript);
|
|
44
44
|
if (!map.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) {
|
|
45
45
|
return [];
|
|
46
46
|
}
|
|
47
|
-
const edits = getFormattingEditsForDocument(
|
|
47
|
+
const edits = getFormattingEditsForDocument(targetScript.id, options);
|
|
48
48
|
return edits
|
|
49
49
|
.map(edit => (0, transform_1.transformTextChange)(sourceScript, language, serviceScript, edit, language_core_1.isFormattingEnabled)?.[1])
|
|
50
50
|
.filter(utils_1.notEmpty);
|
|
@@ -55,15 +55,15 @@ function decorateLanguageService(language, languageService) {
|
|
|
55
55
|
};
|
|
56
56
|
languageService.getFormattingEditsForRange = (filePath, start, end, options) => {
|
|
57
57
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
58
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
59
|
-
if (
|
|
58
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
59
|
+
if (targetScript?.associatedOnly) {
|
|
60
60
|
return [];
|
|
61
61
|
}
|
|
62
62
|
if (serviceScript) {
|
|
63
63
|
const generateStart = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, start, language_core_1.isFormattingEnabled);
|
|
64
64
|
const generateEnd = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, end, language_core_1.isFormattingEnabled);
|
|
65
65
|
if (generateStart !== undefined && generateEnd !== undefined) {
|
|
66
|
-
const edits = getFormattingEditsForRange(
|
|
66
|
+
const edits = getFormattingEditsForRange(targetScript.id, generateStart, generateEnd, options);
|
|
67
67
|
return edits
|
|
68
68
|
.map(edit => (0, transform_1.transformTextChange)(sourceScript, language, serviceScript, edit, language_core_1.isFormattingEnabled)?.[1])
|
|
69
69
|
.filter(utils_1.notEmpty);
|
|
@@ -76,14 +76,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
76
76
|
};
|
|
77
77
|
languageService.getFormattingEditsAfterKeystroke = (filePath, position, key, options) => {
|
|
78
78
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
79
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
80
|
-
if (
|
|
79
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
80
|
+
if (targetScript?.associatedOnly) {
|
|
81
81
|
return [];
|
|
82
82
|
}
|
|
83
83
|
if (serviceScript) {
|
|
84
84
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isFormattingEnabled);
|
|
85
85
|
if (generatePosition !== undefined) {
|
|
86
|
-
const edits = getFormattingEditsAfterKeystroke(
|
|
86
|
+
const edits = getFormattingEditsAfterKeystroke(targetScript.id, generatePosition, key, options);
|
|
87
87
|
return edits
|
|
88
88
|
.map(edit => (0, transform_1.transformTextChange)(sourceScript, language, serviceScript, edit, language_core_1.isFormattingEnabled)?.[1])
|
|
89
89
|
.filter(utils_1.notEmpty);
|
|
@@ -96,18 +96,18 @@ function decorateLanguageService(language, languageService) {
|
|
|
96
96
|
};
|
|
97
97
|
languageService.getEditsForFileRename = (oldFilePath, newFilePath, formatOptions, preferences) => {
|
|
98
98
|
const edits = getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences);
|
|
99
|
-
return (0, transform_1.transformFileTextChanges)(
|
|
99
|
+
return (0, transform_1.transformFileTextChanges)(language, edits, language_core_1.isRenameEnabled);
|
|
100
100
|
};
|
|
101
101
|
languageService.getLinkedEditingRangeAtPosition = (filePath, position) => {
|
|
102
102
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
103
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
104
|
-
if (
|
|
103
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
104
|
+
if (targetScript?.associatedOnly) {
|
|
105
105
|
return undefined;
|
|
106
106
|
}
|
|
107
107
|
if (serviceScript) {
|
|
108
108
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isLinkedEditingEnabled);
|
|
109
109
|
if (generatePosition !== undefined) {
|
|
110
|
-
const info = getLinkedEditingRangeAtPosition(
|
|
110
|
+
const info = getLinkedEditingRangeAtPosition(targetScript.id, generatePosition);
|
|
111
111
|
if (info) {
|
|
112
112
|
return {
|
|
113
113
|
ranges: info.ranges
|
|
@@ -124,19 +124,19 @@ function decorateLanguageService(language, languageService) {
|
|
|
124
124
|
};
|
|
125
125
|
languageService.prepareCallHierarchy = (filePath, position) => {
|
|
126
126
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
127
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
128
|
-
if (
|
|
127
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
128
|
+
if (targetScript?.associatedOnly) {
|
|
129
129
|
return undefined;
|
|
130
130
|
}
|
|
131
131
|
if (serviceScript) {
|
|
132
132
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCallHierarchyEnabled);
|
|
133
133
|
if (generatePosition !== undefined) {
|
|
134
|
-
const item = prepareCallHierarchy(
|
|
134
|
+
const item = prepareCallHierarchy(targetScript.id, generatePosition);
|
|
135
135
|
if (Array.isArray(item)) {
|
|
136
|
-
return item.map(item => (0, transform_1.transformCallHierarchyItem)(
|
|
136
|
+
return item.map(item => (0, transform_1.transformCallHierarchyItem)(language, item, language_core_1.isCallHierarchyEnabled));
|
|
137
137
|
}
|
|
138
138
|
else if (item) {
|
|
139
|
-
return (0, transform_1.transformCallHierarchyItem)(
|
|
139
|
+
return (0, transform_1.transformCallHierarchyItem)(language, item, language_core_1.isCallHierarchyEnabled);
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
}
|
|
@@ -147,14 +147,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
147
147
|
languageService.provideCallHierarchyIncomingCalls = (filePath, position) => {
|
|
148
148
|
let calls = [];
|
|
149
149
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
150
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
151
|
-
if (
|
|
150
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
151
|
+
if (targetScript?.associatedOnly) {
|
|
152
152
|
return [];
|
|
153
153
|
}
|
|
154
154
|
if (serviceScript) {
|
|
155
155
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCallHierarchyEnabled);
|
|
156
156
|
if (generatePosition !== undefined) {
|
|
157
|
-
calls = provideCallHierarchyIncomingCalls(
|
|
157
|
+
calls = provideCallHierarchyIncomingCalls(targetScript.id, generatePosition);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
else {
|
|
@@ -162,9 +162,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
162
162
|
}
|
|
163
163
|
return calls
|
|
164
164
|
.map(call => {
|
|
165
|
-
const from = (0, transform_1.transformCallHierarchyItem)(
|
|
165
|
+
const from = (0, transform_1.transformCallHierarchyItem)(language, call.from, language_core_1.isCallHierarchyEnabled);
|
|
166
166
|
const fromSpans = call.fromSpans
|
|
167
|
-
.map(span => (0, transform_1.transformSpan)(
|
|
167
|
+
.map(span => (0, transform_1.transformSpan)(language, call.from.file, span, language_core_1.isCallHierarchyEnabled)?.textSpan)
|
|
168
168
|
.filter(utils_1.notEmpty);
|
|
169
169
|
return {
|
|
170
170
|
from,
|
|
@@ -175,14 +175,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
175
175
|
languageService.provideCallHierarchyOutgoingCalls = (filePath, position) => {
|
|
176
176
|
let calls = [];
|
|
177
177
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
178
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
179
|
-
if (
|
|
178
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
179
|
+
if (targetScript?.associatedOnly) {
|
|
180
180
|
return [];
|
|
181
181
|
}
|
|
182
182
|
if (serviceScript) {
|
|
183
183
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCallHierarchyEnabled);
|
|
184
184
|
if (generatePosition !== undefined) {
|
|
185
|
-
calls = provideCallHierarchyOutgoingCalls(
|
|
185
|
+
calls = provideCallHierarchyOutgoingCalls(targetScript.id, generatePosition);
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
else {
|
|
@@ -190,7 +190,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
190
190
|
}
|
|
191
191
|
return calls
|
|
192
192
|
.map(call => {
|
|
193
|
-
const to = (0, transform_1.transformCallHierarchyItem)(
|
|
193
|
+
const to = (0, transform_1.transformCallHierarchyItem)(language, call.to, language_core_1.isCallHierarchyEnabled);
|
|
194
194
|
const fromSpans = call.fromSpans
|
|
195
195
|
.map(span => serviceScript
|
|
196
196
|
? (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, span, language_core_1.isCallHierarchyEnabled)?.[1]
|
|
@@ -204,18 +204,18 @@ function decorateLanguageService(language, languageService) {
|
|
|
204
204
|
};
|
|
205
205
|
languageService.organizeImports = (args, formatOptions, preferences) => {
|
|
206
206
|
const unresolved = organizeImports(args, formatOptions, preferences);
|
|
207
|
-
return (0, transform_1.transformFileTextChanges)(
|
|
207
|
+
return (0, transform_1.transformFileTextChanges)(language, unresolved, language_core_1.isCodeActionsEnabled);
|
|
208
208
|
};
|
|
209
209
|
languageService.getQuickInfoAtPosition = (filePath, position) => {
|
|
210
210
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
211
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
212
|
-
if (
|
|
211
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
212
|
+
if (targetScript?.associatedOnly) {
|
|
213
213
|
return undefined;
|
|
214
214
|
}
|
|
215
215
|
if (serviceScript) {
|
|
216
216
|
const infos = [];
|
|
217
217
|
for (const [generatePosition] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, language_core_1.isHoverEnabled)) {
|
|
218
|
-
const info = getQuickInfoAtPosition(
|
|
218
|
+
const info = getQuickInfoAtPosition(targetScript.id, generatePosition);
|
|
219
219
|
if (info) {
|
|
220
220
|
const textSpan = (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, info.textSpan, language_core_1.isHoverEnabled)?.[1];
|
|
221
221
|
if (textSpan) {
|
|
@@ -271,14 +271,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
271
271
|
};
|
|
272
272
|
languageService.getSignatureHelpItems = (filePath, position, options) => {
|
|
273
273
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
274
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
275
|
-
if (
|
|
274
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
275
|
+
if (targetScript?.associatedOnly) {
|
|
276
276
|
return undefined;
|
|
277
277
|
}
|
|
278
278
|
if (serviceScript) {
|
|
279
279
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isSignatureHelpEnabled);
|
|
280
280
|
if (generatePosition !== undefined) {
|
|
281
|
-
const result = getSignatureHelpItems(
|
|
281
|
+
const result = getSignatureHelpItems(targetScript.id, generatePosition, options);
|
|
282
282
|
if (result) {
|
|
283
283
|
const applicableSpan = (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, result.applicableSpan, language_core_1.isSignatureHelpEnabled)?.[1];
|
|
284
284
|
if (applicableSpan) {
|
|
@@ -310,11 +310,11 @@ function decorateLanguageService(language, languageService) {
|
|
|
310
310
|
...highlights,
|
|
311
311
|
highlightSpans: highlights.highlightSpans
|
|
312
312
|
.map(span => {
|
|
313
|
-
const { textSpan } = (0, transform_1.transformSpan)(
|
|
313
|
+
const { textSpan } = (0, transform_1.transformSpan)(language, span.fileName ?? highlights.fileName, span.textSpan, language_core_1.isHighlightEnabled) ?? {};
|
|
314
314
|
if (textSpan) {
|
|
315
315
|
return {
|
|
316
316
|
...span,
|
|
317
|
-
contextSpan: (0, transform_1.transformSpan)(
|
|
317
|
+
contextSpan: (0, transform_1.transformSpan)(language, span.fileName ?? highlights.fileName, span.contextSpan, language_core_1.isHighlightEnabled)?.textSpan,
|
|
318
318
|
textSpan,
|
|
319
319
|
};
|
|
320
320
|
}
|
|
@@ -326,8 +326,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
326
326
|
};
|
|
327
327
|
languageService.getApplicableRefactors = (filePath, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
|
|
328
328
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
329
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
330
|
-
if (
|
|
329
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
330
|
+
if (targetScript?.associatedOnly) {
|
|
331
331
|
return [];
|
|
332
332
|
}
|
|
333
333
|
if (serviceScript) {
|
|
@@ -339,7 +339,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
339
339
|
pos: generatePosition,
|
|
340
340
|
end: generatePosition + positionOrRange.end - positionOrRange.pos,
|
|
341
341
|
};
|
|
342
|
-
return getApplicableRefactors(
|
|
342
|
+
return getApplicableRefactors(targetScript.id, por, preferences, triggerReason, kind, includeInteractiveActions);
|
|
343
343
|
}
|
|
344
344
|
return [];
|
|
345
345
|
}
|
|
@@ -350,8 +350,8 @@ function decorateLanguageService(language, languageService) {
|
|
|
350
350
|
languageService.getEditsForRefactor = (filePath, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
|
|
351
351
|
let edits;
|
|
352
352
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
353
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
354
|
-
if (
|
|
353
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
354
|
+
if (targetScript?.associatedOnly) {
|
|
355
355
|
return undefined;
|
|
356
356
|
}
|
|
357
357
|
if (serviceScript) {
|
|
@@ -365,21 +365,21 @@ function decorateLanguageService(language, languageService) {
|
|
|
365
365
|
pos: generatePosition,
|
|
366
366
|
end: generatePosition + positionOrRange.end - positionOrRange.pos,
|
|
367
367
|
};
|
|
368
|
-
edits = getEditsForRefactor(
|
|
368
|
+
edits = getEditsForRefactor(targetScript.id, formatOptions, por, refactorName, actionName, preferences);
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
371
|
else {
|
|
372
372
|
edits = getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName, preferences);
|
|
373
373
|
}
|
|
374
374
|
if (edits) {
|
|
375
|
-
edits.edits = (0, transform_1.transformFileTextChanges)(
|
|
375
|
+
edits.edits = (0, transform_1.transformFileTextChanges)(language, edits.edits, language_core_1.isCodeActionsEnabled);
|
|
376
376
|
return edits;
|
|
377
377
|
}
|
|
378
378
|
};
|
|
379
379
|
languageService.getRenameInfo = (filePath, position, options) => {
|
|
380
380
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
381
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
382
|
-
if (
|
|
381
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
382
|
+
if (targetScript?.associatedOnly) {
|
|
383
383
|
return {
|
|
384
384
|
canRename: false,
|
|
385
385
|
localizedErrorMessage: "Cannot rename"
|
|
@@ -388,7 +388,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
388
388
|
if (serviceScript) {
|
|
389
389
|
let failed;
|
|
390
390
|
for (const [generateOffset] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, language_core_1.isRenameEnabled)) {
|
|
391
|
-
const info = getRenameInfo(
|
|
391
|
+
const info = getRenameInfo(targetScript.id, generateOffset, options);
|
|
392
392
|
if (info.canRename) {
|
|
393
393
|
const span = (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, info.triggerSpan, language_core_1.isRenameEnabled)?.[1];
|
|
394
394
|
if (span) {
|
|
@@ -415,30 +415,30 @@ function decorateLanguageService(language, languageService) {
|
|
|
415
415
|
languageService.getCodeFixesAtPosition = (filePath, start, end, errorCodes, formatOptions, preferences) => {
|
|
416
416
|
let fixes = [];
|
|
417
417
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
418
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
419
|
-
if (
|
|
418
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
419
|
+
if (targetScript?.associatedOnly) {
|
|
420
420
|
return [];
|
|
421
421
|
}
|
|
422
422
|
if (serviceScript) {
|
|
423
423
|
const generateStart = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, start, language_core_1.isCodeActionsEnabled);
|
|
424
424
|
const generateEnd = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, end, language_core_1.isCodeActionsEnabled);
|
|
425
425
|
if (generateStart !== undefined && generateEnd !== undefined) {
|
|
426
|
-
fixes = getCodeFixesAtPosition(
|
|
426
|
+
fixes = getCodeFixesAtPosition(targetScript.id, generateStart, generateEnd, errorCodes, formatOptions, preferences);
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
429
|
else {
|
|
430
430
|
fixes = getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences);
|
|
431
431
|
}
|
|
432
432
|
fixes = fixes.map(fix => {
|
|
433
|
-
fix.changes = (0, transform_1.transformFileTextChanges)(
|
|
433
|
+
fix.changes = (0, transform_1.transformFileTextChanges)(language, fix.changes, language_core_1.isCodeActionsEnabled);
|
|
434
434
|
return fix;
|
|
435
435
|
});
|
|
436
436
|
return fixes;
|
|
437
437
|
};
|
|
438
438
|
languageService.getEncodedSemanticClassifications = (filePath, span, format) => {
|
|
439
439
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
440
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
441
|
-
if (
|
|
440
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
441
|
+
if (targetScript?.associatedOnly) {
|
|
442
442
|
return {
|
|
443
443
|
spans: [],
|
|
444
444
|
endOfLineState: 0
|
|
@@ -447,7 +447,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
447
447
|
if (serviceScript) {
|
|
448
448
|
let start;
|
|
449
449
|
let end;
|
|
450
|
-
const map = language.maps.get(serviceScript.code,
|
|
450
|
+
const map = language.maps.get(serviceScript.code, targetScript);
|
|
451
451
|
for (const mapping of map.mappings) {
|
|
452
452
|
// TODO reuse the logic from language service
|
|
453
453
|
if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
|
|
@@ -458,11 +458,11 @@ function decorateLanguageService(language, languageService) {
|
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
start ??= 0;
|
|
461
|
-
end ??=
|
|
461
|
+
end ??= targetScript.snapshot.getLength();
|
|
462
462
|
const mappingOffset = (0, transform_1.getMappingOffset)(language, serviceScript);
|
|
463
463
|
start += mappingOffset;
|
|
464
464
|
end += mappingOffset;
|
|
465
|
-
const result = getEncodedSemanticClassifications(
|
|
465
|
+
const result = getEncodedSemanticClassifications(targetScript.id, { start, length: end - start }, format);
|
|
466
466
|
const spans = [];
|
|
467
467
|
for (let i = 0; i < result.spans.length; i += 3) {
|
|
468
468
|
for (const sourceStart of (0, transform_1.toSourceOffsets)(sourceScript, language, serviceScript, result.spans[i], language_core_1.isSemanticTokensEnabled)) {
|
|
@@ -486,33 +486,36 @@ function decorateLanguageService(language, languageService) {
|
|
|
486
486
|
};
|
|
487
487
|
languageService.getSyntacticDiagnostics = filePath => {
|
|
488
488
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
489
|
-
const [
|
|
490
|
-
if (
|
|
489
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
490
|
+
if (targetScript?.associatedOnly) {
|
|
491
491
|
return [];
|
|
492
492
|
}
|
|
493
|
-
return getSyntacticDiagnostics(fileName)
|
|
494
|
-
.map(d => (0, transform_1.transformDiagnostic)(
|
|
495
|
-
.filter(utils_1.notEmpty)
|
|
493
|
+
return getSyntacticDiagnostics(targetScript?.id ?? fileName)
|
|
494
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, languageService.getProgram(), false))
|
|
495
|
+
.filter(utils_1.notEmpty)
|
|
496
|
+
.filter(d => !serviceScript || language.scripts.get(d.file.fileName) === sourceScript);
|
|
496
497
|
};
|
|
497
498
|
languageService.getSemanticDiagnostics = filePath => {
|
|
498
499
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
499
|
-
const [
|
|
500
|
-
if (
|
|
500
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
501
|
+
if (targetScript?.associatedOnly) {
|
|
501
502
|
return [];
|
|
502
503
|
}
|
|
503
|
-
return getSemanticDiagnostics(fileName)
|
|
504
|
-
.map(d => (0, transform_1.transformDiagnostic)(
|
|
505
|
-
.filter(utils_1.notEmpty)
|
|
504
|
+
return getSemanticDiagnostics(targetScript?.id ?? fileName)
|
|
505
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, languageService.getProgram(), false))
|
|
506
|
+
.filter(utils_1.notEmpty)
|
|
507
|
+
.filter(d => !serviceScript || !d.file || language.scripts.get(d.file.fileName) === sourceScript);
|
|
506
508
|
};
|
|
507
509
|
languageService.getSuggestionDiagnostics = filePath => {
|
|
508
510
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
509
|
-
const [
|
|
510
|
-
if (
|
|
511
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
512
|
+
if (targetScript?.associatedOnly) {
|
|
511
513
|
return [];
|
|
512
514
|
}
|
|
513
|
-
return getSuggestionDiagnostics(fileName)
|
|
514
|
-
.map(d => (0, transform_1.transformDiagnostic)(
|
|
515
|
-
.filter(utils_1.notEmpty)
|
|
515
|
+
return getSuggestionDiagnostics(targetScript?.id ?? fileName)
|
|
516
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, languageService.getProgram(), false))
|
|
517
|
+
.filter(utils_1.notEmpty)
|
|
518
|
+
.filter(d => !serviceScript || !d.file || language.scripts.get(d.file.fileName) === sourceScript);
|
|
516
519
|
};
|
|
517
520
|
languageService.getDefinitionAndBoundSpan = (filePath, position) => {
|
|
518
521
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
@@ -522,14 +525,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
522
525
|
}
|
|
523
526
|
});
|
|
524
527
|
const textSpan = unresolved
|
|
525
|
-
.map(s => (0, transform_1.transformSpan)(
|
|
528
|
+
.map(s => (0, transform_1.transformSpan)(language, fileName, s.textSpan, language_core_1.isDefinitionEnabled)?.textSpan)
|
|
526
529
|
.filter(utils_1.notEmpty)[0];
|
|
527
530
|
if (!textSpan) {
|
|
528
531
|
return;
|
|
529
532
|
}
|
|
530
533
|
const definitions = unresolved
|
|
531
534
|
.map(s => s.definitions
|
|
532
|
-
?.map(s => (0, transform_1.transformDocumentSpan)(
|
|
535
|
+
?.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
533
536
|
.filter(utils_1.notEmpty))
|
|
534
537
|
.filter(utils_1.notEmpty)
|
|
535
538
|
.flat();
|
|
@@ -550,11 +553,11 @@ function decorateLanguageService(language, languageService) {
|
|
|
550
553
|
const resolved = unresolved
|
|
551
554
|
.flat()
|
|
552
555
|
.map(symbol => {
|
|
553
|
-
const definition = (0, transform_1.transformDocumentSpan)(
|
|
556
|
+
const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled, true);
|
|
554
557
|
return {
|
|
555
558
|
definition,
|
|
556
559
|
references: symbol.references
|
|
557
|
-
.map(r => (0, transform_1.transformDocumentSpan)(
|
|
560
|
+
.map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled))
|
|
558
561
|
.filter(utils_1.notEmpty),
|
|
559
562
|
};
|
|
560
563
|
});
|
|
@@ -569,7 +572,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
569
572
|
});
|
|
570
573
|
const resolved = unresolved
|
|
571
574
|
.flat()
|
|
572
|
-
.map(s => (0, transform_1.transformDocumentSpan)(
|
|
575
|
+
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
573
576
|
.filter(utils_1.notEmpty);
|
|
574
577
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
575
578
|
};
|
|
@@ -582,7 +585,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
582
585
|
});
|
|
583
586
|
const resolved = unresolved
|
|
584
587
|
.flat()
|
|
585
|
-
.map(s => (0, transform_1.transformDocumentSpan)(
|
|
588
|
+
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isTypeDefinitionEnabled))
|
|
586
589
|
.filter(utils_1.notEmpty);
|
|
587
590
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
588
591
|
};
|
|
@@ -595,7 +598,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
595
598
|
});
|
|
596
599
|
const resolved = unresolved
|
|
597
600
|
.flat()
|
|
598
|
-
.map(s => (0, transform_1.transformDocumentSpan)(
|
|
601
|
+
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isImplementationEnabled))
|
|
599
602
|
.filter(utils_1.notEmpty);
|
|
600
603
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
601
604
|
};
|
|
@@ -608,7 +611,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
608
611
|
});
|
|
609
612
|
const resolved = unresolved
|
|
610
613
|
.flat()
|
|
611
|
-
.map(s => (0, transform_1.transformDocumentSpan)(
|
|
614
|
+
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isRenameEnabled))
|
|
612
615
|
.filter(utils_1.notEmpty);
|
|
613
616
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
614
617
|
};
|
|
@@ -621,20 +624,20 @@ function decorateLanguageService(language, languageService) {
|
|
|
621
624
|
});
|
|
622
625
|
const resolved = unresolved
|
|
623
626
|
.flat()
|
|
624
|
-
.map(s => (0, transform_1.transformDocumentSpan)(
|
|
627
|
+
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
|
|
625
628
|
.filter(utils_1.notEmpty);
|
|
626
629
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
627
630
|
};
|
|
628
631
|
languageService.getCompletionsAtPosition = (filePath, position, options, formattingSettings) => {
|
|
629
632
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
630
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
631
|
-
if (
|
|
633
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
634
|
+
if (targetScript?.associatedOnly) {
|
|
632
635
|
return undefined;
|
|
633
636
|
}
|
|
634
637
|
if (serviceScript) {
|
|
635
638
|
const results = [];
|
|
636
639
|
for (const [generatedOffset, mapping] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, language_core_1.isCompletionEnabled)) {
|
|
637
|
-
const result = getCompletionsAtPosition(
|
|
640
|
+
const result = getCompletionsAtPosition(targetScript.id, generatedOffset, options, formattingSettings);
|
|
638
641
|
if (!result) {
|
|
639
642
|
continue;
|
|
640
643
|
}
|
|
@@ -670,14 +673,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
670
673
|
languageService.getCompletionEntryDetails = (filePath, position, entryName, formatOptions, source, preferences, data) => {
|
|
671
674
|
let details;
|
|
672
675
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
673
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
674
|
-
if (
|
|
676
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
677
|
+
if (targetScript?.associatedOnly) {
|
|
675
678
|
return undefined;
|
|
676
679
|
}
|
|
677
680
|
if (serviceScript) {
|
|
678
681
|
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCompletionEnabled);
|
|
679
682
|
if (generatePosition !== undefined) {
|
|
680
|
-
details = getCompletionEntryDetails(
|
|
683
|
+
details = getCompletionEntryDetails(targetScript.id, generatePosition, entryName, formatOptions, source, preferences, data);
|
|
681
684
|
}
|
|
682
685
|
}
|
|
683
686
|
else {
|
|
@@ -685,21 +688,21 @@ function decorateLanguageService(language, languageService) {
|
|
|
685
688
|
}
|
|
686
689
|
if (details?.codeActions) {
|
|
687
690
|
for (const codeAction of details.codeActions) {
|
|
688
|
-
codeAction.changes = (0, transform_1.transformFileTextChanges)(
|
|
691
|
+
codeAction.changes = (0, transform_1.transformFileTextChanges)(language, codeAction.changes, language_core_1.isCompletionEnabled);
|
|
689
692
|
}
|
|
690
693
|
}
|
|
691
694
|
return details;
|
|
692
695
|
};
|
|
693
696
|
languageService.provideInlayHints = (filePath, span, preferences) => {
|
|
694
697
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
695
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
696
|
-
if (
|
|
698
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
699
|
+
if (targetScript?.associatedOnly) {
|
|
697
700
|
return [];
|
|
698
701
|
}
|
|
699
702
|
if (serviceScript) {
|
|
700
703
|
let start;
|
|
701
704
|
let end;
|
|
702
|
-
const map = language.maps.get(serviceScript.code,
|
|
705
|
+
const map = language.maps.get(serviceScript.code, targetScript);
|
|
703
706
|
for (const mapping of map.mappings) {
|
|
704
707
|
if ((0, language_core_1.isInlayHintsEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
|
|
705
708
|
start ??= mapping.generatedOffsets[0];
|
|
@@ -715,7 +718,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
715
718
|
const mappingOffset = (0, transform_1.getMappingOffset)(language, serviceScript);
|
|
716
719
|
start += mappingOffset;
|
|
717
720
|
end += mappingOffset;
|
|
718
|
-
const result = provideInlayHints(
|
|
721
|
+
const result = provideInlayHints(targetScript.id, { start, length: end - start }, preferences);
|
|
719
722
|
const hints = [];
|
|
720
723
|
for (const hint of result) {
|
|
721
724
|
const sourcePosition = (0, transform_1.toSourceOffset)(sourceScript, language, serviceScript, hint.position, language_core_1.isInlayHintsEnabled);
|
|
@@ -736,17 +739,17 @@ function decorateLanguageService(language, languageService) {
|
|
|
736
739
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
737
740
|
const unresolved = getFileReferences(fileName);
|
|
738
741
|
const resolved = unresolved
|
|
739
|
-
.map(s => (0, transform_1.transformDocumentSpan)(
|
|
742
|
+
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
|
|
740
743
|
.filter(utils_1.notEmpty);
|
|
741
744
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
742
745
|
};
|
|
743
746
|
function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
|
|
744
747
|
const results = [];
|
|
745
748
|
const processedFilePositions = new Set();
|
|
746
|
-
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
749
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
747
750
|
if (serviceScript) {
|
|
748
751
|
for (const [generatedOffset] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, filter)) {
|
|
749
|
-
process(
|
|
752
|
+
process(targetScript.id, generatedOffset);
|
|
750
753
|
}
|
|
751
754
|
}
|
|
752
755
|
else {
|
|
@@ -18,45 +18,60 @@ function decorateProgram(language, program) {
|
|
|
18
18
|
return {
|
|
19
19
|
...result,
|
|
20
20
|
diagnostics: result.diagnostics
|
|
21
|
-
.map(d => (0, transform_1.transformDiagnostic)(
|
|
21
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
22
22
|
.filter(utils_1.notEmpty),
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
program.getSyntacticDiagnostics = (sourceFile, cancellationToken) => {
|
|
26
26
|
if (!sourceFile) {
|
|
27
|
-
return
|
|
27
|
+
return getSyntacticDiagnostics(undefined, cancellationToken)
|
|
28
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
29
|
+
.filter(utils_1.notEmpty);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
33
|
+
const actualSourceFile = targetScript ? program.getSourceFile(targetScript.id) : sourceFile;
|
|
34
|
+
return getSyntacticDiagnostics(actualSourceFile, cancellationToken)
|
|
35
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
36
|
+
.filter(utils_1.notEmpty)
|
|
37
|
+
.filter(d => !serviceScript || !d.file || language.scripts.get(d.file.fileName) === sourceScript);
|
|
28
38
|
}
|
|
29
|
-
const [_serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
30
|
-
const actualSourceFile = sourceScript ? program.getSourceFile(sourceScript.id) : sourceFile;
|
|
31
|
-
return getSyntacticDiagnostics(actualSourceFile, cancellationToken)
|
|
32
|
-
.map(d => (0, transform_1.transformDiagnostic)(sourceScript, language, d, program, true))
|
|
33
|
-
.filter(utils_1.notEmpty);
|
|
34
39
|
};
|
|
35
40
|
program.getSemanticDiagnostics = (sourceFile, cancellationToken) => {
|
|
36
41
|
if (!sourceFile) {
|
|
37
|
-
return
|
|
42
|
+
return getSemanticDiagnostics(undefined, cancellationToken)
|
|
43
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
44
|
+
.filter(utils_1.notEmpty);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
48
|
+
const actualSourceFile = targetScript ? program.getSourceFile(targetScript.id) : sourceFile;
|
|
49
|
+
return getSemanticDiagnostics(actualSourceFile, cancellationToken)
|
|
50
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
51
|
+
.filter(utils_1.notEmpty)
|
|
52
|
+
.filter(d => !serviceScript || !d.file || language.scripts.get(d.file.fileName) === sourceScript);
|
|
38
53
|
}
|
|
39
|
-
const [_serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
40
|
-
const actualSourceFile = sourceScript ? program.getSourceFile(sourceScript.id) : sourceFile;
|
|
41
|
-
return getSemanticDiagnostics(actualSourceFile, cancellationToken)
|
|
42
|
-
.map(d => (0, transform_1.transformDiagnostic)(sourceScript, language, d, program, true))
|
|
43
|
-
.filter(utils_1.notEmpty);
|
|
44
54
|
};
|
|
45
55
|
program.getGlobalDiagnostics = cancellationToken => {
|
|
46
56
|
return getGlobalDiagnostics(cancellationToken)
|
|
47
|
-
.map(d => (0, transform_1.transformDiagnostic)(
|
|
57
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
48
58
|
.filter(utils_1.notEmpty);
|
|
49
59
|
};
|
|
50
60
|
// @ts-ignore
|
|
51
61
|
program.getBindAndCheckDiagnostics = (sourceFile, cancellationToken) => {
|
|
52
62
|
if (!sourceFile) {
|
|
53
|
-
return
|
|
63
|
+
return getBindAndCheckDiagnostics(undefined, cancellationToken)
|
|
64
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
65
|
+
.filter(utils_1.notEmpty);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const [serviceScript, targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
69
|
+
const actualSourceFile = targetScript ? program.getSourceFile(targetScript.id) : sourceFile;
|
|
70
|
+
return getBindAndCheckDiagnostics(actualSourceFile, cancellationToken)
|
|
71
|
+
.map(d => (0, transform_1.transformDiagnostic)(language, d, program, true))
|
|
72
|
+
.filter(utils_1.notEmpty)
|
|
73
|
+
.filter(d => !serviceScript || language.scripts.get(d.file.fileName) === sourceScript);
|
|
54
74
|
}
|
|
55
|
-
const [_serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
56
|
-
const actualSourceFile = sourceScript ? program.getSourceFile(sourceScript.id) : sourceFile;
|
|
57
|
-
return getBindAndCheckDiagnostics(actualSourceFile, cancellationToken)
|
|
58
|
-
.map(d => (0, transform_1.transformDiagnostic)(sourceScript, language, d, program, true))
|
|
59
|
-
.filter(utils_1.notEmpty);
|
|
60
75
|
};
|
|
61
76
|
// fix https://github.com/vuejs/language-tools/issues/4099 with `incremental`
|
|
62
77
|
program.getSourceFileByPath = path => {
|
package/lib/node/transform.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { CodeInformation, SourceScript, TypeScriptServiceScript } from '@volar/language-core';
|
|
2
2
|
import { Language } from '@volar/language-core';
|
|
3
3
|
import type * as ts from 'typescript';
|
|
4
|
-
export declare function transformCallHierarchyItem(
|
|
5
|
-
export declare function transformDiagnostic<T extends ts.Diagnostic>(
|
|
4
|
+
export declare function transformCallHierarchyItem(language: Language<string>, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem;
|
|
5
|
+
export declare function transformDiagnostic<T extends ts.Diagnostic>(language: Language<string>, diagnostic: T, program: ts.Program | undefined, isTsc: boolean): T | undefined;
|
|
6
6
|
export declare function fillSourceFileText(language: Language<string>, sourceFile: ts.SourceFile): void;
|
|
7
|
-
export declare function transformFileTextChanges(
|
|
8
|
-
export declare function transformDocumentSpan<T extends ts.DocumentSpan>(
|
|
9
|
-
export declare function transformSpan(
|
|
7
|
+
export declare function transformFileTextChanges(language: Language<string>, changes: readonly ts.FileTextChanges[], filter: (data: CodeInformation) => boolean): ts.FileTextChanges[];
|
|
8
|
+
export declare function transformDocumentSpan<T extends ts.DocumentSpan>(language: Language<string>, documentSpan: T, filter: (data: CodeInformation) => boolean, shouldFallback?: boolean): T | undefined;
|
|
9
|
+
export declare function transformSpan(language: Language<string>, fileName: string | undefined, textSpan: ts.TextSpan | undefined, filter: (data: CodeInformation) => boolean): {
|
|
10
10
|
fileName: string;
|
|
11
11
|
textSpan: ts.TextSpan;
|
|
12
12
|
} | undefined;
|
|
13
|
-
export declare function transformTextChange(
|
|
14
|
-
export declare function transformTextSpan(
|
|
15
|
-
export declare function toSourceOffset(
|
|
16
|
-
export declare function toSourceOffsets(
|
|
13
|
+
export declare function transformTextChange(sourceScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, textChange: ts.TextChange, filter: (data: CodeInformation) => boolean): [string, ts.TextChange] | undefined;
|
|
14
|
+
export declare function transformTextSpan(sourceScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, textSpan: ts.TextSpan, filter: (data: CodeInformation) => boolean): [string, ts.TextSpan] | undefined;
|
|
15
|
+
export declare function toSourceOffset(sourceScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, position: number, filter: (data: CodeInformation) => boolean): [fileName: string, offset: number] | undefined;
|
|
16
|
+
export declare function toSourceOffsets(sourceScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, position: number, filter: (data: CodeInformation) => boolean): Generator<[fileName: string, offset: number]>;
|
|
17
17
|
export declare function toGeneratedOffset(language: Language, serviceScript: TypeScriptServiceScript, sourceScript: SourceScript<string>, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
|
|
18
18
|
export declare function toGeneratedOffsets(language: Language, serviceScript: TypeScriptServiceScript, sourceScript: SourceScript<string>, position: number, filter: (data: CodeInformation) => boolean): Generator<readonly [number, import("@volar/language-core").Mapping<CodeInformation>], void, unknown>;
|
|
19
19
|
export declare function getMappingOffset(language: Language, serviceScript: TypeScriptServiceScript): number;
|
package/lib/node/transform.js
CHANGED
|
@@ -5,9 +5,9 @@ const language_core_1 = require("@volar/language-core");
|
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
const transformedDiagnostics = new WeakMap();
|
|
7
7
|
const transformedSourceFile = new WeakSet();
|
|
8
|
-
function transformCallHierarchyItem(
|
|
9
|
-
const span = transformSpan(
|
|
10
|
-
const selectionSpan = transformSpan(
|
|
8
|
+
function transformCallHierarchyItem(language, item, filter) {
|
|
9
|
+
const span = transformSpan(language, item.file, item.span, filter);
|
|
10
|
+
const selectionSpan = transformSpan(language, item.file, item.selectionSpan, filter);
|
|
11
11
|
return {
|
|
12
12
|
...item,
|
|
13
13
|
file: span?.fileName ?? item.file,
|
|
@@ -16,21 +16,21 @@ function transformCallHierarchyItem(targetScript, language, item, filter) {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
exports.transformCallHierarchyItem = transformCallHierarchyItem;
|
|
19
|
-
function transformDiagnostic(
|
|
19
|
+
function transformDiagnostic(language, diagnostic, program, isTsc) {
|
|
20
20
|
if (!transformedDiagnostics.has(diagnostic)) {
|
|
21
21
|
transformedDiagnostics.set(diagnostic, undefined);
|
|
22
22
|
const { relatedInformation } = diagnostic;
|
|
23
23
|
if (relatedInformation) {
|
|
24
24
|
diagnostic.relatedInformation = relatedInformation
|
|
25
|
-
.map(d => transformDiagnostic(
|
|
25
|
+
.map(d => transformDiagnostic(language, d, program, isTsc))
|
|
26
26
|
.filter(utils_1.notEmpty);
|
|
27
27
|
}
|
|
28
28
|
if (diagnostic.file !== undefined
|
|
29
29
|
&& diagnostic.start !== undefined
|
|
30
30
|
&& diagnostic.length !== undefined) {
|
|
31
|
-
const [serviceScript
|
|
31
|
+
const [serviceScript] = (0, utils_1.getServiceScript)(language, diagnostic.file.fileName);
|
|
32
32
|
if (serviceScript) {
|
|
33
|
-
const [sourceSpanFileName, sourceSpan] = transformTextSpan(
|
|
33
|
+
const [sourceSpanFileName, sourceSpan] = transformTextSpan(undefined, language, serviceScript, {
|
|
34
34
|
start: diagnostic.start,
|
|
35
35
|
length: diagnostic.length
|
|
36
36
|
}, language_core_1.shouldReportDiagnostics) ?? [];
|
|
@@ -68,21 +68,22 @@ function fillSourceFileText(language, sourceFile) {
|
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
transformedSourceFile.add(sourceFile);
|
|
71
|
-
const [serviceScript
|
|
71
|
+
const [serviceScript] = (0, utils_1.getServiceScript)(language, sourceFile.fileName);
|
|
72
72
|
if (serviceScript && !serviceScript.preventLeadingOffset) {
|
|
73
|
+
const sourceScript = language.scripts.fromVirtualCode(serviceScript.code);
|
|
73
74
|
sourceFile.text = sourceScript.snapshot.getText(0, sourceScript.snapshot.getLength())
|
|
74
75
|
+ sourceFile.text.substring(sourceScript.snapshot.getLength());
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
exports.fillSourceFileText = fillSourceFileText;
|
|
78
|
-
function transformFileTextChanges(
|
|
79
|
+
function transformFileTextChanges(language, changes, filter) {
|
|
79
80
|
const changesPerFile = {};
|
|
80
81
|
const newFiles = new Set();
|
|
81
82
|
for (const fileChanges of changes) {
|
|
82
83
|
const [_, source] = (0, utils_1.getServiceScript)(language, fileChanges.fileName);
|
|
83
84
|
if (source) {
|
|
84
85
|
fileChanges.textChanges.forEach(c => {
|
|
85
|
-
const { fileName, textSpan } = transformSpan(
|
|
86
|
+
const { fileName, textSpan } = transformSpan(language, fileChanges.fileName, c.span, filter) ?? {};
|
|
86
87
|
if (fileName && textSpan) {
|
|
87
88
|
(changesPerFile[fileName] ?? (changesPerFile[fileName] = [])).push({ ...c, span: textSpan });
|
|
88
89
|
}
|
|
@@ -109,8 +110,8 @@ function transformFileTextChanges(targetScript, language, changes, filter) {
|
|
|
109
110
|
return result;
|
|
110
111
|
}
|
|
111
112
|
exports.transformFileTextChanges = transformFileTextChanges;
|
|
112
|
-
function transformDocumentSpan(
|
|
113
|
-
let textSpan = transformSpan(
|
|
113
|
+
function transformDocumentSpan(language, documentSpan, filter, shouldFallback) {
|
|
114
|
+
let textSpan = transformSpan(language, documentSpan.fileName, documentSpan.textSpan, filter);
|
|
114
115
|
if (!textSpan && shouldFallback) {
|
|
115
116
|
textSpan = {
|
|
116
117
|
fileName: documentSpan.fileName,
|
|
@@ -120,9 +121,9 @@ function transformDocumentSpan(targetScript, language, documentSpan, filter, sho
|
|
|
120
121
|
if (!textSpan) {
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
|
-
const contextSpan = transformSpan(
|
|
124
|
-
const originalTextSpan = transformSpan(
|
|
125
|
-
const originalContextSpan = transformSpan(
|
|
124
|
+
const contextSpan = transformSpan(language, documentSpan.fileName, documentSpan.contextSpan, filter);
|
|
125
|
+
const originalTextSpan = transformSpan(language, documentSpan.originalFileName, documentSpan.originalTextSpan, filter);
|
|
126
|
+
const originalContextSpan = transformSpan(language, documentSpan.originalFileName, documentSpan.originalContextSpan, filter);
|
|
126
127
|
return {
|
|
127
128
|
...documentSpan,
|
|
128
129
|
fileName: textSpan.fileName,
|
|
@@ -134,16 +135,13 @@ function transformDocumentSpan(targetScript, language, documentSpan, filter, sho
|
|
|
134
135
|
};
|
|
135
136
|
}
|
|
136
137
|
exports.transformDocumentSpan = transformDocumentSpan;
|
|
137
|
-
function transformSpan(
|
|
138
|
+
function transformSpan(language, fileName, textSpan, filter) {
|
|
138
139
|
if (!fileName || !textSpan) {
|
|
139
140
|
return;
|
|
140
141
|
}
|
|
141
|
-
const [serviceScript
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
else if (serviceScript) {
|
|
146
|
-
const [sourceSpanFileName, sourceSpan] = transformTextSpan(targetScript, language, serviceScript, textSpan, filter) ?? [];
|
|
142
|
+
const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
143
|
+
if (serviceScript) {
|
|
144
|
+
const [sourceSpanFileName, sourceSpan] = transformTextSpan(undefined, language, serviceScript, textSpan, filter) ?? [];
|
|
147
145
|
if (sourceSpan && sourceSpanFileName) {
|
|
148
146
|
return {
|
|
149
147
|
fileName: sourceSpanFileName,
|
|
@@ -159,8 +157,8 @@ function transformSpan(targetScript, language, fileName, textSpan, filter) {
|
|
|
159
157
|
}
|
|
160
158
|
}
|
|
161
159
|
exports.transformSpan = transformSpan;
|
|
162
|
-
function transformTextChange(
|
|
163
|
-
const [sourceSpanFileName, sourceSpan] = transformTextSpan(
|
|
160
|
+
function transformTextChange(sourceScript, language, serviceScript, textChange, filter) {
|
|
161
|
+
const [sourceSpanFileName, sourceSpan] = transformTextSpan(sourceScript, language, serviceScript, textChange.span, filter) ?? [];
|
|
164
162
|
if (sourceSpan && sourceSpanFileName) {
|
|
165
163
|
return [sourceSpanFileName, {
|
|
166
164
|
newText: textChange.newText,
|
|
@@ -170,11 +168,11 @@ function transformTextChange(targetScript, language, serviceScript, textChange,
|
|
|
170
168
|
return undefined;
|
|
171
169
|
}
|
|
172
170
|
exports.transformTextChange = transformTextChange;
|
|
173
|
-
function transformTextSpan(
|
|
171
|
+
function transformTextSpan(sourceScript, language, serviceScript, textSpan, filter) {
|
|
174
172
|
const start = textSpan.start;
|
|
175
173
|
const end = textSpan.start + textSpan.length;
|
|
176
|
-
for (const sourceStart of toSourceOffsets(
|
|
177
|
-
for (const sourceEnd of toSourceOffsets(
|
|
174
|
+
for (const sourceStart of toSourceOffsets(sourceScript, language, serviceScript, start, filter)) {
|
|
175
|
+
for (const sourceEnd of toSourceOffsets(sourceScript, language, serviceScript, end, filter)) {
|
|
178
176
|
if (sourceStart[0] === sourceEnd[0]
|
|
179
177
|
&& sourceEnd[1] >= sourceStart[1]) {
|
|
180
178
|
return [sourceStart[0], {
|
|
@@ -186,18 +184,18 @@ function transformTextSpan(targetScript, language, serviceScript, textSpan, filt
|
|
|
186
184
|
}
|
|
187
185
|
}
|
|
188
186
|
exports.transformTextSpan = transformTextSpan;
|
|
189
|
-
function toSourceOffset(
|
|
190
|
-
for (const source of toSourceOffsets(
|
|
187
|
+
function toSourceOffset(sourceScript, language, serviceScript, position, filter) {
|
|
188
|
+
for (const source of toSourceOffsets(sourceScript, language, serviceScript, position, filter)) {
|
|
191
189
|
return source;
|
|
192
190
|
}
|
|
193
191
|
}
|
|
194
192
|
exports.toSourceOffset = toSourceOffset;
|
|
195
|
-
function* toSourceOffsets(
|
|
196
|
-
if (
|
|
197
|
-
const map = language.maps.get(serviceScript.code,
|
|
193
|
+
function* toSourceOffsets(sourceScript, language, serviceScript, position, filter) {
|
|
194
|
+
if (sourceScript) {
|
|
195
|
+
const map = language.maps.get(serviceScript.code, sourceScript);
|
|
198
196
|
for (const [sourceOffset, mapping] of map.getSourceOffsets(position - getMappingOffset(language, serviceScript))) {
|
|
199
197
|
if (filter(mapping.data)) {
|
|
200
|
-
yield [
|
|
198
|
+
yield [sourceScript.id, sourceOffset];
|
|
201
199
|
}
|
|
202
200
|
}
|
|
203
201
|
}
|
package/lib/node/utils.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Language, SourceScript, TypeScriptServiceScript } from '@volar/language-core';
|
|
2
2
|
export declare function notEmpty<T>(value: T | null | undefined): value is T;
|
|
3
|
-
export declare function getServiceScript(language: Language<string>, fileName: string): [TypeScriptServiceScript, SourceScript<string>] | [undefined, SourceScript<string>] | [undefined, undefined];
|
|
3
|
+
export declare function getServiceScript(language: Language<string>, fileName: string): [serviceScript: TypeScriptServiceScript, targetScript: SourceScript<string>, sourceScript: SourceScript<string>] | [serviceScript: undefined, sourceScript: SourceScript<string>, sourceScript: SourceScript<string>] | [serviceScript: undefined, sourceScript: undefined, targetScript: undefined];
|
package/lib/node/utils.js
CHANGED
|
@@ -13,21 +13,21 @@ function getServiceScript(language, fileName) {
|
|
|
13
13
|
if (targetScript?.generated) {
|
|
14
14
|
const serviceScript = targetScript.generated.languagePlugin.typescript?.getServiceScript(targetScript.generated.root);
|
|
15
15
|
if (serviceScript) {
|
|
16
|
-
return [serviceScript, targetScript];
|
|
16
|
+
return [serviceScript, targetScript, sourceScript];
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
if (sourceScript?.associatedOnly) {
|
|
22
|
-
return [undefined, sourceScript];
|
|
22
|
+
return [undefined, sourceScript, sourceScript];
|
|
23
23
|
}
|
|
24
24
|
if (sourceScript?.generated) {
|
|
25
25
|
const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
|
|
26
26
|
if (serviceScript) {
|
|
27
|
-
return [serviceScript, sourceScript];
|
|
27
|
+
return [serviceScript, sourceScript, sourceScript];
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
return [undefined, undefined];
|
|
30
|
+
return [undefined, undefined, undefined];
|
|
31
31
|
}
|
|
32
32
|
exports.getServiceScript = getServiceScript;
|
|
33
33
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import { LanguagePlugin } from '@volar/language-core';
|
|
1
|
+
import { Language, LanguagePlugin } from '@volar/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
export declare function createAsyncLanguageServicePlugin(extensions: string[], scriptKind: ts.ScriptKind,
|
|
3
|
+
export declare function createAsyncLanguageServicePlugin(extensions: string[], scriptKind: ts.ScriptKind, create: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => Promise<{
|
|
4
|
+
languagePlugins: LanguagePlugin<string>[];
|
|
5
|
+
setup?: (language: Language<string>) => void;
|
|
6
|
+
}>): ts.server.PluginModuleFactory;
|
|
@@ -6,18 +6,15 @@ const common_1 = require("../common");
|
|
|
6
6
|
const decorateLanguageService_1 = require("../node/decorateLanguageService");
|
|
7
7
|
const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
|
|
8
8
|
const createLanguageServicePlugin_1 = require("./createLanguageServicePlugin");
|
|
9
|
-
|
|
10
|
-
const decoratedLanguageServices = new WeakSet();
|
|
11
|
-
const decoratedLanguageServiceHosts = new WeakSet();
|
|
12
|
-
function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePlugins) {
|
|
9
|
+
function createAsyncLanguageServicePlugin(extensions, scriptKind, create) {
|
|
13
10
|
return modules => {
|
|
14
11
|
const { typescript: ts } = modules;
|
|
15
12
|
const pluginModule = {
|
|
16
13
|
create(info) {
|
|
17
|
-
if (!decoratedLanguageServices.has(info.languageService)
|
|
18
|
-
&& !decoratedLanguageServiceHosts.has(info.languageServiceHost)) {
|
|
19
|
-
decoratedLanguageServices.add(info.languageService);
|
|
20
|
-
decoratedLanguageServiceHosts.add(info.languageServiceHost);
|
|
14
|
+
if (!createLanguageServicePlugin_1.decoratedLanguageServices.has(info.languageService)
|
|
15
|
+
&& !createLanguageServicePlugin_1.decoratedLanguageServiceHosts.has(info.languageServiceHost)) {
|
|
16
|
+
createLanguageServicePlugin_1.decoratedLanguageServices.add(info.languageService);
|
|
17
|
+
createLanguageServicePlugin_1.decoratedLanguageServiceHosts.add(info.languageServiceHost);
|
|
21
18
|
const emptySnapshot = ts.ScriptSnapshot.fromString('');
|
|
22
19
|
const getScriptSnapshot = info.languageServiceHost.getScriptSnapshot.bind(info.languageServiceHost);
|
|
23
20
|
const getScriptVersion = info.languageServiceHost.getScriptVersion.bind(info.languageServiceHost);
|
|
@@ -52,7 +49,7 @@ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePl
|
|
|
52
49
|
return getProjectVersion();
|
|
53
50
|
};
|
|
54
51
|
}
|
|
55
|
-
|
|
52
|
+
create(ts, info).then(({ languagePlugins, setup }) => {
|
|
56
53
|
const syncedScriptVersions = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
|
|
57
54
|
const language = (0, language_core_1.createLanguage)([
|
|
58
55
|
...languagePlugins,
|
|
@@ -73,6 +70,7 @@ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePl
|
|
|
73
70
|
});
|
|
74
71
|
(0, decorateLanguageService_1.decorateLanguageService)(language, info.languageService);
|
|
75
72
|
(0, decorateLanguageServiceHost_1.decorateLanguageServiceHost)(ts, language, info.languageServiceHost);
|
|
73
|
+
setup?.(language);
|
|
76
74
|
info.project.markAsDirty();
|
|
77
75
|
initialized = true;
|
|
78
76
|
});
|
|
@@ -81,15 +79,15 @@ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePl
|
|
|
81
79
|
},
|
|
82
80
|
getExternalFiles(project, updateLevel = 0) {
|
|
83
81
|
if (updateLevel >= (1)
|
|
84
|
-
|| !externalFiles.has(project)) {
|
|
85
|
-
const oldFiles = externalFiles.get(project);
|
|
82
|
+
|| !createLanguageServicePlugin_1.externalFiles.has(project)) {
|
|
83
|
+
const oldFiles = createLanguageServicePlugin_1.externalFiles.get(project);
|
|
86
84
|
const newFiles = extensions.length ? (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, extensions) : [];
|
|
87
|
-
externalFiles.set(project, newFiles);
|
|
85
|
+
createLanguageServicePlugin_1.externalFiles.set(project, newFiles);
|
|
88
86
|
if (oldFiles && !(0, createLanguageServicePlugin_1.arrayItemsEqual)(oldFiles, newFiles)) {
|
|
89
87
|
project.refreshDiagnostics();
|
|
90
88
|
}
|
|
91
89
|
}
|
|
92
|
-
return externalFiles.get(project);
|
|
90
|
+
return createLanguageServicePlugin_1.externalFiles.get(project);
|
|
93
91
|
},
|
|
94
92
|
};
|
|
95
93
|
return pluginModule;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import { LanguagePlugin } from '@volar/language-core';
|
|
1
|
+
import { Language, LanguagePlugin } from '@volar/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
export declare
|
|
3
|
+
export declare const externalFiles: WeakMap<ts.server.Project, string[]>;
|
|
4
|
+
export declare const projectExternalFileExtensions: WeakMap<ts.server.Project, string[]>;
|
|
5
|
+
export declare const decoratedLanguageServices: WeakSet<ts.LanguageService>;
|
|
6
|
+
export declare const decoratedLanguageServiceHosts: WeakSet<ts.LanguageServiceHost>;
|
|
7
|
+
export declare function createLanguageServicePlugin(create: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => {
|
|
8
|
+
languagePlugins: LanguagePlugin<string>[];
|
|
9
|
+
setup?: (language: Language<string>) => void;
|
|
10
|
+
}): ts.server.PluginModuleFactory;
|
|
4
11
|
export declare function arrayItemsEqual(a: string[], b: string[]): boolean;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.arrayItemsEqual = exports.createLanguageServicePlugin = void 0;
|
|
3
|
+
exports.arrayItemsEqual = exports.createLanguageServicePlugin = exports.decoratedLanguageServiceHosts = exports.decoratedLanguageServices = exports.projectExternalFileExtensions = exports.externalFiles = void 0;
|
|
4
4
|
const language_core_1 = require("@volar/language-core");
|
|
5
5
|
const common_1 = require("../common");
|
|
6
6
|
const decorateLanguageService_1 = require("../node/decorateLanguageService");
|
|
7
7
|
const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function createLanguageServicePlugin(
|
|
8
|
+
exports.externalFiles = new WeakMap();
|
|
9
|
+
exports.projectExternalFileExtensions = new WeakMap();
|
|
10
|
+
exports.decoratedLanguageServices = new WeakSet();
|
|
11
|
+
exports.decoratedLanguageServiceHosts = new WeakSet();
|
|
12
|
+
function createLanguageServicePlugin(create) {
|
|
13
13
|
return modules => {
|
|
14
14
|
const { typescript: ts } = modules;
|
|
15
15
|
const pluginModule = {
|
|
16
16
|
create(info) {
|
|
17
|
-
if (!decoratedLanguageServices.has(info.languageService)
|
|
18
|
-
&& !decoratedLanguageServiceHosts.has(info.languageServiceHost)) {
|
|
19
|
-
decoratedLanguageServices.add(info.languageService);
|
|
20
|
-
decoratedLanguageServiceHosts.add(info.languageServiceHost);
|
|
21
|
-
const languagePlugins =
|
|
17
|
+
if (!exports.decoratedLanguageServices.has(info.languageService)
|
|
18
|
+
&& !exports.decoratedLanguageServiceHosts.has(info.languageServiceHost)) {
|
|
19
|
+
exports.decoratedLanguageServices.add(info.languageService);
|
|
20
|
+
exports.decoratedLanguageServiceHosts.add(info.languageServiceHost);
|
|
21
|
+
const { languagePlugins, setup } = create(ts, info);
|
|
22
22
|
const extensions = languagePlugins
|
|
23
23
|
.map(plugin => plugin.typescript?.extraFileExtensions.map(ext => '.' + ext.extension) ?? [])
|
|
24
24
|
.flat();
|
|
25
|
-
projectExternalFileExtensions.set(info.project, extensions);
|
|
25
|
+
exports.projectExternalFileExtensions.set(info.project, extensions);
|
|
26
26
|
const getScriptSnapshot = info.languageServiceHost.getScriptSnapshot.bind(info.languageServiceHost);
|
|
27
27
|
const getScriptVersion = info.languageServiceHost.getScriptVersion.bind(info.languageServiceHost);
|
|
28
28
|
const syncedScriptVersions = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
|
|
@@ -45,21 +45,22 @@ function createLanguageServicePlugin(loadLanguagePlugins) {
|
|
|
45
45
|
});
|
|
46
46
|
(0, decorateLanguageService_1.decorateLanguageService)(language, info.languageService);
|
|
47
47
|
(0, decorateLanguageServiceHost_1.decorateLanguageServiceHost)(ts, language, info.languageServiceHost);
|
|
48
|
+
setup?.(language);
|
|
48
49
|
}
|
|
49
50
|
return info.languageService;
|
|
50
51
|
},
|
|
51
52
|
getExternalFiles(project, updateLevel = 0) {
|
|
52
53
|
if (updateLevel >= (1)
|
|
53
|
-
|| !externalFiles.has(project)) {
|
|
54
|
-
const oldFiles = externalFiles.get(project);
|
|
55
|
-
const extensions = projectExternalFileExtensions.get(project);
|
|
54
|
+
|| !exports.externalFiles.has(project)) {
|
|
55
|
+
const oldFiles = exports.externalFiles.get(project);
|
|
56
|
+
const extensions = exports.projectExternalFileExtensions.get(project);
|
|
56
57
|
const newFiles = extensions?.length ? (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, extensions) : [];
|
|
57
|
-
externalFiles.set(project, newFiles);
|
|
58
|
+
exports.externalFiles.set(project, newFiles);
|
|
58
59
|
if (oldFiles && !arrayItemsEqual(oldFiles, newFiles)) {
|
|
59
60
|
project.refreshDiagnostics();
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
return externalFiles.get(project);
|
|
63
|
+
return exports.externalFiles.get(project);
|
|
63
64
|
},
|
|
64
65
|
};
|
|
65
66
|
return pluginModule;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volar/typescript",
|
|
3
|
-
"version": "2.3.0
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"directory": "packages/typescript"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@volar/language-core": "2.3.0
|
|
15
|
+
"@volar/language-core": "2.3.0",
|
|
16
16
|
"path-browserify": "^1.0.1",
|
|
17
17
|
"vscode-uri": "^3.0.8"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/node": "latest",
|
|
21
21
|
"@types/path-browserify": "latest",
|
|
22
|
-
"@volar/language-service": "2.3.0
|
|
22
|
+
"@volar/language-service": "2.3.0"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "4f6488605e22e0f76ea877460848a443fd3e8762"
|
|
25
25
|
}
|