@volar/typescript 2.1.4 → 2.1.5-patch.2

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.isCodeActionsEnabled))
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 {
@@ -277,16 +342,10 @@ function decorateLanguageService(files, languageService) {
277
342
  const result = getEncodedSemanticClassifications(fileName, { start, length: end - start }, format);
278
343
  const spans = [];
279
344
  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
- }
345
+ const sourceStart = (0, transform_1.toSourceOffset)(sourceFile, map, result.spans[i], language_core_1.isSemanticTokensEnabled);
346
+ const sourceEnd = (0, transform_1.toSourceOffset)(sourceFile, map, result.spans[i] + result.spans[i + 1], language_core_1.isSemanticTokensEnabled);
347
+ if (sourceStart !== undefined && sourceEnd !== undefined) {
348
+ spans.push(sourceStart, sourceEnd - sourceStart, result.spans[i + 2]);
290
349
  }
291
350
  }
292
351
  result.spans = spans;
@@ -423,24 +482,29 @@ function decorateLanguageService(files, languageService) {
423
482
  if (virtualCode) {
424
483
  let mainResult;
425
484
  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;
485
+ let isAdditional;
486
+ const generatedOffset = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, data => {
487
+ if (!(0, language_core_1.isCompletionEnabled)(data)) {
488
+ return false;
489
+ }
490
+ isAdditional = typeof data.completion === 'object' && data.completion.isAdditional;
491
+ if (!isAdditional && mainResult) {
492
+ return false;
493
+ }
494
+ return true;
495
+ });
496
+ if (generatedOffset !== undefined) {
497
+ const result = getCompletionsAtPosition(fileName, generatedOffset, options, formattingSettings);
498
+ if (result) {
499
+ for (const entry of result.entries) {
500
+ entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(sourceFile, map, entry.replacementSpan, language_core_1.isCompletionEnabled);
431
501
  }
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
- }
502
+ result.optionalReplacementSpan = result.optionalReplacementSpan && (0, transform_1.transformTextSpan)(sourceFile, map, result.optionalReplacementSpan, language_core_1.isCompletionEnabled);
503
+ if (isAdditional) {
504
+ additionalResults.push(result);
505
+ }
506
+ else {
507
+ mainResult = result;
444
508
  }
445
509
  }
446
510
  }
@@ -465,11 +529,9 @@ function decorateLanguageService(files, languageService) {
465
529
  let details;
466
530
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
467
531
  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
- }
532
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceFile, map, position, language_core_1.isCompletionEnabled);
533
+ if (generatePosition !== undefined) {
534
+ details = getCompletionEntryDetails(fileName, generatePosition, entryName, formatOptions, source, preferences, data);
473
535
  }
474
536
  }
475
537
  else {
@@ -504,14 +566,12 @@ function decorateLanguageService(files, languageService) {
504
566
  const result = provideInlayHints(fileName, { start, length: end - start }, preferences);
505
567
  const hints = [];
506
568
  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
- }
569
+ const sourcePosition = (0, transform_1.toSourceOffset)(sourceFile, map, hint.position, language_core_1.isInlayHintsEnabled);
570
+ if (sourcePosition !== undefined) {
571
+ hints.push({
572
+ ...hint,
573
+ position: sourcePosition,
574
+ });
515
575
  }
516
576
  }
517
577
  return hints;
@@ -532,9 +592,9 @@ function decorateLanguageService(files, languageService) {
532
592
  const processedFilePositions = new Set();
533
593
  const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
534
594
  if (virtualCode) {
535
- for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
595
+ for (const [generatedOffset, mapping] of map.getGeneratedOffsets(position)) {
536
596
  if (filter(mapping.data)) {
537
- process(fileName, generateOffset + sourceFile.snapshot.getLength());
597
+ process(fileName, generatedOffset + sourceFile.snapshot.getLength());
538
598
  }
539
599
  }
540
600
  }
@@ -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
@@ -17,36 +17,31 @@ function createSys(ts, env, currentDirectory) {
17
17
  };
18
18
  const promises = new Set();
19
19
  const fileWatcher = env.onDidChangeWatchedFiles?.(({ changes }) => {
20
+ version++;
20
21
  for (const change of changes) {
21
22
  const fileName = env.typescript.uriToFileName(change.uri);
22
23
  const dirName = path.dirname(fileName);
23
24
  const baseName = path.basename(fileName);
24
- const dir = getDir(dirName);
25
- if (dir.files.has(baseName) || dir.requestedRead) { // is requested file or directory
26
- version++;
27
- if (change.type === 1 || change.type === 2) {
28
- dir.files.set(normalizeFileId(baseName), {
29
- name: baseName,
30
- stat: {
31
- type: 1,
32
- ctime: Date.now(),
33
- mtime: Date.now(),
34
- size: -1,
35
- },
36
- requestedStat: false,
37
- requestedText: false,
38
- });
39
- }
40
- else if (change.type === 3) {
41
- dir.files.set(normalizeFileId(baseName), {
42
- name: baseName,
43
- stat: undefined,
44
- text: undefined,
45
- requestedStat: true,
46
- requestedText: true,
47
- });
48
- }
49
- }
25
+ const fileExists = change.type === 1
26
+ || change.type === 2;
27
+ const dir = getDir(dirName, fileExists);
28
+ dir.files.set(normalizeFileId(baseName), fileExists ? {
29
+ name: baseName,
30
+ stat: {
31
+ type: 1,
32
+ ctime: Date.now(),
33
+ mtime: Date.now(),
34
+ size: -1,
35
+ },
36
+ requestedStat: false,
37
+ requestedText: false,
38
+ } : {
39
+ name: baseName,
40
+ stat: undefined,
41
+ text: undefined,
42
+ requestedStat: true,
43
+ requestedText: true,
44
+ });
50
45
  }
51
46
  });
52
47
  return {
@@ -335,7 +330,7 @@ function createSys(ts, env, currentDirectory) {
335
330
  }
336
331
  return updated;
337
332
  }
338
- function getDir(dirName) {
333
+ function getDir(dirName, markExists = false) {
339
334
  const dirNames = [];
340
335
  let currentDirPath = dirName;
341
336
  let currentDirName = path.basename(currentDirPath);
@@ -350,6 +345,10 @@ function createSys(ts, env, currentDirectory) {
350
345
  for (let i = dirNames.length - 1; i >= 0; i--) {
351
346
  const nextDirName = dirNames[i];
352
347
  currentDir = getDirFromDir(currentDir, nextDirName);
348
+ if (markExists && !currentDir.exists) {
349
+ currentDir.exists = true;
350
+ version++;
351
+ }
353
352
  }
354
353
  return currentDir;
355
354
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/typescript",
3
- "version": "2.1.4",
3
+ "version": "2.1.5-patch.2",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,13 +12,12 @@
12
12
  "directory": "packages/typescript"
13
13
  },
14
14
  "dependencies": {
15
- "@volar/language-core": "2.1.4",
15
+ "@volar/language-core": "2.1.5",
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.4"
22
- },
23
- "gitHead": "cc46289ff6be015ee41a1896fdaef6aa68cee755"
21
+ "@volar/language-service": "2.1.5"
22
+ }
24
23
  }