@volar/typescript 2.3.0-alpha.7 → 2.3.0-alpha.9
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 +191 -131
- package/lib/node/decorateProgram.js +24 -9
- package/lib/node/transform.d.ts +13 -12
- package/lib/node/transform.js +117 -66
- package/lib/node/utils.d.ts +2 -2
- package/lib/node/utils.js +16 -5
- package/lib/quickstart/createAsyncLanguageServicePlugin.js +1 -1
- package/lib/quickstart/createLanguageServicePlugin.js +2 -1
- 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] = (0, utils_1.getServiceScript)(language, fileName);
|
|
15
|
-
if (serviceScript) {
|
|
16
|
-
const tree = getNavigationTree(
|
|
14
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
15
|
+
if (serviceScript || sourceScript?.associatedOnly) {
|
|
16
|
+
const tree = getNavigationTree(sourceScript.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] = (0, utils_1.getServiceScript)(language, fileName);
|
|
27
|
-
if (serviceScript) {
|
|
26
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
27
|
+
if (serviceScript || sourceScript?.associatedOnly) {
|
|
28
28
|
return [];
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
@@ -35,14 +35,18 @@ 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
|
|
38
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
39
|
+
if (sourceScript?.associatedOnly) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
39
42
|
if (serviceScript) {
|
|
43
|
+
const map = language.maps.get(serviceScript.code, sourceScript);
|
|
40
44
|
if (!map.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) {
|
|
41
45
|
return [];
|
|
42
46
|
}
|
|
43
|
-
const edits = getFormattingEditsForDocument(
|
|
47
|
+
const edits = getFormattingEditsForDocument(sourceScript.id, options);
|
|
44
48
|
return edits
|
|
45
|
-
.map(edit => (0, transform_1.transformTextChange)(
|
|
49
|
+
.map(edit => (0, transform_1.transformTextChange)(sourceScript, language, serviceScript, edit, language_core_1.isFormattingEnabled)?.[1])
|
|
46
50
|
.filter(utils_1.notEmpty);
|
|
47
51
|
}
|
|
48
52
|
else {
|
|
@@ -51,14 +55,17 @@ function decorateLanguageService(language, languageService) {
|
|
|
51
55
|
};
|
|
52
56
|
languageService.getFormattingEditsForRange = (filePath, start, end, options) => {
|
|
53
57
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
54
|
-
const [serviceScript, sourceScript
|
|
58
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
59
|
+
if (sourceScript?.associatedOnly) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
55
62
|
if (serviceScript) {
|
|
56
|
-
const generateStart = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
57
|
-
const generateEnd = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
63
|
+
const generateStart = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, start, language_core_1.isFormattingEnabled);
|
|
64
|
+
const generateEnd = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, end, language_core_1.isFormattingEnabled);
|
|
58
65
|
if (generateStart !== undefined && generateEnd !== undefined) {
|
|
59
|
-
const edits = getFormattingEditsForRange(
|
|
66
|
+
const edits = getFormattingEditsForRange(sourceScript.id, generateStart, generateEnd, options);
|
|
60
67
|
return edits
|
|
61
|
-
.map(edit => (0, transform_1.transformTextChange)(
|
|
68
|
+
.map(edit => (0, transform_1.transformTextChange)(sourceScript, language, serviceScript, edit, language_core_1.isFormattingEnabled)?.[1])
|
|
62
69
|
.filter(utils_1.notEmpty);
|
|
63
70
|
}
|
|
64
71
|
return [];
|
|
@@ -69,13 +76,16 @@ function decorateLanguageService(language, languageService) {
|
|
|
69
76
|
};
|
|
70
77
|
languageService.getFormattingEditsAfterKeystroke = (filePath, position, key, options) => {
|
|
71
78
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
72
|
-
const [serviceScript, sourceScript
|
|
79
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
80
|
+
if (sourceScript?.associatedOnly) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
73
83
|
if (serviceScript) {
|
|
74
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
84
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isFormattingEnabled);
|
|
75
85
|
if (generatePosition !== undefined) {
|
|
76
|
-
const edits = getFormattingEditsAfterKeystroke(
|
|
86
|
+
const edits = getFormattingEditsAfterKeystroke(sourceScript.id, generatePosition, key, options);
|
|
77
87
|
return edits
|
|
78
|
-
.map(edit => (0, transform_1.transformTextChange)(
|
|
88
|
+
.map(edit => (0, transform_1.transformTextChange)(sourceScript, language, serviceScript, edit, language_core_1.isFormattingEnabled)?.[1])
|
|
79
89
|
.filter(utils_1.notEmpty);
|
|
80
90
|
}
|
|
81
91
|
return [];
|
|
@@ -86,21 +96,22 @@ function decorateLanguageService(language, languageService) {
|
|
|
86
96
|
};
|
|
87
97
|
languageService.getEditsForFileRename = (oldFilePath, newFilePath, formatOptions, preferences) => {
|
|
88
98
|
const edits = getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences);
|
|
89
|
-
return edits
|
|
90
|
-
.map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isRenameEnabled))
|
|
91
|
-
.filter(utils_1.notEmpty);
|
|
99
|
+
return (0, transform_1.transformFileTextChanges)(undefined, language, edits, language_core_1.isRenameEnabled);
|
|
92
100
|
};
|
|
93
101
|
languageService.getLinkedEditingRangeAtPosition = (filePath, position) => {
|
|
94
102
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
95
|
-
const [serviceScript, sourceScript
|
|
103
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
104
|
+
if (sourceScript?.associatedOnly) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
96
107
|
if (serviceScript) {
|
|
97
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
108
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isLinkedEditingEnabled);
|
|
98
109
|
if (generatePosition !== undefined) {
|
|
99
|
-
const info = getLinkedEditingRangeAtPosition(
|
|
110
|
+
const info = getLinkedEditingRangeAtPosition(sourceScript.id, generatePosition);
|
|
100
111
|
if (info) {
|
|
101
112
|
return {
|
|
102
113
|
ranges: info.ranges
|
|
103
|
-
.map(span => (0, transform_1.transformTextSpan)(
|
|
114
|
+
.map(span => (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, span, language_core_1.isLinkedEditingEnabled)?.[1])
|
|
104
115
|
.filter(utils_1.notEmpty),
|
|
105
116
|
wordPattern: info.wordPattern,
|
|
106
117
|
};
|
|
@@ -113,16 +124,19 @@ function decorateLanguageService(language, languageService) {
|
|
|
113
124
|
};
|
|
114
125
|
languageService.prepareCallHierarchy = (filePath, position) => {
|
|
115
126
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
116
|
-
const [serviceScript, sourceScript
|
|
127
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
128
|
+
if (sourceScript?.associatedOnly) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
117
131
|
if (serviceScript) {
|
|
118
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
132
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCallHierarchyEnabled);
|
|
119
133
|
if (generatePosition !== undefined) {
|
|
120
|
-
const item = prepareCallHierarchy(
|
|
134
|
+
const item = prepareCallHierarchy(sourceScript.id, generatePosition);
|
|
121
135
|
if (Array.isArray(item)) {
|
|
122
|
-
return item.map(item => (0, transform_1.transformCallHierarchyItem)(language, item, language_core_1.isCallHierarchyEnabled));
|
|
136
|
+
return item.map(item => (0, transform_1.transformCallHierarchyItem)(undefined, language, item, language_core_1.isCallHierarchyEnabled));
|
|
123
137
|
}
|
|
124
138
|
else if (item) {
|
|
125
|
-
return (0, transform_1.transformCallHierarchyItem)(language, item, language_core_1.isCallHierarchyEnabled);
|
|
139
|
+
return (0, transform_1.transformCallHierarchyItem)(undefined, language, item, language_core_1.isCallHierarchyEnabled);
|
|
126
140
|
}
|
|
127
141
|
}
|
|
128
142
|
}
|
|
@@ -133,11 +147,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
133
147
|
languageService.provideCallHierarchyIncomingCalls = (filePath, position) => {
|
|
134
148
|
let calls = [];
|
|
135
149
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
136
|
-
const [serviceScript, sourceScript
|
|
150
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
151
|
+
if (sourceScript?.associatedOnly) {
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
137
154
|
if (serviceScript) {
|
|
138
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
155
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCallHierarchyEnabled);
|
|
139
156
|
if (generatePosition !== undefined) {
|
|
140
|
-
calls = provideCallHierarchyIncomingCalls(
|
|
157
|
+
calls = provideCallHierarchyIncomingCalls(sourceScript.id, generatePosition);
|
|
141
158
|
}
|
|
142
159
|
}
|
|
143
160
|
else {
|
|
@@ -145,9 +162,9 @@ function decorateLanguageService(language, languageService) {
|
|
|
145
162
|
}
|
|
146
163
|
return calls
|
|
147
164
|
.map(call => {
|
|
148
|
-
const from = (0, transform_1.transformCallHierarchyItem)(language, call.from, language_core_1.isCallHierarchyEnabled);
|
|
165
|
+
const from = (0, transform_1.transformCallHierarchyItem)(undefined, language, call.from, language_core_1.isCallHierarchyEnabled);
|
|
149
166
|
const fromSpans = call.fromSpans
|
|
150
|
-
.map(span => (0, transform_1.transformSpan)(language, call.from.file, span, language_core_1.isCallHierarchyEnabled)?.textSpan)
|
|
167
|
+
.map(span => (0, transform_1.transformSpan)(undefined, language, call.from.file, span, language_core_1.isCallHierarchyEnabled)?.textSpan)
|
|
151
168
|
.filter(utils_1.notEmpty);
|
|
152
169
|
return {
|
|
153
170
|
from,
|
|
@@ -158,9 +175,12 @@ function decorateLanguageService(language, languageService) {
|
|
|
158
175
|
languageService.provideCallHierarchyOutgoingCalls = (filePath, position) => {
|
|
159
176
|
let calls = [];
|
|
160
177
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
161
|
-
const [serviceScript, sourceScript
|
|
178
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
179
|
+
if (sourceScript?.associatedOnly) {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
162
182
|
if (serviceScript) {
|
|
163
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
183
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCallHierarchyEnabled);
|
|
164
184
|
if (generatePosition !== undefined) {
|
|
165
185
|
calls = provideCallHierarchyOutgoingCalls(fileName, generatePosition);
|
|
166
186
|
}
|
|
@@ -170,10 +190,10 @@ function decorateLanguageService(language, languageService) {
|
|
|
170
190
|
}
|
|
171
191
|
return calls
|
|
172
192
|
.map(call => {
|
|
173
|
-
const to = (0, transform_1.transformCallHierarchyItem)(language, call.to, language_core_1.isCallHierarchyEnabled);
|
|
193
|
+
const to = (0, transform_1.transformCallHierarchyItem)(undefined, language, call.to, language_core_1.isCallHierarchyEnabled);
|
|
174
194
|
const fromSpans = call.fromSpans
|
|
175
|
-
.map(span =>
|
|
176
|
-
? (0, transform_1.transformTextSpan)(
|
|
195
|
+
.map(span => serviceScript
|
|
196
|
+
? (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, span, language_core_1.isCallHierarchyEnabled)?.[1]
|
|
177
197
|
: span)
|
|
178
198
|
.filter(utils_1.notEmpty);
|
|
179
199
|
return {
|
|
@@ -184,27 +204,24 @@ function decorateLanguageService(language, languageService) {
|
|
|
184
204
|
};
|
|
185
205
|
languageService.organizeImports = (args, formatOptions, preferences) => {
|
|
186
206
|
const unresolved = organizeImports(args, formatOptions, preferences);
|
|
187
|
-
|
|
188
|
-
.map(changes => (0, transform_1.transformFileTextChanges)(language, changes, language_core_1.isCodeActionsEnabled))
|
|
189
|
-
.filter(utils_1.notEmpty);
|
|
190
|
-
return resolved;
|
|
207
|
+
return (0, transform_1.transformFileTextChanges)(undefined, language, unresolved, language_core_1.isCodeActionsEnabled);
|
|
191
208
|
};
|
|
192
209
|
languageService.getQuickInfoAtPosition = (filePath, position) => {
|
|
193
210
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
194
|
-
const [serviceScript, sourceScript
|
|
211
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
212
|
+
if (sourceScript?.associatedOnly) {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
195
215
|
if (serviceScript) {
|
|
196
216
|
const infos = [];
|
|
197
|
-
for (const [generatePosition
|
|
198
|
-
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
const info = getQuickInfoAtPosition(fileName, generatePosition);
|
|
217
|
+
for (const [generatePosition] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, language_core_1.isHoverEnabled)) {
|
|
218
|
+
const info = getQuickInfoAtPosition(sourceScript.id, generatePosition);
|
|
202
219
|
if (info) {
|
|
203
|
-
const textSpan = (0, transform_1.transformTextSpan)(
|
|
220
|
+
const textSpan = (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, info.textSpan, language_core_1.isHoverEnabled)?.[1];
|
|
204
221
|
if (textSpan) {
|
|
205
222
|
infos.push({
|
|
206
223
|
...info,
|
|
207
|
-
textSpan,
|
|
224
|
+
textSpan: textSpan,
|
|
208
225
|
});
|
|
209
226
|
}
|
|
210
227
|
}
|
|
@@ -254,13 +271,16 @@ function decorateLanguageService(language, languageService) {
|
|
|
254
271
|
};
|
|
255
272
|
languageService.getSignatureHelpItems = (filePath, position, options) => {
|
|
256
273
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
257
|
-
const [serviceScript, sourceScript
|
|
274
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
275
|
+
if (sourceScript?.associatedOnly) {
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
258
278
|
if (serviceScript) {
|
|
259
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
279
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isSignatureHelpEnabled);
|
|
260
280
|
if (generatePosition !== undefined) {
|
|
261
|
-
const result = getSignatureHelpItems(
|
|
281
|
+
const result = getSignatureHelpItems(sourceScript.id, generatePosition, options);
|
|
262
282
|
if (result) {
|
|
263
|
-
const applicableSpan = (0, transform_1.transformTextSpan)(
|
|
283
|
+
const applicableSpan = (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, result.applicableSpan, language_core_1.isSignatureHelpEnabled)?.[1];
|
|
264
284
|
if (applicableSpan) {
|
|
265
285
|
return {
|
|
266
286
|
...result,
|
|
@@ -276,7 +296,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
276
296
|
};
|
|
277
297
|
languageService.getDocumentHighlights = (filePath, position, filesToSearch) => {
|
|
278
298
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
279
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isHighlightEnabled, position => getDocumentHighlights(fileName, position, filesToSearch), function* (result) {
|
|
299
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isHighlightEnabled, (fileName, position) => getDocumentHighlights(fileName, position, filesToSearch), function* (result) {
|
|
280
300
|
for (const ref of result) {
|
|
281
301
|
for (const reference of ref.highlightSpans) {
|
|
282
302
|
yield [reference.fileName ?? ref.fileName, reference.textSpan.start];
|
|
@@ -290,11 +310,11 @@ function decorateLanguageService(language, languageService) {
|
|
|
290
310
|
...highlights,
|
|
291
311
|
highlightSpans: highlights.highlightSpans
|
|
292
312
|
.map(span => {
|
|
293
|
-
const textSpan = (0, transform_1.transformSpan)(language, span.fileName ?? highlights.fileName, span.textSpan, language_core_1.isHighlightEnabled)
|
|
313
|
+
const { textSpan } = (0, transform_1.transformSpan)(undefined, language, span.fileName ?? highlights.fileName, span.textSpan, language_core_1.isHighlightEnabled) ?? {};
|
|
294
314
|
if (textSpan) {
|
|
295
315
|
return {
|
|
296
316
|
...span,
|
|
297
|
-
contextSpan: (0, transform_1.transformSpan)(language, span.fileName ?? highlights.fileName, span.contextSpan, language_core_1.isHighlightEnabled)?.textSpan,
|
|
317
|
+
contextSpan: (0, transform_1.transformSpan)(undefined, language, span.fileName ?? highlights.fileName, span.contextSpan, language_core_1.isHighlightEnabled)?.textSpan,
|
|
298
318
|
textSpan,
|
|
299
319
|
};
|
|
300
320
|
}
|
|
@@ -306,9 +326,12 @@ function decorateLanguageService(language, languageService) {
|
|
|
306
326
|
};
|
|
307
327
|
languageService.getApplicableRefactors = (filePath, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
|
|
308
328
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
309
|
-
const [serviceScript, sourceScript
|
|
329
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
330
|
+
if (sourceScript?.associatedOnly) {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
310
333
|
if (serviceScript) {
|
|
311
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
334
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos, language_core_1.isCodeActionsEnabled);
|
|
312
335
|
if (generatePosition !== undefined) {
|
|
313
336
|
const por = typeof positionOrRange === 'number'
|
|
314
337
|
? generatePosition
|
|
@@ -316,7 +339,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
316
339
|
pos: generatePosition,
|
|
317
340
|
end: generatePosition + positionOrRange.end - positionOrRange.pos,
|
|
318
341
|
};
|
|
319
|
-
return getApplicableRefactors(
|
|
342
|
+
return getApplicableRefactors(sourceScript.id, por, preferences, triggerReason, kind, includeInteractiveActions);
|
|
320
343
|
}
|
|
321
344
|
return [];
|
|
322
345
|
}
|
|
@@ -327,9 +350,12 @@ function decorateLanguageService(language, languageService) {
|
|
|
327
350
|
languageService.getEditsForRefactor = (filePath, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
|
|
328
351
|
let edits;
|
|
329
352
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
330
|
-
const [serviceScript, sourceScript
|
|
353
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
354
|
+
if (sourceScript?.associatedOnly) {
|
|
355
|
+
return undefined;
|
|
356
|
+
}
|
|
331
357
|
if (serviceScript) {
|
|
332
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
358
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, typeof positionOrRange === 'number'
|
|
333
359
|
? positionOrRange
|
|
334
360
|
: positionOrRange.pos, language_core_1.isCodeActionsEnabled);
|
|
335
361
|
if (generatePosition !== undefined) {
|
|
@@ -339,31 +365,32 @@ function decorateLanguageService(language, languageService) {
|
|
|
339
365
|
pos: generatePosition,
|
|
340
366
|
end: generatePosition + positionOrRange.end - positionOrRange.pos,
|
|
341
367
|
};
|
|
342
|
-
edits = getEditsForRefactor(
|
|
368
|
+
edits = getEditsForRefactor(sourceScript.id, formatOptions, por, refactorName, actionName, preferences);
|
|
343
369
|
}
|
|
344
370
|
}
|
|
345
371
|
else {
|
|
346
372
|
edits = getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName, preferences);
|
|
347
373
|
}
|
|
348
374
|
if (edits) {
|
|
349
|
-
edits.edits = edits.edits
|
|
350
|
-
.map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isCodeActionsEnabled))
|
|
351
|
-
.filter(utils_1.notEmpty);
|
|
375
|
+
edits.edits = (0, transform_1.transformFileTextChanges)(undefined, language, edits.edits, language_core_1.isCodeActionsEnabled);
|
|
352
376
|
return edits;
|
|
353
377
|
}
|
|
354
378
|
};
|
|
355
379
|
languageService.getRenameInfo = (filePath, position, options) => {
|
|
356
380
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
357
|
-
const [serviceScript, sourceScript
|
|
381
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
382
|
+
if (sourceScript?.associatedOnly) {
|
|
383
|
+
return {
|
|
384
|
+
canRename: false,
|
|
385
|
+
localizedErrorMessage: "Cannot rename"
|
|
386
|
+
};
|
|
387
|
+
}
|
|
358
388
|
if (serviceScript) {
|
|
359
389
|
let failed;
|
|
360
|
-
for (const [generateOffset
|
|
361
|
-
|
|
362
|
-
continue;
|
|
363
|
-
}
|
|
364
|
-
const info = getRenameInfo(fileName, generateOffset, options);
|
|
390
|
+
for (const [generateOffset] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, language_core_1.isRenameEnabled)) {
|
|
391
|
+
const info = getRenameInfo(sourceScript.id, generateOffset, options);
|
|
365
392
|
if (info.canRename) {
|
|
366
|
-
const span = (0, transform_1.transformTextSpan)(
|
|
393
|
+
const span = (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, info.triggerSpan, language_core_1.isRenameEnabled)?.[1];
|
|
367
394
|
if (span) {
|
|
368
395
|
info.triggerSpan = span;
|
|
369
396
|
return info;
|
|
@@ -388,29 +415,39 @@ function decorateLanguageService(language, languageService) {
|
|
|
388
415
|
languageService.getCodeFixesAtPosition = (filePath, start, end, errorCodes, formatOptions, preferences) => {
|
|
389
416
|
let fixes = [];
|
|
390
417
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
391
|
-
const [serviceScript, sourceScript
|
|
418
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
419
|
+
if (sourceScript?.associatedOnly) {
|
|
420
|
+
return [];
|
|
421
|
+
}
|
|
392
422
|
if (serviceScript) {
|
|
393
|
-
const generateStart = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
394
|
-
const generateEnd = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
423
|
+
const generateStart = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, start, language_core_1.isCodeActionsEnabled);
|
|
424
|
+
const generateEnd = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, end, language_core_1.isCodeActionsEnabled);
|
|
395
425
|
if (generateStart !== undefined && generateEnd !== undefined) {
|
|
396
|
-
fixes = getCodeFixesAtPosition(
|
|
426
|
+
fixes = getCodeFixesAtPosition(sourceScript.id, generateStart, generateEnd, errorCodes, formatOptions, preferences);
|
|
397
427
|
}
|
|
398
428
|
}
|
|
399
429
|
else {
|
|
400
430
|
fixes = getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences);
|
|
401
431
|
}
|
|
402
432
|
fixes = fixes.map(fix => {
|
|
403
|
-
fix.changes =
|
|
433
|
+
fix.changes = (0, transform_1.transformFileTextChanges)(undefined, language, fix.changes, language_core_1.isCodeActionsEnabled);
|
|
404
434
|
return fix;
|
|
405
435
|
});
|
|
406
436
|
return fixes;
|
|
407
437
|
};
|
|
408
438
|
languageService.getEncodedSemanticClassifications = (filePath, span, format) => {
|
|
409
439
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
410
|
-
const [serviceScript, sourceScript
|
|
440
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
441
|
+
if (sourceScript?.associatedOnly) {
|
|
442
|
+
return {
|
|
443
|
+
spans: [],
|
|
444
|
+
endOfLineState: 0
|
|
445
|
+
};
|
|
446
|
+
}
|
|
411
447
|
if (serviceScript) {
|
|
412
448
|
let start;
|
|
413
449
|
let end;
|
|
450
|
+
const map = language.maps.get(serviceScript.code, sourceScript);
|
|
414
451
|
for (const mapping of map.mappings) {
|
|
415
452
|
// TODO reuse the logic from language service
|
|
416
453
|
if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
|
|
@@ -422,16 +459,22 @@ function decorateLanguageService(language, languageService) {
|
|
|
422
459
|
}
|
|
423
460
|
start ??= 0;
|
|
424
461
|
end ??= sourceScript.snapshot.getLength();
|
|
425
|
-
const mappingOffset = (0, transform_1.getMappingOffset)(
|
|
462
|
+
const mappingOffset = (0, transform_1.getMappingOffset)(language, serviceScript);
|
|
426
463
|
start += mappingOffset;
|
|
427
464
|
end += mappingOffset;
|
|
428
|
-
const result = getEncodedSemanticClassifications(
|
|
465
|
+
const result = getEncodedSemanticClassifications(sourceScript.id, { start, length: end - start }, format);
|
|
429
466
|
const spans = [];
|
|
430
467
|
for (let i = 0; i < result.spans.length; i += 3) {
|
|
431
|
-
const sourceStart
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
468
|
+
for (const sourceStart of (0, transform_1.toSourceOffsets)(sourceScript, language, serviceScript, result.spans[i], language_core_1.isSemanticTokensEnabled)) {
|
|
469
|
+
for (const sourceEnd of (0, transform_1.toSourceOffsets)(sourceScript, language, serviceScript, result.spans[i] + result.spans[i + 1], language_core_1.isSemanticTokensEnabled)) {
|
|
470
|
+
if (sourceStart[0] === sourceEnd[0] && sourceEnd[1] >= sourceStart[1]) {
|
|
471
|
+
spans.push(sourceStart[1], sourceEnd[1] - sourceStart[1], result.spans[i + 2]);
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (spans.length) {
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
435
478
|
}
|
|
436
479
|
}
|
|
437
480
|
result.spans = spans;
|
|
@@ -443,38 +486,50 @@ function decorateLanguageService(language, languageService) {
|
|
|
443
486
|
};
|
|
444
487
|
languageService.getSyntacticDiagnostics = filePath => {
|
|
445
488
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
489
|
+
const [_serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
490
|
+
if (sourceScript?.associatedOnly) {
|
|
491
|
+
return [];
|
|
492
|
+
}
|
|
446
493
|
return getSyntacticDiagnostics(fileName)
|
|
447
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d, false))
|
|
494
|
+
.map(d => (0, transform_1.transformDiagnostic)(sourceScript, language, d, languageService.getProgram(), false))
|
|
448
495
|
.filter(utils_1.notEmpty);
|
|
449
496
|
};
|
|
450
497
|
languageService.getSemanticDiagnostics = filePath => {
|
|
451
498
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
499
|
+
const [_serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
500
|
+
if (sourceScript?.associatedOnly) {
|
|
501
|
+
return [];
|
|
502
|
+
}
|
|
452
503
|
return getSemanticDiagnostics(fileName)
|
|
453
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d, false))
|
|
504
|
+
.map(d => (0, transform_1.transformDiagnostic)(sourceScript, language, d, languageService.getProgram(), false))
|
|
454
505
|
.filter(utils_1.notEmpty);
|
|
455
506
|
};
|
|
456
507
|
languageService.getSuggestionDiagnostics = filePath => {
|
|
457
508
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
509
|
+
const [_serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
510
|
+
if (sourceScript?.associatedOnly) {
|
|
511
|
+
return [];
|
|
512
|
+
}
|
|
458
513
|
return getSuggestionDiagnostics(fileName)
|
|
459
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d, false))
|
|
514
|
+
.map(d => (0, transform_1.transformDiagnostic)(sourceScript, language, d, languageService.getProgram(), false))
|
|
460
515
|
.filter(utils_1.notEmpty);
|
|
461
516
|
};
|
|
462
517
|
languageService.getDefinitionAndBoundSpan = (filePath, position) => {
|
|
463
518
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
464
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAndBoundSpan(fileName, position), function* (result) {
|
|
519
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, (fileName, position) => getDefinitionAndBoundSpan(fileName, position), function* (result) {
|
|
465
520
|
for (const ref of result.definitions ?? []) {
|
|
466
521
|
yield [ref.fileName, ref.textSpan.start];
|
|
467
522
|
}
|
|
468
523
|
});
|
|
469
524
|
const textSpan = unresolved
|
|
470
|
-
.map(s => (0, transform_1.transformSpan)(language, fileName, s.textSpan, language_core_1.isDefinitionEnabled)?.textSpan)
|
|
525
|
+
.map(s => (0, transform_1.transformSpan)(undefined, language, fileName, s.textSpan, language_core_1.isDefinitionEnabled)?.textSpan)
|
|
471
526
|
.filter(utils_1.notEmpty)[0];
|
|
472
527
|
if (!textSpan) {
|
|
473
528
|
return;
|
|
474
529
|
}
|
|
475
530
|
const definitions = unresolved
|
|
476
531
|
.map(s => s.definitions
|
|
477
|
-
?.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
532
|
+
?.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
478
533
|
.filter(utils_1.notEmpty))
|
|
479
534
|
.filter(utils_1.notEmpty)
|
|
480
535
|
.flat();
|
|
@@ -485,7 +540,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
485
540
|
};
|
|
486
541
|
languageService.findReferences = (filePath, position) => {
|
|
487
542
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
488
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => findReferences(fileName, position), function* (result) {
|
|
543
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, (fileName, position) => findReferences(fileName, position), function* (result) {
|
|
489
544
|
for (const ref of result) {
|
|
490
545
|
for (const reference of ref.references) {
|
|
491
546
|
yield [reference.fileName, reference.textSpan.start];
|
|
@@ -495,11 +550,11 @@ function decorateLanguageService(language, languageService) {
|
|
|
495
550
|
const resolved = unresolved
|
|
496
551
|
.flat()
|
|
497
552
|
.map(symbol => {
|
|
498
|
-
const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled, true);
|
|
553
|
+
const definition = (0, transform_1.transformDocumentSpan)(undefined, language, symbol.definition, language_core_1.isDefinitionEnabled, true);
|
|
499
554
|
return {
|
|
500
555
|
definition,
|
|
501
556
|
references: symbol.references
|
|
502
|
-
.map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled))
|
|
557
|
+
.map(r => (0, transform_1.transformDocumentSpan)(undefined, language, r, language_core_1.isReferencesEnabled))
|
|
503
558
|
.filter(utils_1.notEmpty),
|
|
504
559
|
};
|
|
505
560
|
});
|
|
@@ -507,79 +562,79 @@ function decorateLanguageService(language, languageService) {
|
|
|
507
562
|
};
|
|
508
563
|
languageService.getDefinitionAtPosition = (filePath, position) => {
|
|
509
564
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
510
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAtPosition(fileName, position), function* (result) {
|
|
565
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, (fileName, position) => getDefinitionAtPosition(fileName, position), function* (result) {
|
|
511
566
|
for (const ref of result) {
|
|
512
567
|
yield [ref.fileName, ref.textSpan.start];
|
|
513
568
|
}
|
|
514
569
|
});
|
|
515
570
|
const resolved = unresolved
|
|
516
571
|
.flat()
|
|
517
|
-
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
572
|
+
.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
518
573
|
.filter(utils_1.notEmpty);
|
|
519
574
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
520
575
|
};
|
|
521
576
|
languageService.getTypeDefinitionAtPosition = (filePath, position) => {
|
|
522
577
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
523
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, position => getTypeDefinitionAtPosition(fileName, position), function* (result) {
|
|
578
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, (fileName, position) => getTypeDefinitionAtPosition(fileName, position), function* (result) {
|
|
524
579
|
for (const ref of result) {
|
|
525
580
|
yield [ref.fileName, ref.textSpan.start];
|
|
526
581
|
}
|
|
527
582
|
});
|
|
528
583
|
const resolved = unresolved
|
|
529
584
|
.flat()
|
|
530
|
-
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isTypeDefinitionEnabled))
|
|
585
|
+
.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isTypeDefinitionEnabled))
|
|
531
586
|
.filter(utils_1.notEmpty);
|
|
532
587
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
533
588
|
};
|
|
534
589
|
languageService.getImplementationAtPosition = (filePath, position) => {
|
|
535
590
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
536
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, position => getImplementationAtPosition(fileName, position), function* (result) {
|
|
591
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, (fileName, position) => getImplementationAtPosition(fileName, position), function* (result) {
|
|
537
592
|
for (const ref of result) {
|
|
538
593
|
yield [ref.fileName, ref.textSpan.start];
|
|
539
594
|
}
|
|
540
595
|
});
|
|
541
596
|
const resolved = unresolved
|
|
542
597
|
.flat()
|
|
543
|
-
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isImplementationEnabled))
|
|
598
|
+
.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isImplementationEnabled))
|
|
544
599
|
.filter(utils_1.notEmpty);
|
|
545
600
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
546
601
|
};
|
|
547
602
|
languageService.findRenameLocations = (filePath, position, findInStrings, findInComments, preferences) => {
|
|
548
603
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
549
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, position => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) {
|
|
604
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, (fileName, position) => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) {
|
|
550
605
|
for (const ref of result) {
|
|
551
606
|
yield [ref.fileName, ref.textSpan.start];
|
|
552
607
|
}
|
|
553
608
|
});
|
|
554
609
|
const resolved = unresolved
|
|
555
610
|
.flat()
|
|
556
|
-
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isRenameEnabled))
|
|
611
|
+
.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isRenameEnabled))
|
|
557
612
|
.filter(utils_1.notEmpty);
|
|
558
613
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
559
614
|
};
|
|
560
615
|
languageService.getReferencesAtPosition = (filePath, position) => {
|
|
561
616
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
562
|
-
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => getReferencesAtPosition(fileName, position), function* (result) {
|
|
617
|
+
const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, (fileName, position) => getReferencesAtPosition(fileName, position), function* (result) {
|
|
563
618
|
for (const ref of result) {
|
|
564
619
|
yield [ref.fileName, ref.textSpan.start];
|
|
565
620
|
}
|
|
566
621
|
});
|
|
567
622
|
const resolved = unresolved
|
|
568
623
|
.flat()
|
|
569
|
-
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
|
|
624
|
+
.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isReferencesEnabled))
|
|
570
625
|
.filter(utils_1.notEmpty);
|
|
571
626
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
572
627
|
};
|
|
573
628
|
languageService.getCompletionsAtPosition = (filePath, position, options, formattingSettings) => {
|
|
574
629
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
575
|
-
const [serviceScript, sourceScript
|
|
630
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
631
|
+
if (sourceScript?.associatedOnly) {
|
|
632
|
+
return undefined;
|
|
633
|
+
}
|
|
576
634
|
if (serviceScript) {
|
|
577
635
|
const results = [];
|
|
578
|
-
for (const [generatedOffset, mapping] of (0, transform_1.toGeneratedOffsets)(serviceScript, sourceScript,
|
|
579
|
-
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
const result = getCompletionsAtPosition(fileName, generatedOffset, options, formattingSettings);
|
|
636
|
+
for (const [generatedOffset, mapping] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, language_core_1.isCompletionEnabled)) {
|
|
637
|
+
const result = getCompletionsAtPosition(sourceScript.id, generatedOffset, options, formattingSettings);
|
|
583
638
|
if (!result) {
|
|
584
639
|
continue;
|
|
585
640
|
}
|
|
@@ -587,10 +642,10 @@ function decorateLanguageService(language, languageService) {
|
|
|
587
642
|
result.entries = result.entries.filter(entry => !!entry.sourceDisplay);
|
|
588
643
|
}
|
|
589
644
|
for (const entry of result.entries) {
|
|
590
|
-
entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(
|
|
645
|
+
entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, entry.replacementSpan, language_core_1.isCompletionEnabled)?.[1];
|
|
591
646
|
}
|
|
592
647
|
result.optionalReplacementSpan = result.optionalReplacementSpan
|
|
593
|
-
&& (0, transform_1.transformTextSpan)(
|
|
648
|
+
&& (0, transform_1.transformTextSpan)(sourceScript, language, serviceScript, result.optionalReplacementSpan, language_core_1.isCompletionEnabled)?.[1];
|
|
594
649
|
const isAdditional = typeof mapping.data.completion === 'object' && mapping.data.completion.isAdditional;
|
|
595
650
|
if (isAdditional) {
|
|
596
651
|
results.push(result);
|
|
@@ -615,11 +670,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
615
670
|
languageService.getCompletionEntryDetails = (filePath, position, entryName, formatOptions, source, preferences, data) => {
|
|
616
671
|
let details;
|
|
617
672
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
618
|
-
const [serviceScript, sourceScript
|
|
673
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
674
|
+
if (sourceScript?.associatedOnly) {
|
|
675
|
+
return undefined;
|
|
676
|
+
}
|
|
619
677
|
if (serviceScript) {
|
|
620
|
-
const generatePosition = (0, transform_1.toGeneratedOffset)(serviceScript, sourceScript,
|
|
678
|
+
const generatePosition = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, position, language_core_1.isCompletionEnabled);
|
|
621
679
|
if (generatePosition !== undefined) {
|
|
622
|
-
details = getCompletionEntryDetails(
|
|
680
|
+
details = getCompletionEntryDetails(sourceScript.id, generatePosition, entryName, formatOptions, source, preferences, data);
|
|
623
681
|
}
|
|
624
682
|
}
|
|
625
683
|
else {
|
|
@@ -627,17 +685,21 @@ function decorateLanguageService(language, languageService) {
|
|
|
627
685
|
}
|
|
628
686
|
if (details?.codeActions) {
|
|
629
687
|
for (const codeAction of details.codeActions) {
|
|
630
|
-
codeAction.changes =
|
|
688
|
+
codeAction.changes = (0, transform_1.transformFileTextChanges)(undefined, language, codeAction.changes, language_core_1.isCompletionEnabled);
|
|
631
689
|
}
|
|
632
690
|
}
|
|
633
691
|
return details;
|
|
634
692
|
};
|
|
635
693
|
languageService.provideInlayHints = (filePath, span, preferences) => {
|
|
636
694
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
637
|
-
const [serviceScript, sourceScript
|
|
695
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
696
|
+
if (sourceScript?.associatedOnly) {
|
|
697
|
+
return [];
|
|
698
|
+
}
|
|
638
699
|
if (serviceScript) {
|
|
639
700
|
let start;
|
|
640
701
|
let end;
|
|
702
|
+
const map = language.maps.get(serviceScript.code, sourceScript);
|
|
641
703
|
for (const mapping of map.mappings) {
|
|
642
704
|
if ((0, language_core_1.isInlayHintsEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
|
|
643
705
|
start ??= mapping.generatedOffsets[0];
|
|
@@ -650,17 +712,17 @@ function decorateLanguageService(language, languageService) {
|
|
|
650
712
|
start = 0;
|
|
651
713
|
end = 0;
|
|
652
714
|
}
|
|
653
|
-
const mappingOffset = (0, transform_1.getMappingOffset)(
|
|
715
|
+
const mappingOffset = (0, transform_1.getMappingOffset)(language, serviceScript);
|
|
654
716
|
start += mappingOffset;
|
|
655
717
|
end += mappingOffset;
|
|
656
|
-
const result = provideInlayHints(
|
|
718
|
+
const result = provideInlayHints(sourceScript.id, { start, length: end - start }, preferences);
|
|
657
719
|
const hints = [];
|
|
658
720
|
for (const hint of result) {
|
|
659
|
-
const sourcePosition = (0, transform_1.toSourceOffset)(
|
|
721
|
+
const sourcePosition = (0, transform_1.toSourceOffset)(sourceScript, language, serviceScript, hint.position, language_core_1.isInlayHintsEnabled);
|
|
660
722
|
if (sourcePosition !== undefined) {
|
|
661
723
|
hints.push({
|
|
662
724
|
...hint,
|
|
663
|
-
position: sourcePosition,
|
|
725
|
+
position: sourcePosition[1],
|
|
664
726
|
});
|
|
665
727
|
}
|
|
666
728
|
}
|
|
@@ -674,19 +736,17 @@ function decorateLanguageService(language, languageService) {
|
|
|
674
736
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
675
737
|
const unresolved = getFileReferences(fileName);
|
|
676
738
|
const resolved = unresolved
|
|
677
|
-
.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
|
|
739
|
+
.map(s => (0, transform_1.transformDocumentSpan)(undefined, language, s, language_core_1.isReferencesEnabled))
|
|
678
740
|
.filter(utils_1.notEmpty);
|
|
679
741
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
680
742
|
};
|
|
681
743
|
function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
|
|
682
744
|
const results = [];
|
|
683
745
|
const processedFilePositions = new Set();
|
|
684
|
-
const [serviceScript, sourceScript
|
|
746
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
685
747
|
if (serviceScript) {
|
|
686
|
-
for (const [generatedOffset
|
|
687
|
-
|
|
688
|
-
process(fileName, generatedOffset + (0, transform_1.getMappingOffset)(serviceScript, sourceScript));
|
|
689
|
-
}
|
|
748
|
+
for (const [generatedOffset] of (0, transform_1.toGeneratedOffsets)(language, serviceScript, sourceScript, position, filter)) {
|
|
749
|
+
process(sourceScript.id, generatedOffset);
|
|
690
750
|
}
|
|
691
751
|
}
|
|
692
752
|
else {
|
|
@@ -698,14 +758,14 @@ function decorateLanguageService(language, languageService) {
|
|
|
698
758
|
return;
|
|
699
759
|
}
|
|
700
760
|
processedFilePositions.add(fileName + ':' + position);
|
|
701
|
-
const result = worker(position);
|
|
761
|
+
const result = worker(fileName, position);
|
|
702
762
|
if (!result) {
|
|
703
763
|
return;
|
|
704
764
|
}
|
|
705
765
|
results.push(result);
|
|
706
766
|
for (const ref of getLinkedCodes(result)) {
|
|
707
767
|
processedFilePositions.add(ref[0] + ':' + ref[1]);
|
|
708
|
-
const [serviceScript
|
|
768
|
+
const [serviceScript] = (0, utils_1.getServiceScript)(language, ref[0]);
|
|
709
769
|
if (!serviceScript) {
|
|
710
770
|
continue;
|
|
711
771
|
}
|
|
@@ -713,7 +773,7 @@ function decorateLanguageService(language, languageService) {
|
|
|
713
773
|
if (!linkedCodeMap) {
|
|
714
774
|
continue;
|
|
715
775
|
}
|
|
716
|
-
const mappingOffset = (0, transform_1.getMappingOffset)(
|
|
776
|
+
const mappingOffset = (0, transform_1.getMappingOffset)(language, serviceScript);
|
|
717
777
|
for (const linkedCodeOffset of linkedCodeMap.getLinkedOffsets(ref[1] - mappingOffset)) {
|
|
718
778
|
process(ref[0], linkedCodeOffset + mappingOffset);
|
|
719
779
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.decorateProgram = void 0;
|
|
4
|
-
const utils_1 = require("./utils");
|
|
5
4
|
const transform_1 = require("./transform");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
6
|
function decorateProgram(language, program) {
|
|
7
7
|
const emit = program.emit;
|
|
8
8
|
// for tsc --noEmit
|
|
@@ -18,29 +18,44 @@ function decorateProgram(language, program) {
|
|
|
18
18
|
return {
|
|
19
19
|
...result,
|
|
20
20
|
diagnostics: result.diagnostics
|
|
21
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
21
|
+
.map(d => (0, transform_1.transformDiagnostic)(undefined, language, d, program, true))
|
|
22
22
|
.filter(utils_1.notEmpty),
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
program.getSyntacticDiagnostics = (sourceFile, cancellationToken) => {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
if (!sourceFile) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
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))
|
|
28
33
|
.filter(utils_1.notEmpty);
|
|
29
34
|
};
|
|
30
35
|
program.getSemanticDiagnostics = (sourceFile, cancellationToken) => {
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
if (!sourceFile) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
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))
|
|
33
43
|
.filter(utils_1.notEmpty);
|
|
34
44
|
};
|
|
35
45
|
program.getGlobalDiagnostics = cancellationToken => {
|
|
36
46
|
return getGlobalDiagnostics(cancellationToken)
|
|
37
|
-
.map(d => (0, transform_1.transformDiagnostic)(language, d, true))
|
|
47
|
+
.map(d => (0, transform_1.transformDiagnostic)(undefined, language, d, program, true))
|
|
38
48
|
.filter(utils_1.notEmpty);
|
|
39
49
|
};
|
|
40
50
|
// @ts-ignore
|
|
41
51
|
program.getBindAndCheckDiagnostics = (sourceFile, cancellationToken) => {
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
if (!sourceFile) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
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))
|
|
44
59
|
.filter(utils_1.notEmpty);
|
|
45
60
|
};
|
|
46
61
|
// fix https://github.com/vuejs/language-tools/issues/4099 with `incremental`
|
package/lib/node/transform.d.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import type { CodeInformation,
|
|
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(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, isTsc: boolean): T | undefined;
|
|
4
|
+
export declare function transformCallHierarchyItem(targetScript: SourceScript<string> | undefined, language: Language<string>, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem;
|
|
5
|
+
export declare function transformDiagnostic<T extends ts.Diagnostic>(targetScript: SourceScript<string> | undefined, 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(language: Language<string>, changes: 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): {
|
|
7
|
+
export declare function transformFileTextChanges(targetScript: SourceScript<string> | undefined, language: Language<string>, changes: readonly ts.FileTextChanges[], filter: (data: CodeInformation) => boolean): ts.FileTextChanges[];
|
|
8
|
+
export declare function transformDocumentSpan<T extends ts.DocumentSpan>(targetScript: SourceScript<string> | undefined, language: Language<string>, documentSpan: T, filter: (data: CodeInformation) => boolean, shouldFallback?: boolean): T | undefined;
|
|
9
|
+
export declare function transformSpan(targetScript: SourceScript<string> | undefined, 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
|
|
17
|
-
export declare function
|
|
18
|
-
export declare function
|
|
13
|
+
export declare function transformTextChange(targetScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, textChange: ts.TextChange, filter: (data: CodeInformation) => boolean): [string, ts.TextChange] | undefined;
|
|
14
|
+
export declare function transformTextSpan(targetScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, textSpan: ts.TextSpan, filter: (data: CodeInformation) => boolean): [string, ts.TextSpan] | undefined;
|
|
15
|
+
export declare function toSourceOffset(targetScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, position: number, filter: (data: CodeInformation) => boolean): [fileName: string, offset: number] | undefined;
|
|
16
|
+
export declare function toSourceOffsets(targetScript: SourceScript<string> | undefined, language: Language<string>, serviceScript: TypeScriptServiceScript, position: number, filter: (data: CodeInformation) => boolean): Generator<[fileName: string, offset: number]>;
|
|
17
|
+
export declare function toGeneratedOffset(language: Language, serviceScript: TypeScriptServiceScript, sourceScript: SourceScript<string>, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
|
|
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
|
+
export declare function getMappingOffset(language: Language, serviceScript: TypeScriptServiceScript): number;
|
package/lib/node/transform.js
CHANGED
|
@@ -1,41 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMappingOffset = exports.toGeneratedOffsets = exports.toGeneratedOffset = exports.toSourceOffset = exports.transformTextSpan = exports.transformTextChange = exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = exports.fillSourceFileText = exports.transformDiagnostic = exports.transformCallHierarchyItem = void 0;
|
|
3
|
+
exports.getMappingOffset = exports.toGeneratedOffsets = exports.toGeneratedOffset = exports.toSourceOffsets = 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();
|
|
7
7
|
const transformedSourceFile = new WeakSet();
|
|
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);
|
|
8
|
+
function transformCallHierarchyItem(targetScript, language, item, filter) {
|
|
9
|
+
const span = transformSpan(targetScript, language, item.file, item.span, filter);
|
|
10
|
+
const selectionSpan = transformSpan(targetScript, language, item.file, item.selectionSpan, filter);
|
|
11
11
|
return {
|
|
12
12
|
...item,
|
|
13
|
+
file: span?.fileName ?? item.file,
|
|
13
14
|
span: span?.textSpan ?? { start: 0, length: 0 },
|
|
14
15
|
selectionSpan: selectionSpan?.textSpan ?? { start: 0, length: 0 },
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
exports.transformCallHierarchyItem = transformCallHierarchyItem;
|
|
18
|
-
function transformDiagnostic(language, diagnostic, isTsc) {
|
|
19
|
+
function transformDiagnostic(targetScript, language, diagnostic, program, isTsc) {
|
|
19
20
|
if (!transformedDiagnostics.has(diagnostic)) {
|
|
20
21
|
transformedDiagnostics.set(diagnostic, undefined);
|
|
21
22
|
const { relatedInformation } = diagnostic;
|
|
22
23
|
if (relatedInformation) {
|
|
23
24
|
diagnostic.relatedInformation = relatedInformation
|
|
24
|
-
.map(d => transformDiagnostic(language, d, isTsc))
|
|
25
|
+
.map(d => transformDiagnostic(targetScript, language, d, program, isTsc))
|
|
25
26
|
.filter(utils_1.notEmpty);
|
|
26
27
|
}
|
|
27
28
|
if (diagnostic.file !== undefined
|
|
28
29
|
&& diagnostic.start !== undefined
|
|
29
30
|
&& diagnostic.length !== undefined) {
|
|
30
|
-
const [serviceScript, sourceScript
|
|
31
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, diagnostic.file.fileName);
|
|
31
32
|
if (serviceScript) {
|
|
32
|
-
const sourceSpan = transformTextSpan(
|
|
33
|
-
|
|
33
|
+
const [sourceSpanFileName, sourceSpan] = transformTextSpan(sourceScript, language, serviceScript, {
|
|
34
|
+
start: diagnostic.start,
|
|
35
|
+
length: diagnostic.length
|
|
36
|
+
}, language_core_1.shouldReportDiagnostics) ?? [];
|
|
37
|
+
const actualDiagnosticFile = sourceSpanFileName
|
|
38
|
+
? diagnostic.file.fileName === sourceSpanFileName
|
|
39
|
+
? diagnostic.file
|
|
40
|
+
: program?.getSourceFile(sourceSpanFileName)
|
|
41
|
+
: undefined;
|
|
42
|
+
if (sourceSpan && actualDiagnosticFile) {
|
|
34
43
|
if (isTsc) {
|
|
35
44
|
fillSourceFileText(language, diagnostic.file);
|
|
36
45
|
}
|
|
37
46
|
transformedDiagnostics.set(diagnostic, {
|
|
38
47
|
...diagnostic,
|
|
48
|
+
file: actualDiagnosticFile,
|
|
39
49
|
start: sourceSpan.start,
|
|
40
50
|
length: sourceSpan.length,
|
|
41
51
|
});
|
|
@@ -65,29 +75,42 @@ function fillSourceFileText(language, sourceFile) {
|
|
|
65
75
|
}
|
|
66
76
|
}
|
|
67
77
|
exports.fillSourceFileText = fillSourceFileText;
|
|
68
|
-
function transformFileTextChanges(language, changes, filter) {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
span: span.textSpan,
|
|
79
|
-
};
|
|
78
|
+
function transformFileTextChanges(targetScript, language, changes, filter) {
|
|
79
|
+
const changesPerFile = {};
|
|
80
|
+
const newFiles = new Set();
|
|
81
|
+
for (const fileChanges of changes) {
|
|
82
|
+
const [_, source] = (0, utils_1.getServiceScript)(language, fileChanges.fileName);
|
|
83
|
+
if (source) {
|
|
84
|
+
fileChanges.textChanges.forEach(c => {
|
|
85
|
+
const { fileName, textSpan } = transformSpan(targetScript, language, fileChanges.fileName, c.span, filter) ?? {};
|
|
86
|
+
if (fileName && textSpan) {
|
|
87
|
+
(changesPerFile[fileName] ?? (changesPerFile[fileName] = [])).push({ ...c, span: textSpan });
|
|
80
88
|
}
|
|
81
|
-
})
|
|
82
|
-
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const list = (changesPerFile[fileChanges.fileName] ?? (changesPerFile[fileChanges.fileName] = []));
|
|
93
|
+
fileChanges.textChanges.forEach(c => {
|
|
94
|
+
list.push(c);
|
|
95
|
+
});
|
|
96
|
+
if (fileChanges.isNewFile) {
|
|
97
|
+
newFiles.add(fileChanges.fileName);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
83
100
|
}
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
const result = [];
|
|
102
|
+
for (const fileName in changesPerFile) {
|
|
103
|
+
result.push({
|
|
104
|
+
fileName,
|
|
105
|
+
isNewFile: newFiles.has(fileName),
|
|
106
|
+
textChanges: changesPerFile[fileName]
|
|
107
|
+
});
|
|
86
108
|
}
|
|
109
|
+
return result;
|
|
87
110
|
}
|
|
88
111
|
exports.transformFileTextChanges = transformFileTextChanges;
|
|
89
|
-
function transformDocumentSpan(language, documentSpan, filter, shouldFallback) {
|
|
90
|
-
let textSpan = transformSpan(language, documentSpan.fileName, documentSpan.textSpan, filter);
|
|
112
|
+
function transformDocumentSpan(targetScript, language, documentSpan, filter, shouldFallback) {
|
|
113
|
+
let textSpan = transformSpan(targetScript, language, documentSpan.fileName, documentSpan.textSpan, filter);
|
|
91
114
|
if (!textSpan && shouldFallback) {
|
|
92
115
|
textSpan = {
|
|
93
116
|
fileName: documentSpan.fileName,
|
|
@@ -97,9 +120,9 @@ function transformDocumentSpan(language, documentSpan, filter, shouldFallback) {
|
|
|
97
120
|
if (!textSpan) {
|
|
98
121
|
return;
|
|
99
122
|
}
|
|
100
|
-
const contextSpan = transformSpan(language, documentSpan.fileName, documentSpan.contextSpan, filter);
|
|
101
|
-
const originalTextSpan = transformSpan(language, documentSpan.originalFileName, documentSpan.originalTextSpan, filter);
|
|
102
|
-
const originalContextSpan = transformSpan(language, documentSpan.originalFileName, documentSpan.originalContextSpan, filter);
|
|
123
|
+
const contextSpan = transformSpan(targetScript, language, documentSpan.fileName, documentSpan.contextSpan, filter);
|
|
124
|
+
const originalTextSpan = transformSpan(targetScript, language, documentSpan.originalFileName, documentSpan.originalTextSpan, filter);
|
|
125
|
+
const originalContextSpan = transformSpan(targetScript, language, documentSpan.originalFileName, documentSpan.originalContextSpan, filter);
|
|
103
126
|
return {
|
|
104
127
|
...documentSpan,
|
|
105
128
|
fileName: textSpan.fileName,
|
|
@@ -111,16 +134,19 @@ function transformDocumentSpan(language, documentSpan, filter, shouldFallback) {
|
|
|
111
134
|
};
|
|
112
135
|
}
|
|
113
136
|
exports.transformDocumentSpan = transformDocumentSpan;
|
|
114
|
-
function transformSpan(language, fileName, textSpan, filter) {
|
|
137
|
+
function transformSpan(targetScript, language, fileName, textSpan, filter) {
|
|
115
138
|
if (!fileName || !textSpan) {
|
|
116
139
|
return;
|
|
117
140
|
}
|
|
118
|
-
const [serviceScript, sourceScript
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
141
|
+
const [serviceScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
142
|
+
if (sourceScript?.associatedOnly) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
else if (serviceScript) {
|
|
146
|
+
const [sourceSpanFileName, sourceSpan] = transformTextSpan(targetScript, language, serviceScript, textSpan, filter) ?? [];
|
|
147
|
+
if (sourceSpan && sourceSpanFileName) {
|
|
122
148
|
return {
|
|
123
|
-
fileName,
|
|
149
|
+
fileName: sourceSpanFileName,
|
|
124
150
|
textSpan: sourceSpan,
|
|
125
151
|
};
|
|
126
152
|
}
|
|
@@ -133,55 +159,80 @@ function transformSpan(language, fileName, textSpan, filter) {
|
|
|
133
159
|
}
|
|
134
160
|
}
|
|
135
161
|
exports.transformSpan = transformSpan;
|
|
136
|
-
function transformTextChange(
|
|
137
|
-
const sourceSpan = transformTextSpan(
|
|
138
|
-
if (sourceSpan) {
|
|
139
|
-
return {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
162
|
+
function transformTextChange(targetScript, language, serviceScript, textChange, filter) {
|
|
163
|
+
const [sourceSpanFileName, sourceSpan] = transformTextSpan(targetScript, language, serviceScript, textChange.span, filter) ?? [];
|
|
164
|
+
if (sourceSpan && sourceSpanFileName) {
|
|
165
|
+
return [sourceSpanFileName, {
|
|
166
|
+
newText: textChange.newText,
|
|
167
|
+
span: sourceSpan,
|
|
168
|
+
}];
|
|
143
169
|
}
|
|
170
|
+
return undefined;
|
|
144
171
|
}
|
|
145
172
|
exports.transformTextChange = transformTextChange;
|
|
146
|
-
function transformTextSpan(
|
|
173
|
+
function transformTextSpan(targetScript, language, serviceScript, textSpan, filter) {
|
|
147
174
|
const start = textSpan.start;
|
|
148
175
|
const end = textSpan.start + textSpan.length;
|
|
149
|
-
const sourceStart
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
176
|
+
for (const sourceStart of toSourceOffsets(targetScript, language, serviceScript, start, filter)) {
|
|
177
|
+
for (const sourceEnd of toSourceOffsets(targetScript, language, serviceScript, end, filter)) {
|
|
178
|
+
if (sourceStart[0] === sourceEnd[0]
|
|
179
|
+
&& sourceEnd[1] >= sourceStart[1]) {
|
|
180
|
+
return [sourceStart[0], {
|
|
181
|
+
start: sourceStart[1],
|
|
182
|
+
length: sourceEnd[1] - sourceStart[1],
|
|
183
|
+
}];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
156
186
|
}
|
|
157
187
|
}
|
|
158
188
|
exports.transformTextSpan = transformTextSpan;
|
|
159
|
-
function toSourceOffset(
|
|
160
|
-
for (const
|
|
161
|
-
|
|
162
|
-
return sourceOffset;
|
|
163
|
-
}
|
|
189
|
+
function toSourceOffset(targetScript, language, serviceScript, position, filter) {
|
|
190
|
+
for (const source of toSourceOffsets(targetScript, language, serviceScript, position, filter)) {
|
|
191
|
+
return source;
|
|
164
192
|
}
|
|
165
193
|
}
|
|
166
194
|
exports.toSourceOffset = toSourceOffset;
|
|
167
|
-
function
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
195
|
+
function* toSourceOffsets(targetScript, language, serviceScript, position, filter) {
|
|
196
|
+
if (targetScript) {
|
|
197
|
+
const map = language.maps.get(serviceScript.code, targetScript);
|
|
198
|
+
for (const [sourceOffset, mapping] of map.getSourceOffsets(position - getMappingOffset(language, serviceScript))) {
|
|
199
|
+
if (filter(mapping.data)) {
|
|
200
|
+
yield [targetScript.id, sourceOffset];
|
|
201
|
+
}
|
|
171
202
|
}
|
|
172
203
|
}
|
|
204
|
+
else {
|
|
205
|
+
for (const [fileName, _snapshot, map] of language.maps.forEach(serviceScript.code)) {
|
|
206
|
+
for (const [sourceOffset, mapping] of map.getSourceOffsets(position - getMappingOffset(language, serviceScript))) {
|
|
207
|
+
if (filter(mapping.data)) {
|
|
208
|
+
yield [fileName, sourceOffset];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.toSourceOffsets = toSourceOffsets;
|
|
215
|
+
function toGeneratedOffset(language, serviceScript, sourceScript, position, filter) {
|
|
216
|
+
for (const [generateOffset] of toGeneratedOffsets(language, serviceScript, sourceScript, position, filter)) {
|
|
217
|
+
return generateOffset;
|
|
218
|
+
}
|
|
173
219
|
}
|
|
174
220
|
exports.toGeneratedOffset = toGeneratedOffset;
|
|
175
|
-
function* toGeneratedOffsets(serviceScript, sourceScript,
|
|
221
|
+
function* toGeneratedOffsets(language, serviceScript, sourceScript, position, filter) {
|
|
222
|
+
const map = language.maps.get(serviceScript.code, sourceScript);
|
|
176
223
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
177
|
-
|
|
224
|
+
if (filter(mapping.data)) {
|
|
225
|
+
yield [generateOffset + getMappingOffset(language, serviceScript), mapping];
|
|
226
|
+
}
|
|
178
227
|
}
|
|
179
228
|
}
|
|
180
229
|
exports.toGeneratedOffsets = toGeneratedOffsets;
|
|
181
|
-
function getMappingOffset(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
230
|
+
function getMappingOffset(language, serviceScript) {
|
|
231
|
+
if (serviceScript.preventLeadingOffset) {
|
|
232
|
+
return 0;
|
|
233
|
+
}
|
|
234
|
+
const sourceScript = language.scripts.fromVirtualCode(serviceScript.code);
|
|
235
|
+
return sourceScript.snapshot.getLength();
|
|
185
236
|
}
|
|
186
237
|
exports.getMappingOffset = getMappingOffset;
|
|
187
238
|
//# sourceMappingURL=transform.js.map
|
package/lib/node/utils.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { Language } from '@volar/language-core';
|
|
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):
|
|
3
|
+
export declare function getServiceScript(language: Language<string>, fileName: string): [TypeScriptServiceScript, SourceScript<string>] | [undefined, SourceScript<string>] | [undefined, undefined];
|
package/lib/node/utils.js
CHANGED
|
@@ -7,16 +7,27 @@ function notEmpty(value) {
|
|
|
7
7
|
exports.notEmpty = notEmpty;
|
|
8
8
|
function getServiceScript(language, fileName) {
|
|
9
9
|
const sourceScript = language.scripts.get(fileName);
|
|
10
|
+
if (sourceScript?.targetIds.size) {
|
|
11
|
+
for (const targetId of sourceScript.targetIds) {
|
|
12
|
+
const targetScript = language.scripts.get(targetId);
|
|
13
|
+
if (targetScript?.generated) {
|
|
14
|
+
const serviceScript = targetScript.generated.languagePlugin.typescript?.getServiceScript(targetScript.generated.root);
|
|
15
|
+
if (serviceScript) {
|
|
16
|
+
return [serviceScript, targetScript];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (sourceScript?.associatedOnly) {
|
|
22
|
+
return [undefined, sourceScript];
|
|
23
|
+
}
|
|
10
24
|
if (sourceScript?.generated) {
|
|
11
25
|
const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
|
|
12
26
|
if (serviceScript) {
|
|
13
|
-
|
|
14
|
-
if (map) {
|
|
15
|
-
return [serviceScript, sourceScript, map];
|
|
16
|
-
}
|
|
27
|
+
return [serviceScript, sourceScript];
|
|
17
28
|
}
|
|
18
29
|
}
|
|
19
|
-
return [undefined, undefined
|
|
30
|
+
return [undefined, undefined];
|
|
20
31
|
}
|
|
21
32
|
exports.getServiceScript = getServiceScript;
|
|
22
33
|
//# sourceMappingURL=utils.js.map
|
|
@@ -83,7 +83,7 @@ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePl
|
|
|
83
83
|
if (updateLevel >= (1)
|
|
84
84
|
|| !externalFiles.has(project)) {
|
|
85
85
|
const oldFiles = externalFiles.get(project);
|
|
86
|
-
const newFiles = (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, extensions);
|
|
86
|
+
const newFiles = extensions.length ? (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, extensions) : [];
|
|
87
87
|
externalFiles.set(project, newFiles);
|
|
88
88
|
if (oldFiles && !(0, createLanguageServicePlugin_1.arrayItemsEqual)(oldFiles, newFiles)) {
|
|
89
89
|
project.refreshDiagnostics();
|
|
@@ -52,7 +52,8 @@ function createLanguageServicePlugin(loadLanguagePlugins) {
|
|
|
52
52
|
if (updateLevel >= (1)
|
|
53
53
|
|| !externalFiles.has(project)) {
|
|
54
54
|
const oldFiles = externalFiles.get(project);
|
|
55
|
-
const
|
|
55
|
+
const extensions = projectExternalFileExtensions.get(project);
|
|
56
|
+
const newFiles = extensions?.length ? (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, extensions) : [];
|
|
56
57
|
externalFiles.set(project, newFiles);
|
|
57
58
|
if (oldFiles && !arrayItemsEqual(oldFiles, newFiles)) {
|
|
58
59
|
project.refreshDiagnostics();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volar/typescript",
|
|
3
|
-
"version": "2.3.0-alpha.
|
|
3
|
+
"version": "2.3.0-alpha.9",
|
|
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-alpha.
|
|
15
|
+
"@volar/language-core": "2.3.0-alpha.9",
|
|
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-alpha.
|
|
22
|
+
"@volar/language-service": "2.3.0-alpha.9"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "3f741930343896dfc464a893ebe5f3619bb1a1aa"
|
|
25
25
|
}
|