@volar/typescript 1.11.1 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,662 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateLanguageService = void 0;
4
+ const language_core_1 = require("@volar/language-core");
5
+ const dedupe_1 = require("./dedupe");
6
+ function decorateLanguageService(virtualFiles, languageService, isTsPlugin) {
7
+ const transformedDiagnostics = new WeakMap();
8
+ const { findReferences, findRenameLocations, getCompletionEntryDetails, getCompletionsAtPosition, getDefinitionAndBoundSpan, getDefinitionAtPosition, getFileReferences, getImplementationAtPosition, getQuickInfoAtPosition, getReferencesAtPosition, getSemanticDiagnostics, getSyntacticDiagnostics, getSuggestionDiagnostics, getTypeDefinitionAtPosition, getEncodedSemanticClassifications, getDocumentHighlights, getApplicableRefactors, getEditsForRefactor, getRenameInfo, getCodeFixesAtPosition, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, organizeImports, } = languageService;
9
+ languageService.prepareCallHierarchy = (fileName, position) => {
10
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
11
+ if (virtualFile) {
12
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
13
+ if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
14
+ const item = prepareCallHierarchy(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0));
15
+ if (Array.isArray(item)) {
16
+ return item.map(item => transformCallHierarchyItem(item, language_core_1.isCallHierarchyEnabled));
17
+ }
18
+ else if (item) {
19
+ return transformCallHierarchyItem(item, language_core_1.isCallHierarchyEnabled);
20
+ }
21
+ }
22
+ }
23
+ }
24
+ else {
25
+ return prepareCallHierarchy(fileName, position);
26
+ }
27
+ };
28
+ languageService.provideCallHierarchyIncomingCalls = (fileName, position) => {
29
+ let calls = [];
30
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
31
+ if (virtualFile) {
32
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
33
+ if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
34
+ calls = provideCallHierarchyIncomingCalls(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0));
35
+ }
36
+ }
37
+ }
38
+ else {
39
+ calls = provideCallHierarchyIncomingCalls(fileName, position);
40
+ }
41
+ return calls
42
+ .map(call => {
43
+ const from = transformCallHierarchyItem(call.from, language_core_1.isCallHierarchyEnabled);
44
+ const fromSpans = call.fromSpans
45
+ .map(span => transformSpan(call.from.file, span, language_core_1.isCallHierarchyEnabled)?.textSpan)
46
+ .filter(notEmpty);
47
+ return {
48
+ from,
49
+ fromSpans,
50
+ };
51
+ });
52
+ };
53
+ languageService.provideCallHierarchyOutgoingCalls = (fileName, position) => {
54
+ let calls = [];
55
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
56
+ if (virtualFile) {
57
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
58
+ if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
59
+ calls = provideCallHierarchyOutgoingCalls(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0));
60
+ }
61
+ }
62
+ }
63
+ else {
64
+ calls = provideCallHierarchyOutgoingCalls(fileName, position);
65
+ }
66
+ return calls
67
+ .map(call => {
68
+ const to = transformCallHierarchyItem(call.to, language_core_1.isCallHierarchyEnabled);
69
+ const fromSpans = call.fromSpans
70
+ .map(span => transformSpan(fileName, span, language_core_1.isCallHierarchyEnabled)?.textSpan)
71
+ .filter(notEmpty);
72
+ return {
73
+ to,
74
+ fromSpans,
75
+ };
76
+ });
77
+ };
78
+ languageService.organizeImports = (args, formatOptions, preferences) => {
79
+ const unresolved = organizeImports(args, formatOptions, preferences);
80
+ const resolved = unresolved
81
+ .map(changes => transformFileTextChanges(changes, language_core_1.isCodeActionsEnabled))
82
+ .filter(notEmpty);
83
+ return resolved;
84
+ };
85
+ languageService.getQuickInfoAtPosition = (fileName, position) => {
86
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
87
+ if (virtualFile) {
88
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
89
+ if ((0, language_core_1.isHoverEnabled)(mapping.data)) {
90
+ const result = getQuickInfoAtPosition(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0));
91
+ if (result) {
92
+ const textSpan = transformSpan(fileName, result.textSpan, language_core_1.isHoverEnabled)?.textSpan;
93
+ if (textSpan) {
94
+ return {
95
+ ...result,
96
+ textSpan,
97
+ };
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ return getQuickInfoAtPosition(fileName, position);
105
+ }
106
+ };
107
+ languageService.getDocumentHighlights = (fileName, position, filesToSearch) => {
108
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isHighlightEnabled, position => getDocumentHighlights(fileName, position, filesToSearch), function* (result) {
109
+ for (const ref of result) {
110
+ for (const reference of ref.highlightSpans) {
111
+ yield [reference.fileName ?? ref.fileName, reference.textSpan.start];
112
+ }
113
+ }
114
+ });
115
+ const resolved = unresolved
116
+ .flat()
117
+ .map(highlights => {
118
+ return {
119
+ ...highlights,
120
+ highlightSpans: highlights.highlightSpans
121
+ .map(span => {
122
+ const textSpan = transformSpan(span.fileName ?? highlights.fileName, span.textSpan, language_core_1.isHighlightEnabled)?.textSpan;
123
+ if (textSpan) {
124
+ return {
125
+ ...span,
126
+ contextSpan: transformSpan(span.fileName ?? highlights.fileName, span.contextSpan, language_core_1.isHighlightEnabled)?.textSpan,
127
+ textSpan,
128
+ };
129
+ }
130
+ })
131
+ .filter(notEmpty),
132
+ };
133
+ });
134
+ return resolved;
135
+ };
136
+ languageService.getApplicableRefactors = (fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
137
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
138
+ if (virtualFile) {
139
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos)) {
140
+ if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
141
+ const por = typeof positionOrRange === 'number'
142
+ ? generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0)
143
+ : {
144
+ pos: generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0),
145
+ end: generateOffset + positionOrRange.end - positionOrRange.pos + (isTsPlugin ? sourceFile.snapshot.getLength() : 0),
146
+ };
147
+ return getApplicableRefactors(fileName, por, preferences, triggerReason, kind, includeInteractiveActions);
148
+ }
149
+ }
150
+ return [];
151
+ }
152
+ else {
153
+ return getApplicableRefactors(fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions);
154
+ }
155
+ };
156
+ languageService.getEditsForRefactor = (fileName, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
157
+ let edits;
158
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
159
+ if (virtualFile) {
160
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos)) {
161
+ if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
162
+ const por = typeof positionOrRange === 'number'
163
+ ? generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0)
164
+ : {
165
+ pos: generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0),
166
+ end: generateOffset + positionOrRange.end - positionOrRange.pos + (isTsPlugin ? sourceFile.snapshot.getLength() : 0),
167
+ };
168
+ edits = getEditsForRefactor(fileName, formatOptions, por, refactorName, actionName, preferences);
169
+ }
170
+ }
171
+ }
172
+ else {
173
+ edits = getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName, preferences);
174
+ }
175
+ if (edits) {
176
+ edits.edits = edits.edits
177
+ .map(edit => transformFileTextChanges(edit, language_core_1.isCodeActionsEnabled))
178
+ .filter(notEmpty);
179
+ return edits;
180
+ }
181
+ };
182
+ languageService.getRenameInfo = (fileName, position, options) => {
183
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
184
+ if (virtualFile) {
185
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
186
+ if ((0, language_core_1.isRenameEnabled)(mapping.data)) {
187
+ const info = getRenameInfo(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0), options);
188
+ if (info.canRename) {
189
+ const span = transformSpan(fileName, info.triggerSpan, language_core_1.isRenameEnabled);
190
+ if (span) {
191
+ info.triggerSpan = span.textSpan;
192
+ return info;
193
+ }
194
+ }
195
+ else {
196
+ return info;
197
+ }
198
+ }
199
+ }
200
+ return {
201
+ canRename: false,
202
+ localizedErrorMessage: 'Failed to get rename locations',
203
+ };
204
+ }
205
+ else {
206
+ return getRenameInfo(fileName, position, options);
207
+ }
208
+ };
209
+ languageService.getCodeFixesAtPosition = (fileName, start, end, errorCodes, formatOptions, preferences) => {
210
+ let fixes = [];
211
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
212
+ if (virtualFile) {
213
+ for (const [generateStart, mapping] of map.getGeneratedOffsets(start)) {
214
+ if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
215
+ for (const [generateEnd, mapping] of map.getGeneratedOffsets(end)) {
216
+ if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
217
+ fixes = getCodeFixesAtPosition(fileName, generateStart + (isTsPlugin ? sourceFile.snapshot.getLength() : 0), generateEnd + (isTsPlugin ? sourceFile.snapshot.getLength() : 0), errorCodes, formatOptions, preferences);
218
+ break;
219
+ }
220
+ }
221
+ break;
222
+ }
223
+ }
224
+ }
225
+ else {
226
+ fixes = getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences);
227
+ }
228
+ fixes = fixes.map(fix => {
229
+ fix.changes = fix.changes.map(edit => transformFileTextChanges(edit, language_core_1.isCodeActionsEnabled)).filter(notEmpty);
230
+ return fix;
231
+ });
232
+ return fixes;
233
+ };
234
+ languageService.getEncodedSemanticClassifications = (fileName, span, format) => {
235
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
236
+ if (virtualFile) {
237
+ let start;
238
+ let end;
239
+ for (const mapping of map.mappings) {
240
+ if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
241
+ start ??= mapping.generatedOffsets[0];
242
+ end ??= mapping.generatedOffsets[mapping.generatedOffsets.length - 1];
243
+ start = Math.min(start, mapping.generatedOffsets[0]);
244
+ end = Math.max(end, mapping.generatedOffsets[mapping.generatedOffsets.length - 1]);
245
+ }
246
+ }
247
+ if (start === undefined || end === undefined) {
248
+ start = 0;
249
+ end = 0;
250
+ }
251
+ if (isTsPlugin) {
252
+ start += sourceFile.snapshot.getLength();
253
+ end += sourceFile.snapshot.getLength();
254
+ }
255
+ const result = getEncodedSemanticClassifications(fileName, { start, length: end - start }, format);
256
+ const spans = [];
257
+ for (let i = 0; i < result.spans.length; i += 3) {
258
+ for (const [sourceStart, mapping] of map.getSourceOffsets(result.spans[i] - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
259
+ if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data)) {
260
+ for (const [sourceEnd, mapping] of map.getSourceOffsets(result.spans[i] + result.spans[i + 1] - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
261
+ if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data)) {
262
+ spans.push(sourceStart, sourceEnd - sourceStart, result.spans[i + 2]);
263
+ break;
264
+ }
265
+ }
266
+ break;
267
+ }
268
+ }
269
+ }
270
+ result.spans = spans;
271
+ return result;
272
+ }
273
+ else {
274
+ return getEncodedSemanticClassifications(fileName, span);
275
+ }
276
+ };
277
+ languageService.getSyntacticDiagnostics = (fileName) => {
278
+ return getSyntacticDiagnostics(fileName)
279
+ .map(diagnostic => transformDiagnostic(diagnostic))
280
+ .filter(notEmpty);
281
+ };
282
+ languageService.getSemanticDiagnostics = (fileName) => {
283
+ return getSemanticDiagnostics(fileName)
284
+ .map(diagnostic => transformDiagnostic(diagnostic))
285
+ .filter(notEmpty);
286
+ };
287
+ languageService.getSuggestionDiagnostics = (fileName) => {
288
+ return getSuggestionDiagnostics(fileName)
289
+ .map(diagnostic => transformDiagnostic(diagnostic))
290
+ .filter(notEmpty);
291
+ };
292
+ languageService.getDefinitionAndBoundSpan = (fileName, position) => {
293
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAndBoundSpan(fileName, position), function* (result) {
294
+ for (const ref of result.definitions ?? []) {
295
+ yield [ref.fileName, ref.textSpan.start];
296
+ }
297
+ });
298
+ const textSpan = unresolved
299
+ .map(s => transformSpan(fileName, s.textSpan, language_core_1.isDefinitionEnabled)?.textSpan)
300
+ .filter(notEmpty)[0];
301
+ if (!textSpan)
302
+ return;
303
+ const definitions = unresolved
304
+ .map(s => s.definitions
305
+ ?.map(s => transformDocumentSpan(s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
306
+ .filter(notEmpty))
307
+ .filter(notEmpty)
308
+ .flat();
309
+ return {
310
+ textSpan,
311
+ definitions: (0, dedupe_1.dedupeDocumentSpans)(definitions),
312
+ };
313
+ };
314
+ languageService.findReferences = (fileName, position) => {
315
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => findReferences(fileName, position), function* (result) {
316
+ for (const ref of result) {
317
+ for (const reference of ref.references) {
318
+ yield [reference.fileName, reference.textSpan.start];
319
+ }
320
+ }
321
+ });
322
+ const resolved = unresolved
323
+ .flat()
324
+ .map(symbol => {
325
+ const definition = transformDocumentSpan(symbol.definition, language_core_1.isDefinitionEnabled);
326
+ if (definition) {
327
+ return {
328
+ definition,
329
+ references: symbol.references
330
+ .map(r => transformDocumentSpan(r, language_core_1.isReferencesEnabled))
331
+ .filter(notEmpty),
332
+ };
333
+ }
334
+ })
335
+ .filter(notEmpty);
336
+ return (0, dedupe_1.dedupeReferencedSymbols)(resolved);
337
+ };
338
+ languageService.getDefinitionAtPosition = (fileName, position) => {
339
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAtPosition(fileName, position), function* (result) {
340
+ for (const ref of result) {
341
+ yield [ref.fileName, ref.textSpan.start];
342
+ }
343
+ });
344
+ const resolved = unresolved
345
+ .flat()
346
+ .map(s => transformDocumentSpan(s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
347
+ .filter(notEmpty);
348
+ return (0, dedupe_1.dedupeDocumentSpans)(resolved);
349
+ };
350
+ languageService.getTypeDefinitionAtPosition = (fileName, position) => {
351
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, position => getTypeDefinitionAtPosition(fileName, position), function* (result) {
352
+ for (const ref of result) {
353
+ yield [ref.fileName, ref.textSpan.start];
354
+ }
355
+ });
356
+ const resolved = unresolved
357
+ .flat()
358
+ .map(s => transformDocumentSpan(s, language_core_1.isTypeDefinitionEnabled))
359
+ .filter(notEmpty);
360
+ return (0, dedupe_1.dedupeDocumentSpans)(resolved);
361
+ };
362
+ languageService.getImplementationAtPosition = (fileName, position) => {
363
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, position => getImplementationAtPosition(fileName, position), function* (result) {
364
+ for (const ref of result) {
365
+ yield [ref.fileName, ref.textSpan.start];
366
+ }
367
+ });
368
+ const resolved = unresolved
369
+ .flat()
370
+ .map(s => transformDocumentSpan(s, language_core_1.isImplementationEnabled))
371
+ .filter(notEmpty);
372
+ return (0, dedupe_1.dedupeDocumentSpans)(resolved);
373
+ };
374
+ languageService.findRenameLocations = (fileName, position, findInStrings, findInComments, preferences) => {
375
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, position => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) {
376
+ for (const ref of result) {
377
+ yield [ref.fileName, ref.textSpan.start];
378
+ }
379
+ });
380
+ const resolved = unresolved
381
+ .flat()
382
+ .map(s => transformDocumentSpan(s, language_core_1.isRenameEnabled))
383
+ .filter(notEmpty);
384
+ return (0, dedupe_1.dedupeDocumentSpans)(resolved);
385
+ };
386
+ languageService.getReferencesAtPosition = (fileName, position) => {
387
+ const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => getReferencesAtPosition(fileName, position), function* (result) {
388
+ for (const ref of result) {
389
+ yield [ref.fileName, ref.textSpan.start];
390
+ }
391
+ });
392
+ const resolved = unresolved
393
+ .flat()
394
+ .map(s => transformDocumentSpan(s, language_core_1.isReferencesEnabled))
395
+ .filter(notEmpty);
396
+ return (0, dedupe_1.dedupeDocumentSpans)(resolved);
397
+ };
398
+ languageService.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
399
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
400
+ if (virtualFile) {
401
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
402
+ if ((0, language_core_1.isCompletionEnabled)(mapping.data)) {
403
+ const result = getCompletionsAtPosition(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0), options, formattingSettings);
404
+ if (result) {
405
+ for (const entry of result.entries) {
406
+ entry.replacementSpan = transformSpan(fileName, entry.replacementSpan, language_core_1.isCompletionEnabled)?.textSpan;
407
+ }
408
+ result.optionalReplacementSpan = transformSpan(fileName, result.optionalReplacementSpan, language_core_1.isCompletionEnabled)?.textSpan;
409
+ }
410
+ return result;
411
+ }
412
+ }
413
+ }
414
+ else {
415
+ return getCompletionsAtPosition(fileName, position, options, formattingSettings);
416
+ }
417
+ };
418
+ languageService.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
419
+ const details = getCompletionEntryDetails(fileName, position, entryName, formatOptions, source, preferences, data);
420
+ if (details?.codeActions) {
421
+ for (const codeAction of details.codeActions) {
422
+ codeAction.changes = codeAction.changes.map(edit => transformFileTextChanges(edit, language_core_1.isCodeLensEnabled)).filter(notEmpty);
423
+ }
424
+ }
425
+ return details;
426
+ };
427
+ languageService.provideInlayHints = (fileName, span, preferences) => {
428
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
429
+ if (virtualFile) {
430
+ let start;
431
+ let end;
432
+ for (const mapping of map.mappings) {
433
+ if ((0, language_core_1.isInlayHintsEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
434
+ start ??= mapping.generatedOffsets[0];
435
+ end ??= mapping.generatedOffsets[mapping.generatedOffsets.length - 1];
436
+ start = Math.min(start, mapping.generatedOffsets[0]);
437
+ end = Math.max(end, mapping.generatedOffsets[mapping.generatedOffsets.length - 1]);
438
+ }
439
+ }
440
+ if (start === undefined || end === undefined) {
441
+ start = 0;
442
+ end = 0;
443
+ }
444
+ if (isTsPlugin) {
445
+ start += sourceFile.snapshot.getLength();
446
+ end += sourceFile.snapshot.getLength();
447
+ }
448
+ const result = provideInlayHints(fileName, { start, length: end - start }, preferences);
449
+ const hints = [];
450
+ for (const hint of result) {
451
+ for (const [sourcePosition, mapping] of map.getSourceOffsets(hint.position - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
452
+ if ((0, language_core_1.isInlayHintsEnabled)(mapping.data)) {
453
+ hints.push({
454
+ ...hint,
455
+ position: sourcePosition,
456
+ });
457
+ break;
458
+ }
459
+ }
460
+ }
461
+ return hints;
462
+ }
463
+ else {
464
+ return provideInlayHints(fileName, span, preferences);
465
+ }
466
+ };
467
+ languageService.getFileReferences = (fileName) => {
468
+ const unresolved = getFileReferences(fileName);
469
+ const resolved = unresolved
470
+ .map(s => transformDocumentSpan(s, language_core_1.isReferencesEnabled))
471
+ .filter(notEmpty);
472
+ return (0, dedupe_1.dedupeDocumentSpans)(resolved);
473
+ };
474
+ function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
475
+ let results = [];
476
+ const processedFilePositions = new Set();
477
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
478
+ if (virtualFile) {
479
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
480
+ if (filter(mapping.data)) {
481
+ process(fileName, generateOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0));
482
+ }
483
+ }
484
+ }
485
+ else {
486
+ process(fileName, position);
487
+ }
488
+ return results;
489
+ function process(fileName, position) {
490
+ if (processedFilePositions.has(fileName + ':' + position))
491
+ return;
492
+ processedFilePositions.add(fileName + ':' + position);
493
+ const result = worker(position);
494
+ if (!result)
495
+ return;
496
+ results = results.concat(result);
497
+ for (const ref of getLinkedCodes(result)) {
498
+ processedFilePositions.add(ref[0] + ':' + ref[1]);
499
+ const [virtualFile, sourceFile] = getVirtualFileAndMap(ref[0]);
500
+ if (!virtualFile)
501
+ continue;
502
+ const linkedCodeMap = virtualFiles.getLinkedCodeMap(virtualFile);
503
+ if (!linkedCodeMap)
504
+ continue;
505
+ for (const linkedCodeOffset of linkedCodeMap.getLinkedOffsets(ref[1] - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
506
+ process(ref[0], linkedCodeOffset + (isTsPlugin ? sourceFile.snapshot.getLength() : 0));
507
+ }
508
+ }
509
+ }
510
+ }
511
+ // transforms
512
+ function transformCallHierarchyItem(item, filter) {
513
+ const span = transformSpan(item.file, item.span, filter);
514
+ const selectionSpan = transformSpan(item.file, item.selectionSpan, filter);
515
+ return {
516
+ ...item,
517
+ span: span?.textSpan ?? { start: 0, length: 0 },
518
+ selectionSpan: selectionSpan?.textSpan ?? { start: 0, length: 0 },
519
+ };
520
+ }
521
+ function transformDiagnostic(diagnostic) {
522
+ if (!transformedDiagnostics.has(diagnostic)) {
523
+ if (diagnostic.start !== undefined && diagnostic.file) {
524
+ transformedDiagnostics.set(diagnostic, undefined);
525
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(diagnostic.file?.fileName);
526
+ if (virtualFile) {
527
+ for (const [sourceOffset, mapping] of map.getSourceOffsets(diagnostic.start - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
528
+ if ((0, language_core_1.shouldReportDiagnostics)(mapping.data)) {
529
+ transformedDiagnostics.set(diagnostic, {
530
+ ...diagnostic,
531
+ start: sourceOffset,
532
+ });
533
+ break;
534
+ }
535
+ }
536
+ }
537
+ else {
538
+ transformedDiagnostics.set(diagnostic, diagnostic);
539
+ }
540
+ }
541
+ else {
542
+ transformedDiagnostics.set(diagnostic, diagnostic);
543
+ }
544
+ if (diagnostic.relatedInformation) {
545
+ diagnostic.relatedInformation = diagnostic.relatedInformation
546
+ .map(transformDiagnostic)
547
+ .filter(notEmpty);
548
+ }
549
+ }
550
+ return transformedDiagnostics.get(diagnostic);
551
+ }
552
+ function transformFileTextChanges(changes, filter) {
553
+ const [_, source] = getVirtualFileAndMap(changes.fileName);
554
+ if (source) {
555
+ return {
556
+ ...changes,
557
+ fileName: source.id,
558
+ textChanges: changes.textChanges.map(c => {
559
+ const span = transformSpan(changes.fileName, c.span, filter);
560
+ if (span) {
561
+ return {
562
+ ...c,
563
+ span: span.textSpan,
564
+ };
565
+ }
566
+ }).filter(notEmpty),
567
+ };
568
+ }
569
+ else {
570
+ return changes;
571
+ }
572
+ }
573
+ function transformDocumentSpan(documentSpan, filter, shouldFallback) {
574
+ let textSpan = transformSpan(documentSpan.fileName, documentSpan.textSpan, filter);
575
+ if (!textSpan && shouldFallback) {
576
+ const [virtualFile, source] = getVirtualFileAndMap(documentSpan.fileName);
577
+ if (virtualFile) {
578
+ textSpan = {
579
+ fileName: source.id,
580
+ textSpan: { start: 0, length: 0 },
581
+ };
582
+ }
583
+ }
584
+ if (!textSpan)
585
+ return;
586
+ const contextSpan = transformSpan(documentSpan.fileName, documentSpan.contextSpan, filter);
587
+ const originalTextSpan = transformSpan(documentSpan.originalFileName, documentSpan.originalTextSpan, filter);
588
+ const originalContextSpan = transformSpan(documentSpan.originalFileName, documentSpan.originalContextSpan, filter);
589
+ return {
590
+ ...documentSpan,
591
+ fileName: textSpan.fileName,
592
+ textSpan: textSpan.textSpan,
593
+ contextSpan: contextSpan?.textSpan,
594
+ originalFileName: originalTextSpan?.fileName,
595
+ originalTextSpan: originalTextSpan?.textSpan,
596
+ originalContextSpan: originalContextSpan?.textSpan,
597
+ };
598
+ }
599
+ function transformSpan(fileName, textSpan, filter) {
600
+ if (!fileName)
601
+ return;
602
+ if (!textSpan)
603
+ return;
604
+ const [virtualFile, sourceFile, map] = getVirtualFileAndMap(fileName);
605
+ if (virtualFile) {
606
+ for (const sourceStart of map.getSourceOffsets(textSpan.start - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
607
+ if (filter(sourceStart[1].data)) {
608
+ for (const sourceEnd of map.getSourceOffsets(textSpan.start + textSpan.length - (isTsPlugin ? sourceFile.snapshot.getLength() : 0))) {
609
+ if (filter(sourceEnd[1].data)) {
610
+ return {
611
+ fileName: sourceFile.id,
612
+ textSpan: {
613
+ start: sourceStart[0],
614
+ length: sourceEnd[0] - sourceStart[0],
615
+ },
616
+ };
617
+ }
618
+ }
619
+ }
620
+ }
621
+ }
622
+ else {
623
+ return {
624
+ fileName,
625
+ textSpan,
626
+ };
627
+ }
628
+ }
629
+ function getVirtualFileAndMap(fileName) {
630
+ if (isTsPlugin) {
631
+ const sourceFile = virtualFiles.getSourceFile(fileName);
632
+ if (sourceFile?.virtualFile) {
633
+ for (const virtualFile of (0, language_core_1.forEachEmbeddedFile)(sourceFile.virtualFile[0])) {
634
+ const ext = virtualFile.id.substring(fileName.length);
635
+ if (virtualFile.typescript && (ext === '.d.ts' || ext.match(/^\.(js|ts)x?$/))) {
636
+ for (const map of virtualFiles.getMaps(virtualFile)) {
637
+ if (map[1][0] === sourceFile.snapshot) {
638
+ return [virtualFile, sourceFile, map[1][1]];
639
+ }
640
+ }
641
+ }
642
+ }
643
+ }
644
+ }
645
+ else {
646
+ const [virtualFile, sourceFile] = virtualFiles.getVirtualFile(fileName);
647
+ if (virtualFile) {
648
+ for (const map of virtualFiles.getMaps(virtualFile)) {
649
+ if (map[1][0] === sourceFile.snapshot) {
650
+ return [virtualFile, sourceFile, map[1][1]];
651
+ }
652
+ }
653
+ }
654
+ }
655
+ return [undefined, undefined, undefined];
656
+ }
657
+ }
658
+ exports.decorateLanguageService = decorateLanguageService;
659
+ function notEmpty(value) {
660
+ return value !== null && value !== undefined;
661
+ }
662
+ //# sourceMappingURL=decorateLanguageService.js.map
@@ -1,9 +1,4 @@
1
- import { VirtualFiles } from '@volar/language-core';
1
+ import { FileProvider } from '@volar/language-core';
2
2
  import type * as ts from 'typescript/lib/tsserverlibrary';
3
- export declare function decorateLanguageServiceHost(virtualFiles: VirtualFiles, languageServiceHost: ts.LanguageServiceHost, ts: typeof import('typescript/lib/tsserverlibrary'), exts: string[]): void;
3
+ export declare function decorateLanguageServiceHost(virtualFiles: FileProvider, languageServiceHost: ts.LanguageServiceHost, ts: typeof import('typescript/lib/tsserverlibrary'), exts: string[]): void;
4
4
  export declare function searchExternalFiles(ts: typeof import('typescript/lib/tsserverlibrary'), project: ts.server.Project, exts: string[]): string[];
5
- /**
6
- * @deprecated use `searchExternalFiles` instead
7
- */
8
- export declare const getExternalFiles: typeof searchExternalFiles;
9
- //# sourceMappingURL=serverPlugin.d.ts.map