@volar/typescript 2.1.5 → 2.1.6

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.
@@ -29,19 +29,92 @@ function decorateLanguageService(files, languageService) {
29
29
  }
30
30
  };
31
31
  // methods
32
- 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;
32
+ const { findReferences, findRenameLocations, getCompletionEntryDetails, getCompletionsAtPosition, getDefinitionAndBoundSpan, getDefinitionAtPosition, getFileReferences, getFormattingEditsForDocument, getFormattingEditsForRange, getFormattingEditsAfterKeystroke, getImplementationAtPosition, getLinkedEditingRangeAtPosition, getQuickInfoAtPosition, getReferencesAtPosition, getSemanticDiagnostics, getSyntacticDiagnostics, getSuggestionDiagnostics, getTypeDefinitionAtPosition, getEncodedSemanticClassifications, getDocumentHighlights, getApplicableRefactors, getEditsForFileRename, getEditsForRefactor, getRenameInfo, getCodeFixesAtPosition, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, organizeImports, } = languageService;
33
+ languageService.getFormattingEditsForDocument = (fileName, options) => {
34
+ const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
35
+ if (virtualCode) {
36
+ if (!map.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) {
37
+ return [];
38
+ }
39
+ const edits = getFormattingEditsForDocument(fileName, options);
40
+ return edits
41
+ .map(edit => (0, transform_1.transformTextChange)(sourceFile, map, edit, language_core_1.isFormattingEnabled))
42
+ .filter(utils_1.notEmpty);
43
+ }
44
+ else {
45
+ return getFormattingEditsForDocument(fileName, options);
46
+ }
47
+ };
48
+ languageService.getFormattingEditsForRange = (fileName, start, end, options) => {
49
+ const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
50
+ if (virtualCode) {
51
+ const generateStart = (0, transform_1.toGeneratedOffset)(sourceFile, map, start, language_core_1.isFormattingEnabled);
52
+ const generateEnd = (0, transform_1.toGeneratedOffset)(sourceFile, map, end, language_core_1.isFormattingEnabled);
53
+ if (generateStart !== undefined && generateEnd !== undefined) {
54
+ const edits = getFormattingEditsForRange(fileName, generateStart, generateEnd, options);
55
+ return edits
56
+ .map(edit => (0, transform_1.transformTextChange)(sourceFile, map, edit, language_core_1.isFormattingEnabled))
57
+ .filter(utils_1.notEmpty);
58
+ }
59
+ return [];
60
+ }
61
+ else {
62
+ return getFormattingEditsForRange(fileName, start, end, options);
63
+ }
64
+ };
65
+ languageService.getFormattingEditsAfterKeystroke = (fileName, position, key, options) => {
66
+ const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
67
+ if (virtualCode) {
68
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isFormattingEnabled);
69
+ if (generatePosition !== undefined) {
70
+ const edits = getFormattingEditsAfterKeystroke(fileName, generatePosition, key, options);
71
+ return edits
72
+ .map(edit => (0, transform_1.transformTextChange)(sourceFile, map, edit, language_core_1.isFormattingEnabled))
73
+ .filter(utils_1.notEmpty);
74
+ }
75
+ return [];
76
+ }
77
+ else {
78
+ return getFormattingEditsAfterKeystroke(fileName, position, key, options);
79
+ }
80
+ };
81
+ languageService.getEditsForFileRename = (oldFilePath, newFilePath, formatOptions, preferences) => {
82
+ const edits = getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences);
83
+ return edits
84
+ .map(edit => (0, transform_1.transformFileTextChanges)(files, edit, language_core_1.isRenameEnabled))
85
+ .filter(utils_1.notEmpty);
86
+ };
87
+ languageService.getLinkedEditingRangeAtPosition = (fileName, position) => {
88
+ const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
89
+ if (virtualCode) {
90
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isLinkedEditingEnabled);
91
+ if (generatePosition !== undefined) {
92
+ const info = getLinkedEditingRangeAtPosition(fileName, generatePosition);
93
+ if (info) {
94
+ return {
95
+ ranges: info.ranges
96
+ .map(span => (0, transform_1.transformTextSpan)(sourceFile, map, span, language_core_1.isLinkedEditingEnabled))
97
+ .filter(utils_1.notEmpty),
98
+ wordPattern: info.wordPattern,
99
+ };
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ return getLinkedEditingRangeAtPosition(fileName, position);
105
+ }
106
+ };
33
107
  languageService.prepareCallHierarchy = (fileName, position) => {
34
108
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
35
109
  if (virtualCode) {
36
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
37
- if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
38
- const item = prepareCallHierarchy(fileName, generateOffset + sourceFile.snapshot.getLength());
39
- if (Array.isArray(item)) {
40
- return item.map(item => (0, transform_1.transformCallHierarchyItem)(files, item, language_core_1.isCallHierarchyEnabled));
41
- }
42
- else if (item) {
43
- return (0, transform_1.transformCallHierarchyItem)(files, item, language_core_1.isCallHierarchyEnabled);
44
- }
110
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isCallHierarchyEnabled);
111
+ if (generatePosition !== undefined) {
112
+ const item = prepareCallHierarchy(fileName, generatePosition);
113
+ if (Array.isArray(item)) {
114
+ return item.map(item => (0, transform_1.transformCallHierarchyItem)(files, item, language_core_1.isCallHierarchyEnabled));
115
+ }
116
+ else if (item) {
117
+ return (0, transform_1.transformCallHierarchyItem)(files, item, language_core_1.isCallHierarchyEnabled);
45
118
  }
46
119
  }
47
120
  }
@@ -53,10 +126,9 @@ function decorateLanguageService(files, languageService) {
53
126
  let calls = [];
54
127
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
55
128
  if (virtualCode) {
56
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
57
- if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
58
- calls = provideCallHierarchyIncomingCalls(fileName, generateOffset + sourceFile.snapshot.getLength());
59
- }
129
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isCallHierarchyEnabled);
130
+ if (generatePosition !== undefined) {
131
+ calls = provideCallHierarchyIncomingCalls(fileName, generatePosition);
60
132
  }
61
133
  }
62
134
  else {
@@ -78,10 +150,9 @@ function decorateLanguageService(files, languageService) {
78
150
  let calls = [];
79
151
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
80
152
  if (virtualCode) {
81
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
82
- if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
83
- calls = provideCallHierarchyOutgoingCalls(fileName, generateOffset + sourceFile.snapshot.getLength());
84
- }
153
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isCallHierarchyEnabled);
154
+ if (generatePosition !== undefined) {
155
+ calls = provideCallHierarchyOutgoingCalls(fileName, generatePosition);
85
156
  }
86
157
  }
87
158
  else {
@@ -91,7 +162,9 @@ function decorateLanguageService(files, languageService) {
91
162
  .map(call => {
92
163
  const to = (0, transform_1.transformCallHierarchyItem)(files, call.to, language_core_1.isCallHierarchyEnabled);
93
164
  const fromSpans = call.fromSpans
94
- .map(span => (0, transform_1.transformSpan)(files, fileName, span, language_core_1.isCallHierarchyEnabled)?.textSpan)
165
+ .map(span => sourceFile
166
+ ? (0, transform_1.transformTextSpan)(sourceFile, map, span, language_core_1.isCallHierarchyEnabled)
167
+ : span)
95
168
  .filter(utils_1.notEmpty);
96
169
  return {
97
170
  to,
@@ -109,17 +182,16 @@ function decorateLanguageService(files, languageService) {
109
182
  languageService.getQuickInfoAtPosition = (fileName, position) => {
110
183
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
111
184
  if (virtualCode) {
112
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
113
- if ((0, language_core_1.isHoverEnabled)(mapping.data)) {
114
- const result = getQuickInfoAtPosition(fileName, generateOffset + sourceFile.snapshot.getLength());
115
- if (result) {
116
- const textSpan = (0, transform_1.transformSpan)(files, fileName, result.textSpan, language_core_1.isHoverEnabled)?.textSpan;
117
- if (textSpan) {
118
- return {
119
- ...result,
120
- textSpan,
121
- };
122
- }
185
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isHoverEnabled);
186
+ if (generatePosition !== undefined) {
187
+ const result = getQuickInfoAtPosition(fileName, generatePosition);
188
+ if (result) {
189
+ const textSpan = (0, transform_1.transformTextSpan)(sourceFile, map, result.textSpan, language_core_1.isHoverEnabled);
190
+ if (textSpan) {
191
+ return {
192
+ ...result,
193
+ textSpan,
194
+ };
123
195
  }
124
196
  }
125
197
  }
@@ -160,16 +232,15 @@ function decorateLanguageService(files, languageService) {
160
232
  languageService.getApplicableRefactors = (fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
161
233
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
162
234
  if (virtualCode) {
163
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos)) {
164
- if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
165
- const por = typeof positionOrRange === 'number'
166
- ? generateOffset + sourceFile.snapshot.getLength()
167
- : {
168
- pos: generateOffset + sourceFile.snapshot.getLength(),
169
- end: generateOffset + positionOrRange.end - positionOrRange.pos + sourceFile.snapshot.getLength(),
170
- };
171
- return getApplicableRefactors(fileName, por, preferences, triggerReason, kind, includeInteractiveActions);
172
- }
235
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos, language_core_1.isCodeActionsEnabled);
236
+ if (generatePosition !== undefined) {
237
+ const por = typeof positionOrRange === 'number'
238
+ ? generatePosition
239
+ : {
240
+ pos: generatePosition,
241
+ end: generatePosition + positionOrRange.end - positionOrRange.pos,
242
+ };
243
+ return getApplicableRefactors(fileName, por, preferences, triggerReason, kind, includeInteractiveActions);
173
244
  }
174
245
  return [];
175
246
  }
@@ -181,16 +252,17 @@ function decorateLanguageService(files, languageService) {
181
252
  let edits;
182
253
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
183
254
  if (virtualCode) {
184
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos)) {
185
- if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
186
- const por = typeof positionOrRange === 'number'
187
- ? generateOffset + sourceFile.snapshot.getLength()
188
- : {
189
- pos: generateOffset + sourceFile.snapshot.getLength(),
190
- end: generateOffset + positionOrRange.end - positionOrRange.pos + sourceFile.snapshot.getLength(),
191
- };
192
- edits = getEditsForRefactor(fileName, formatOptions, por, refactorName, actionName, preferences);
193
- }
255
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, typeof positionOrRange === 'number'
256
+ ? positionOrRange
257
+ : positionOrRange.pos, language_core_1.isCodeActionsEnabled);
258
+ if (generatePosition !== undefined) {
259
+ const por = typeof positionOrRange === 'number'
260
+ ? generatePosition
261
+ : {
262
+ pos: generatePosition,
263
+ end: generatePosition + positionOrRange.end - positionOrRange.pos,
264
+ };
265
+ edits = getEditsForRefactor(fileName, formatOptions, por, refactorName, actionName, preferences);
194
266
  }
195
267
  }
196
268
  else {
@@ -206,20 +278,19 @@ function decorateLanguageService(files, languageService) {
206
278
  languageService.getRenameInfo = (fileName, position, options) => {
207
279
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
208
280
  if (virtualCode) {
209
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
210
- if ((0, language_core_1.isRenameEnabled)(mapping.data)) {
211
- const info = getRenameInfo(fileName, generateOffset + sourceFile.snapshot.getLength(), options);
212
- if (info.canRename) {
213
- const span = (0, transform_1.transformSpan)(files, fileName, info.triggerSpan, language_core_1.isRenameEnabled);
214
- if (span) {
215
- info.triggerSpan = span.textSpan;
216
- return info;
217
- }
218
- }
219
- else {
281
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isRenameEnabled);
282
+ if (generatePosition !== undefined) {
283
+ const info = getRenameInfo(fileName, generatePosition, options);
284
+ if (info.canRename) {
285
+ const span = (0, transform_1.transformTextSpan)(sourceFile, map, info.triggerSpan, language_core_1.isRenameEnabled);
286
+ if (span) {
287
+ info.triggerSpan = span;
220
288
  return info;
221
289
  }
222
290
  }
291
+ else {
292
+ return info;
293
+ }
223
294
  }
224
295
  return {
225
296
  canRename: false,
@@ -234,16 +305,10 @@ function decorateLanguageService(files, languageService) {
234
305
  let fixes = [];
235
306
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
236
307
  if (virtualCode) {
237
- for (const [generateStart, mapping] of map.getGeneratedOffsets(start)) {
238
- if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
239
- for (const [generateEnd, mapping] of map.getGeneratedOffsets(end)) {
240
- if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
241
- fixes = getCodeFixesAtPosition(fileName, generateStart + sourceFile.snapshot.getLength(), generateEnd + sourceFile.snapshot.getLength(), errorCodes, formatOptions, preferences);
242
- break;
243
- }
244
- }
245
- break;
246
- }
308
+ const generateStart = (0, transform_1.toGeneratedOffset)(sourceFile, map, start, language_core_1.isCodeActionsEnabled);
309
+ const generateEnd = (0, transform_1.toGeneratedOffset)(sourceFile, map, end, language_core_1.isCodeActionsEnabled);
310
+ if (generateStart !== undefined && generateEnd !== undefined) {
311
+ fixes = getCodeFixesAtPosition(fileName, generateStart, generateEnd, errorCodes, formatOptions, preferences);
247
312
  }
248
313
  }
249
314
  else {
@@ -261,32 +326,25 @@ function decorateLanguageService(files, languageService) {
261
326
  let start;
262
327
  let end;
263
328
  for (const mapping of map.mappings) {
329
+ // TODO reuse the logic from language service
264
330
  if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) {
265
331
  start ??= mapping.generatedOffsets[0];
266
- end ??= mapping.generatedOffsets[mapping.generatedOffsets.length - 1];
332
+ end ??= mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1];
267
333
  start = Math.min(start, mapping.generatedOffsets[0]);
268
- end = Math.max(end, mapping.generatedOffsets[mapping.generatedOffsets.length - 1]);
334
+ end = Math.max(end, mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1]);
269
335
  }
270
336
  }
271
- if (start === undefined || end === undefined) {
272
- start = 0;
273
- end = 0;
274
- }
337
+ start ??= 0;
338
+ end ??= sourceFile.snapshot.getLength();
275
339
  start += sourceFile.snapshot.getLength();
276
340
  end += sourceFile.snapshot.getLength();
277
341
  const result = getEncodedSemanticClassifications(fileName, { start, length: end - start }, format);
278
342
  const spans = [];
279
343
  for (let i = 0; i < result.spans.length; i += 3) {
280
- for (const [sourceStart, mapping] of map.getSourceOffsets(result.spans[i] - sourceFile.snapshot.getLength())) {
281
- if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data)) {
282
- for (const [sourceEnd, mapping] of map.getSourceOffsets(result.spans[i] + result.spans[i + 1] - sourceFile.snapshot.getLength())) {
283
- if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data)) {
284
- spans.push(sourceStart, sourceEnd - sourceStart, result.spans[i + 2]);
285
- break;
286
- }
287
- }
288
- break;
289
- }
344
+ const sourceStart = (0, transform_1.toSourceOffset)(sourceFile, map, result.spans[i], language_core_1.isSemanticTokensEnabled);
345
+ const sourceEnd = (0, transform_1.toSourceOffset)(sourceFile, map, result.spans[i] + result.spans[i + 1], language_core_1.isSemanticTokensEnabled);
346
+ if (sourceStart !== undefined && sourceEnd !== undefined) {
347
+ spans.push(sourceStart, sourceEnd - sourceStart, result.spans[i + 2]);
290
348
  }
291
349
  }
292
350
  result.spans = spans;
@@ -423,24 +481,29 @@ function decorateLanguageService(files, languageService) {
423
481
  if (virtualCode) {
424
482
  let mainResult;
425
483
  let additionalResults = [];
426
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
427
- if ((0, language_core_1.isCompletionEnabled)(mapping.data)) {
428
- const isAdditional = typeof mapping.data.completion === 'object' && mapping.data.completion.isAdditional;
429
- if (!isAdditional && mainResult) {
430
- continue;
484
+ let isAdditional;
485
+ const generatedOffset = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, data => {
486
+ if (!(0, language_core_1.isCompletionEnabled)(data)) {
487
+ return false;
488
+ }
489
+ isAdditional = typeof data.completion === 'object' && data.completion.isAdditional;
490
+ if (!isAdditional && mainResult) {
491
+ return false;
492
+ }
493
+ return true;
494
+ });
495
+ if (generatedOffset !== undefined) {
496
+ const result = getCompletionsAtPosition(fileName, generatedOffset, options, formattingSettings);
497
+ if (result) {
498
+ for (const entry of result.entries) {
499
+ entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(sourceFile, map, entry.replacementSpan, language_core_1.isCompletionEnabled);
431
500
  }
432
- const result = getCompletionsAtPosition(fileName, generateOffset + sourceFile.snapshot.getLength(), options, formattingSettings);
433
- if (result) {
434
- for (const entry of result.entries) {
435
- entry.replacementSpan = (0, transform_1.transformSpan)(files, fileName, entry.replacementSpan, language_core_1.isCompletionEnabled)?.textSpan;
436
- }
437
- result.optionalReplacementSpan = (0, transform_1.transformSpan)(files, fileName, result.optionalReplacementSpan, language_core_1.isCompletionEnabled)?.textSpan;
438
- if (isAdditional) {
439
- additionalResults.push(result);
440
- }
441
- else {
442
- mainResult = result;
443
- }
501
+ result.optionalReplacementSpan = result.optionalReplacementSpan && (0, transform_1.transformTextSpan)(sourceFile, map, result.optionalReplacementSpan, language_core_1.isCompletionEnabled);
502
+ if (isAdditional) {
503
+ additionalResults.push(result);
504
+ }
505
+ else {
506
+ mainResult = result;
444
507
  }
445
508
  }
446
509
  }
@@ -465,11 +528,9 @@ function decorateLanguageService(files, languageService) {
465
528
  let details;
466
529
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
467
530
  if (virtualCode) {
468
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
469
- if ((0, language_core_1.isCompletionEnabled)(mapping.data)) {
470
- details = getCompletionEntryDetails(fileName, generateOffset + sourceFile.snapshot.getLength(), entryName, formatOptions, source, preferences, data);
471
- break;
472
- }
531
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isCompletionEnabled);
532
+ if (generatePosition !== undefined) {
533
+ details = getCompletionEntryDetails(fileName, generatePosition, entryName, formatOptions, source, preferences, data);
473
534
  }
474
535
  }
475
536
  else {
@@ -504,14 +565,12 @@ function decorateLanguageService(files, languageService) {
504
565
  const result = provideInlayHints(fileName, { start, length: end - start }, preferences);
505
566
  const hints = [];
506
567
  for (const hint of result) {
507
- for (const [sourcePosition, mapping] of map.getSourceOffsets(hint.position - sourceFile.snapshot.getLength())) {
508
- if ((0, language_core_1.isInlayHintsEnabled)(mapping.data)) {
509
- hints.push({
510
- ...hint,
511
- position: sourcePosition,
512
- });
513
- break;
514
- }
568
+ const sourcePosition = (0, transform_1.toSourceOffset)(sourceFile, map, hint.position, language_core_1.isInlayHintsEnabled);
569
+ if (sourcePosition !== undefined) {
570
+ hints.push({
571
+ ...hint,
572
+ position: sourcePosition,
573
+ });
515
574
  }
516
575
  }
517
576
  return hints;
@@ -532,9 +591,9 @@ function decorateLanguageService(files, languageService) {
532
591
  const processedFilePositions = new Set();
533
592
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
534
593
  if (virtualCode) {
535
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
594
+ for (const [generatedOffset, mapping] of map.getGeneratedOffsets(position)) {
536
595
  if (filter(mapping.data)) {
537
- process(fileName, generateOffset + sourceFile.snapshot.getLength());
596
+ process(fileName, generatedOffset + sourceFile.snapshot.getLength());
538
597
  }
539
598
  }
540
599
  }
@@ -58,28 +58,24 @@ function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts) {
58
58
  };
59
59
  }
60
60
  languageServiceHost.getScriptSnapshot = fileName => {
61
- if (exts.some(ext => fileName.endsWith(ext))) {
62
- updateScript(fileName);
63
- return scripts.get(fileName)?.snapshot;
61
+ const virtualScript = updateVirtualScript(fileName);
62
+ if (virtualScript) {
63
+ return virtualScript.snapshot;
64
64
  }
65
65
  return getScriptSnapshot(fileName);
66
66
  };
67
67
  if (getScriptKind) {
68
68
  languageServiceHost.getScriptKind = fileName => {
69
- if (exts.some(ext => fileName.endsWith(ext))) {
70
- updateScript(fileName);
71
- const script = scripts.get(fileName);
72
- if (script) {
73
- return script.kind;
74
- }
75
- return ts.ScriptKind.Deferred;
69
+ const virtualScript = updateVirtualScript(fileName);
70
+ if (virtualScript) {
71
+ return virtualScript.kind;
76
72
  }
77
73
  return getScriptKind(fileName);
78
74
  };
79
75
  }
80
- function updateScript(fileName) {
76
+ function updateVirtualScript(fileName) {
81
77
  const version = languageServiceHost.getScriptVersion(fileName);
82
- if (version !== scripts.get(fileName)?.version) {
78
+ if (version !== scripts.get(fileName)?.[0]) {
83
79
  let extension = '.ts';
84
80
  let snapshotSnapshot;
85
81
  let scriptKind = ts.ScriptKind.TS;
@@ -106,14 +102,18 @@ function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts) {
106
102
  extraProjectVersion++;
107
103
  virtualFiles.delete(fileName);
108
104
  }
109
- scripts.set(fileName, {
110
- version,
111
- extension,
112
- snapshot: snapshotSnapshot,
113
- kind: scriptKind,
114
- });
105
+ if (snapshotSnapshot) {
106
+ scripts.set(fileName, [
107
+ version,
108
+ {
109
+ extension,
110
+ snapshot: snapshotSnapshot,
111
+ kind: scriptKind,
112
+ }
113
+ ]);
114
+ }
115
115
  }
116
- return scripts.get(fileName);
116
+ return scripts.get(fileName)?.[1];
117
117
  }
118
118
  }
119
119
  exports.decorateLanguageServiceHost = decorateLanguageServiceHost;
@@ -1,4 +1,4 @@
1
- import { FileRegistry, CodeInformation } from '@volar/language-core';
1
+ import { FileRegistry, CodeInformation, SourceMap, SourceFile } from '@volar/language-core';
2
2
  import type * as ts from 'typescript';
3
3
  export declare function transformCallHierarchyItem(files: FileRegistry, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem;
4
4
  export declare function transformDiagnostic<T extends ts.Diagnostic>(files: FileRegistry, diagnostic: T): T | undefined;
@@ -8,3 +8,7 @@ export declare function transformSpan(files: FileRegistry, fileName: string | un
8
8
  fileName: string;
9
9
  textSpan: ts.TextSpan;
10
10
  } | undefined;
11
+ export declare function transformTextChange(sourceFile: SourceFile, map: SourceMap<CodeInformation>, textChange: ts.TextChange, filter: (data: CodeInformation) => boolean): ts.TextChange | undefined;
12
+ export declare function transformTextSpan(sourceFile: SourceFile, map: SourceMap<CodeInformation>, textSpan: ts.TextSpan, filter: (data: CodeInformation) => boolean): ts.TextSpan | undefined;
13
+ export declare function toSourceOffset(sourceFile: SourceFile, map: SourceMap, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
14
+ export declare function toGeneratedOffset(sourceFile: SourceFile, map: SourceMap, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = exports.transformDiagnostic = exports.transformCallHierarchyItem = void 0;
3
+ exports.toGeneratedOffset = exports.toSourceOffset = exports.transformTextSpan = exports.transformTextChange = exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = 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();
@@ -28,12 +28,12 @@ function transformDiagnostic(files, diagnostic) {
28
28
  && diagnostic.length !== undefined) {
29
29
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, diagnostic.file.fileName);
30
30
  if (virtualCode) {
31
- const sourceRange = transformRange(sourceFile, map, diagnostic.start, diagnostic.start + diagnostic.length, language_core_1.shouldReportDiagnostics);
32
- if (sourceRange) {
31
+ const sourceSpan = transformTextSpan(sourceFile, map, { start: diagnostic.start, length: diagnostic.length }, language_core_1.shouldReportDiagnostics);
32
+ if (sourceSpan) {
33
33
  transformedDiagnostics.set(diagnostic, {
34
34
  ...diagnostic,
35
- start: sourceRange[0],
36
- length: sourceRange[1] - sourceRange[0],
35
+ start: sourceSpan.start,
36
+ length: sourceSpan.length,
37
37
  });
38
38
  }
39
39
  }
@@ -98,22 +98,16 @@ function transformDocumentSpan(files, documentSpan, filter, shouldFallback) {
98
98
  }
99
99
  exports.transformDocumentSpan = transformDocumentSpan;
100
100
  function transformSpan(files, fileName, textSpan, filter) {
101
- if (!fileName) {
102
- return;
103
- }
104
- if (!textSpan) {
101
+ if (!fileName || !textSpan) {
105
102
  return;
106
103
  }
107
104
  const [virtualFile, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
108
105
  if (virtualFile) {
109
- const sourceRange = transformRange(sourceFile, map, textSpan.start, textSpan.start + textSpan.length, filter);
110
- if (sourceRange) {
106
+ const sourceSpan = transformTextSpan(sourceFile, map, textSpan, filter);
107
+ if (sourceSpan) {
111
108
  return {
112
109
  fileName,
113
- textSpan: {
114
- start: sourceRange[0],
115
- length: sourceRange[1] - sourceRange[0],
116
- },
110
+ textSpan: sourceSpan,
117
111
  };
118
112
  }
119
113
  }
@@ -125,15 +119,43 @@ function transformSpan(files, fileName, textSpan, filter) {
125
119
  }
126
120
  }
127
121
  exports.transformSpan = transformSpan;
128
- function transformRange(sourceFile, map, start, end, filter) {
129
- for (const sourceStart of map.getSourceOffsets(start - sourceFile.snapshot.getLength())) {
130
- if (filter(sourceStart[1].data)) {
131
- for (const sourceEnd of map.getSourceOffsets(end - sourceFile.snapshot.getLength())) {
132
- if (sourceEnd[0] >= sourceStart[0] && filter(sourceEnd[1].data)) {
133
- return [sourceStart[0], sourceEnd[0]];
134
- }
135
- }
122
+ function transformTextChange(sourceFile, map, textChange, filter) {
123
+ const sourceSpan = transformTextSpan(sourceFile, map, textChange.span, filter);
124
+ if (sourceSpan) {
125
+ return {
126
+ newText: textChange.newText,
127
+ span: sourceSpan,
128
+ };
129
+ }
130
+ }
131
+ exports.transformTextChange = transformTextChange;
132
+ function transformTextSpan(sourceFile, map, textSpan, filter) {
133
+ const start = textSpan.start;
134
+ const end = textSpan.start + textSpan.length;
135
+ const sourceStart = toSourceOffset(sourceFile, map, start, filter);
136
+ const sourceEnd = toSourceOffset(sourceFile, map, end, filter);
137
+ if (sourceStart !== undefined && sourceEnd !== undefined && sourceEnd >= sourceStart) {
138
+ return {
139
+ start: sourceStart,
140
+ length: sourceEnd - sourceStart,
141
+ };
142
+ }
143
+ }
144
+ exports.transformTextSpan = transformTextSpan;
145
+ function toSourceOffset(sourceFile, map, position, filter) {
146
+ for (const [sourceOffset, mapping] of map.getSourceOffsets(position - sourceFile.snapshot.getLength())) {
147
+ if (filter(mapping.data)) {
148
+ return sourceOffset;
149
+ }
150
+ }
151
+ }
152
+ exports.toSourceOffset = toSourceOffset;
153
+ function toGeneratedOffset(sourceFile, map, position, filter) {
154
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
155
+ if (filter(mapping.data)) {
156
+ return generateOffset + sourceFile.snapshot.getLength();
136
157
  }
137
158
  }
138
159
  }
160
+ exports.toGeneratedOffset = toGeneratedOffset;
139
161
  //# sourceMappingURL=transform.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/typescript",
3
- "version": "2.1.5",
3
+ "version": "2.1.6",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,13 +12,13 @@
12
12
  "directory": "packages/typescript"
13
13
  },
14
14
  "dependencies": {
15
- "@volar/language-core": "2.1.5",
15
+ "@volar/language-core": "2.1.6",
16
16
  "path-browserify": "^1.0.1"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "latest",
20
20
  "@types/path-browserify": "latest",
21
- "@volar/language-service": "2.1.5"
21
+ "@volar/language-service": "2.1.6"
22
22
  },
23
- "gitHead": "1b7f456660134891d91608f36cfc6dd2eaea6f70"
23
+ "gitHead": "7feafa54fd3540569d492c2ab582c10c0cdc84d2"
24
24
  }