@volar/typescript 2.2.0-alpha.1 → 2.2.0-alpha.11

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,2 @@
1
+ import type { LanguagePlugin } from "@volar/language-core";
2
+ export declare const fileLanguageIdProviderPlugin: LanguagePlugin;
package/lib/common.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fileLanguageIdProviderPlugin = void 0;
4
+ exports.fileLanguageIdProviderPlugin = {
5
+ getLanguageId(scriptId) {
6
+ const ext = scriptId.split('.').pop();
7
+ switch (ext) {
8
+ case 'js': return 'javascript';
9
+ case 'cjs': return 'javascript';
10
+ case 'mjs': return 'javascript';
11
+ case 'ts': return 'typescript';
12
+ case 'cts': return 'typescript';
13
+ case 'mts': return 'typescript';
14
+ case 'jsx': return 'javascriptreact';
15
+ case 'tsx': return 'typescriptreact';
16
+ }
17
+ },
18
+ };
19
+ //# sourceMappingURL=common.js.map
@@ -5,10 +5,12 @@ const language_core_1 = require("@volar/language-core");
5
5
  const dedupe_1 = require("./dedupe");
6
6
  const utils_1 = require("./utils");
7
7
  const transform_1 = require("./transform");
8
+ const windowsPathReg = /\\/g;
8
9
  function decorateLanguageService(language, languageService) {
9
10
  // ignored methods
10
11
  const { getNavigationTree, getOutliningSpans, } = languageService;
11
- languageService.getNavigationTree = fileName => {
12
+ languageService.getNavigationTree = filePath => {
13
+ const fileName = filePath.replace(windowsPathReg, '/');
12
14
  const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName);
13
15
  if (serviceScript) {
14
16
  const tree = getNavigationTree(fileName);
@@ -19,7 +21,8 @@ function decorateLanguageService(language, languageService) {
19
21
  return getNavigationTree(fileName);
20
22
  }
21
23
  };
22
- languageService.getOutliningSpans = fileName => {
24
+ languageService.getOutliningSpans = filePath => {
25
+ const fileName = filePath.replace(windowsPathReg, '/');
23
26
  const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName);
24
27
  if (serviceScript) {
25
28
  return [];
@@ -29,8 +32,9 @@ function decorateLanguageService(language, languageService) {
29
32
  }
30
33
  };
31
34
  // methods
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) => {
35
+ const { findReferences, findRenameLocations, getCompletionEntryDetails, getCompletionsAtPosition, getDefinitionAndBoundSpan, getDefinitionAtPosition, getFileReferences, getFormattingEditsForDocument, getFormattingEditsForRange, getFormattingEditsAfterKeystroke, getImplementationAtPosition, getLinkedEditingRangeAtPosition, getQuickInfoAtPosition, getSignatureHelpItems, getReferencesAtPosition, getSemanticDiagnostics, getSyntacticDiagnostics, getSuggestionDiagnostics, getTypeDefinitionAtPosition, getEncodedSemanticClassifications, getDocumentHighlights, getApplicableRefactors, getEditsForFileRename, getEditsForRefactor, getRenameInfo, getCodeFixesAtPosition, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, organizeImports, } = languageService;
36
+ languageService.getFormattingEditsForDocument = (filePath, options) => {
37
+ const fileName = filePath.replace(windowsPathReg, '/');
34
38
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
35
39
  if (serviceScript) {
36
40
  if (!map.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) {
@@ -45,7 +49,8 @@ function decorateLanguageService(language, languageService) {
45
49
  return getFormattingEditsForDocument(fileName, options);
46
50
  }
47
51
  };
48
- languageService.getFormattingEditsForRange = (fileName, start, end, options) => {
52
+ languageService.getFormattingEditsForRange = (filePath, start, end, options) => {
53
+ const fileName = filePath.replace(windowsPathReg, '/');
49
54
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
50
55
  if (serviceScript) {
51
56
  const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isFormattingEnabled);
@@ -62,7 +67,8 @@ function decorateLanguageService(language, languageService) {
62
67
  return getFormattingEditsForRange(fileName, start, end, options);
63
68
  }
64
69
  };
65
- languageService.getFormattingEditsAfterKeystroke = (fileName, position, key, options) => {
70
+ languageService.getFormattingEditsAfterKeystroke = (filePath, position, key, options) => {
71
+ const fileName = filePath.replace(windowsPathReg, '/');
66
72
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
67
73
  if (serviceScript) {
68
74
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isFormattingEnabled);
@@ -84,7 +90,8 @@ function decorateLanguageService(language, languageService) {
84
90
  .map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isRenameEnabled))
85
91
  .filter(utils_1.notEmpty);
86
92
  };
87
- languageService.getLinkedEditingRangeAtPosition = (fileName, position) => {
93
+ languageService.getLinkedEditingRangeAtPosition = (filePath, position) => {
94
+ const fileName = filePath.replace(windowsPathReg, '/');
88
95
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
89
96
  if (serviceScript) {
90
97
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isLinkedEditingEnabled);
@@ -104,7 +111,8 @@ function decorateLanguageService(language, languageService) {
104
111
  return getLinkedEditingRangeAtPosition(fileName, position);
105
112
  }
106
113
  };
107
- languageService.prepareCallHierarchy = (fileName, position) => {
114
+ languageService.prepareCallHierarchy = (filePath, position) => {
115
+ const fileName = filePath.replace(windowsPathReg, '/');
108
116
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
109
117
  if (serviceScript) {
110
118
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled);
@@ -122,8 +130,9 @@ function decorateLanguageService(language, languageService) {
122
130
  return prepareCallHierarchy(fileName, position);
123
131
  }
124
132
  };
125
- languageService.provideCallHierarchyIncomingCalls = (fileName, position) => {
133
+ languageService.provideCallHierarchyIncomingCalls = (filePath, position) => {
126
134
  let calls = [];
135
+ const fileName = filePath.replace(windowsPathReg, '/');
127
136
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
128
137
  if (serviceScript) {
129
138
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled);
@@ -146,8 +155,9 @@ function decorateLanguageService(language, languageService) {
146
155
  };
147
156
  });
148
157
  };
149
- languageService.provideCallHierarchyOutgoingCalls = (fileName, position) => {
158
+ languageService.provideCallHierarchyOutgoingCalls = (filePath, position) => {
150
159
  let calls = [];
160
+ const fileName = filePath.replace(windowsPathReg, '/');
151
161
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
152
162
  if (serviceScript) {
153
163
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled);
@@ -179,7 +189,8 @@ function decorateLanguageService(language, languageService) {
179
189
  .filter(utils_1.notEmpty);
180
190
  return resolved;
181
191
  };
182
- languageService.getQuickInfoAtPosition = (fileName, position) => {
192
+ languageService.getQuickInfoAtPosition = (filePath, position) => {
193
+ const fileName = filePath.replace(windowsPathReg, '/');
183
194
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
184
195
  if (serviceScript) {
185
196
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isHoverEnabled);
@@ -200,7 +211,30 @@ function decorateLanguageService(language, languageService) {
200
211
  return getQuickInfoAtPosition(fileName, position);
201
212
  }
202
213
  };
203
- languageService.getDocumentHighlights = (fileName, position, filesToSearch) => {
214
+ languageService.getSignatureHelpItems = (filePath, position, options) => {
215
+ const fileName = filePath.replace(windowsPathReg, '/');
216
+ const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
217
+ if (serviceScript) {
218
+ const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isSignatureHelpEnabled);
219
+ if (generatePosition !== undefined) {
220
+ const result = getSignatureHelpItems(fileName, generatePosition, options);
221
+ if (result) {
222
+ const applicableSpan = (0, transform_1.transformTextSpan)(sourceScript, map, result.applicableSpan, language_core_1.isSignatureHelpEnabled);
223
+ if (applicableSpan) {
224
+ return {
225
+ ...result,
226
+ applicableSpan,
227
+ };
228
+ }
229
+ }
230
+ }
231
+ }
232
+ else {
233
+ return getSignatureHelpItems(fileName, position, options);
234
+ }
235
+ };
236
+ languageService.getDocumentHighlights = (filePath, position, filesToSearch) => {
237
+ const fileName = filePath.replace(windowsPathReg, '/');
204
238
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isHighlightEnabled, position => getDocumentHighlights(fileName, position, filesToSearch), function* (result) {
205
239
  for (const ref of result) {
206
240
  for (const reference of ref.highlightSpans) {
@@ -229,7 +263,8 @@ function decorateLanguageService(language, languageService) {
229
263
  });
230
264
  return resolved;
231
265
  };
232
- languageService.getApplicableRefactors = (fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
266
+ languageService.getApplicableRefactors = (filePath, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
267
+ const fileName = filePath.replace(windowsPathReg, '/');
233
268
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
234
269
  if (serviceScript) {
235
270
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos, language_core_1.isCodeActionsEnabled);
@@ -248,8 +283,9 @@ function decorateLanguageService(language, languageService) {
248
283
  return getApplicableRefactors(fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions);
249
284
  }
250
285
  };
251
- languageService.getEditsForRefactor = (fileName, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
286
+ languageService.getEditsForRefactor = (filePath, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
252
287
  let edits;
288
+ const fileName = filePath.replace(windowsPathReg, '/');
253
289
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
254
290
  if (serviceScript) {
255
291
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, typeof positionOrRange === 'number'
@@ -275,12 +311,13 @@ function decorateLanguageService(language, languageService) {
275
311
  return edits;
276
312
  }
277
313
  };
278
- languageService.getRenameInfo = (fileName, position, options) => {
314
+ languageService.getRenameInfo = (filePath, position, options) => {
315
+ const fileName = filePath.replace(windowsPathReg, '/');
279
316
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
280
317
  if (serviceScript) {
281
- const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isRenameEnabled);
282
- if (generatePosition !== undefined) {
283
- const info = getRenameInfo(fileName, generatePosition, options);
318
+ let failed;
319
+ for (const generateOffset of (0, transform_1.forEachGeneratedOffset)(sourceScript, map, position, language_core_1.isRenameEnabled)) {
320
+ const info = getRenameInfo(fileName, generateOffset, options);
284
321
  if (info.canRename) {
285
322
  const span = (0, transform_1.transformTextSpan)(sourceScript, map, info.triggerSpan, language_core_1.isRenameEnabled);
286
323
  if (span) {
@@ -289,9 +326,12 @@ function decorateLanguageService(language, languageService) {
289
326
  }
290
327
  }
291
328
  else {
292
- return info;
329
+ failed = info;
293
330
  }
294
331
  }
332
+ if (failed) {
333
+ return failed;
334
+ }
295
335
  return {
296
336
  canRename: false,
297
337
  localizedErrorMessage: 'Failed to get rename locations',
@@ -301,8 +341,9 @@ function decorateLanguageService(language, languageService) {
301
341
  return getRenameInfo(fileName, position, options);
302
342
  }
303
343
  };
304
- languageService.getCodeFixesAtPosition = (fileName, start, end, errorCodes, formatOptions, preferences) => {
344
+ languageService.getCodeFixesAtPosition = (filePath, start, end, errorCodes, formatOptions, preferences) => {
305
345
  let fixes = [];
346
+ const fileName = filePath.replace(windowsPathReg, '/');
306
347
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
307
348
  if (serviceScript) {
308
349
  const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isCodeActionsEnabled);
@@ -320,7 +361,8 @@ function decorateLanguageService(language, languageService) {
320
361
  });
321
362
  return fixes;
322
363
  };
323
- languageService.getEncodedSemanticClassifications = (fileName, span, format) => {
364
+ languageService.getEncodedSemanticClassifications = (filePath, span, format) => {
365
+ const fileName = filePath.replace(windowsPathReg, '/');
324
366
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
325
367
  if (serviceScript) {
326
368
  let start;
@@ -354,22 +396,26 @@ function decorateLanguageService(language, languageService) {
354
396
  return getEncodedSemanticClassifications(fileName, span, format);
355
397
  }
356
398
  };
357
- languageService.getSyntacticDiagnostics = fileName => {
399
+ languageService.getSyntacticDiagnostics = filePath => {
400
+ const fileName = filePath.replace(windowsPathReg, '/');
358
401
  return getSyntacticDiagnostics(fileName)
359
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
402
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, false))
360
403
  .filter(utils_1.notEmpty);
361
404
  };
362
- languageService.getSemanticDiagnostics = fileName => {
405
+ languageService.getSemanticDiagnostics = filePath => {
406
+ const fileName = filePath.replace(windowsPathReg, '/');
363
407
  return getSemanticDiagnostics(fileName)
364
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
408
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, false))
365
409
  .filter(utils_1.notEmpty);
366
410
  };
367
- languageService.getSuggestionDiagnostics = fileName => {
411
+ languageService.getSuggestionDiagnostics = filePath => {
412
+ const fileName = filePath.replace(windowsPathReg, '/');
368
413
  return getSuggestionDiagnostics(fileName)
369
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
414
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, false))
370
415
  .filter(utils_1.notEmpty);
371
416
  };
372
- languageService.getDefinitionAndBoundSpan = (fileName, position) => {
417
+ languageService.getDefinitionAndBoundSpan = (filePath, position) => {
418
+ const fileName = filePath.replace(windowsPathReg, '/');
373
419
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAndBoundSpan(fileName, position), function* (result) {
374
420
  for (const ref of result.definitions ?? []) {
375
421
  yield [ref.fileName, ref.textSpan.start];
@@ -392,7 +438,8 @@ function decorateLanguageService(language, languageService) {
392
438
  definitions: (0, dedupe_1.dedupeDocumentSpans)(definitions),
393
439
  };
394
440
  };
395
- languageService.findReferences = (fileName, position) => {
441
+ languageService.findReferences = (filePath, position) => {
442
+ const fileName = filePath.replace(windowsPathReg, '/');
396
443
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => findReferences(fileName, position), function* (result) {
397
444
  for (const ref of result) {
398
445
  for (const reference of ref.references) {
@@ -403,20 +450,18 @@ function decorateLanguageService(language, languageService) {
403
450
  const resolved = unresolved
404
451
  .flat()
405
452
  .map(symbol => {
406
- const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled);
407
- if (definition) {
408
- return {
409
- definition,
410
- references: symbol.references
411
- .map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled))
412
- .filter(utils_1.notEmpty),
413
- };
414
- }
415
- })
416
- .filter(utils_1.notEmpty);
417
- return (0, dedupe_1.dedupeReferencedSymbols)(resolved);
453
+ const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled, true);
454
+ return {
455
+ definition,
456
+ references: symbol.references
457
+ .map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled))
458
+ .filter(utils_1.notEmpty),
459
+ };
460
+ });
461
+ return resolved;
418
462
  };
419
- languageService.getDefinitionAtPosition = (fileName, position) => {
463
+ languageService.getDefinitionAtPosition = (filePath, position) => {
464
+ const fileName = filePath.replace(windowsPathReg, '/');
420
465
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAtPosition(fileName, position), function* (result) {
421
466
  for (const ref of result) {
422
467
  yield [ref.fileName, ref.textSpan.start];
@@ -428,7 +473,8 @@ function decorateLanguageService(language, languageService) {
428
473
  .filter(utils_1.notEmpty);
429
474
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
430
475
  };
431
- languageService.getTypeDefinitionAtPosition = (fileName, position) => {
476
+ languageService.getTypeDefinitionAtPosition = (filePath, position) => {
477
+ const fileName = filePath.replace(windowsPathReg, '/');
432
478
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, position => getTypeDefinitionAtPosition(fileName, position), function* (result) {
433
479
  for (const ref of result) {
434
480
  yield [ref.fileName, ref.textSpan.start];
@@ -440,7 +486,8 @@ function decorateLanguageService(language, languageService) {
440
486
  .filter(utils_1.notEmpty);
441
487
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
442
488
  };
443
- languageService.getImplementationAtPosition = (fileName, position) => {
489
+ languageService.getImplementationAtPosition = (filePath, position) => {
490
+ const fileName = filePath.replace(windowsPathReg, '/');
444
491
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, position => getImplementationAtPosition(fileName, position), function* (result) {
445
492
  for (const ref of result) {
446
493
  yield [ref.fileName, ref.textSpan.start];
@@ -452,7 +499,8 @@ function decorateLanguageService(language, languageService) {
452
499
  .filter(utils_1.notEmpty);
453
500
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
454
501
  };
455
- languageService.findRenameLocations = (fileName, position, findInStrings, findInComments, preferences) => {
502
+ languageService.findRenameLocations = (filePath, position, findInStrings, findInComments, preferences) => {
503
+ const fileName = filePath.replace(windowsPathReg, '/');
456
504
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, position => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) {
457
505
  for (const ref of result) {
458
506
  yield [ref.fileName, ref.textSpan.start];
@@ -464,7 +512,8 @@ function decorateLanguageService(language, languageService) {
464
512
  .filter(utils_1.notEmpty);
465
513
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
466
514
  };
467
- languageService.getReferencesAtPosition = (fileName, position) => {
515
+ languageService.getReferencesAtPosition = (filePath, position) => {
516
+ const fileName = filePath.replace(windowsPathReg, '/');
468
517
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => getReferencesAtPosition(fileName, position), function* (result) {
469
518
  for (const ref of result) {
470
519
  yield [ref.fileName, ref.textSpan.start];
@@ -476,7 +525,8 @@ function decorateLanguageService(language, languageService) {
476
525
  .filter(utils_1.notEmpty);
477
526
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
478
527
  };
479
- languageService.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
528
+ languageService.getCompletionsAtPosition = (filePath, position, options, formattingSettings) => {
529
+ const fileName = filePath.replace(windowsPathReg, '/');
480
530
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
481
531
  if (serviceScript) {
482
532
  let mainResult;
@@ -524,8 +574,9 @@ function decorateLanguageService(language, languageService) {
524
574
  return getCompletionsAtPosition(fileName, position, options, formattingSettings);
525
575
  }
526
576
  };
527
- languageService.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
577
+ languageService.getCompletionEntryDetails = (filePath, position, entryName, formatOptions, source, preferences, data) => {
528
578
  let details;
579
+ const fileName = filePath.replace(windowsPathReg, '/');
529
580
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
530
581
  if (serviceScript) {
531
582
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCompletionEnabled);
@@ -543,7 +594,8 @@ function decorateLanguageService(language, languageService) {
543
594
  }
544
595
  return details;
545
596
  };
546
- languageService.provideInlayHints = (fileName, span, preferences) => {
597
+ languageService.provideInlayHints = (filePath, span, preferences) => {
598
+ const fileName = filePath.replace(windowsPathReg, '/');
547
599
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
548
600
  if (serviceScript) {
549
601
  let start;
@@ -579,7 +631,8 @@ function decorateLanguageService(language, languageService) {
579
631
  return provideInlayHints(fileName, span, preferences);
580
632
  }
581
633
  };
582
- languageService.getFileReferences = fileName => {
634
+ languageService.getFileReferences = filePath => {
635
+ const fileName = filePath.replace(windowsPathReg, '/');
583
636
  const unresolved = getFileReferences(fileName);
584
637
  const resolved = unresolved
585
638
  .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
@@ -587,7 +640,7 @@ function decorateLanguageService(language, languageService) {
587
640
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
588
641
  };
589
642
  function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
590
- let results = [];
643
+ const results = [];
591
644
  const processedFilePositions = new Set();
592
645
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
593
646
  if (serviceScript) {
@@ -610,7 +663,7 @@ function decorateLanguageService(language, languageService) {
610
663
  if (!result) {
611
664
  return;
612
665
  }
613
- results = results.concat(result);
666
+ results.push(result);
614
667
  for (const ref of getLinkedCodes(result)) {
615
668
  processedFilePositions.add(ref[0] + ':' + ref[1]);
616
669
  const [virtualFile, sourceScript] = (0, utils_1.getServiceScript)(language, ref[0]);
@@ -1,4 +1,4 @@
1
- import { type Language } from '@volar/language-core';
1
+ import type { Language } from '@volar/language-core';
2
2
  import type * as ts from 'typescript';
3
- export declare function decorateLanguageServiceHost(language: Language, languageServiceHost: ts.LanguageServiceHost, ts: typeof import('typescript')): void;
3
+ export declare function decorateLanguageServiceHost(ts: typeof import('typescript'), language: Language, languageServiceHost: ts.LanguageServiceHost): void;
4
4
  export declare function searchExternalFiles(ts: typeof import('typescript'), project: ts.server.Project, exts: string[]): string[];
@@ -1,25 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.searchExternalFiles = exports.decorateLanguageServiceHost = void 0;
4
- const language_core_1 = require("@volar/language-core");
5
4
  const resolveModuleName_1 = require("../resolveModuleName");
6
- function decorateLanguageServiceHost(language, languageServiceHost, ts) {
7
- let extraProjectVersion = 0;
8
- const exts = language.plugins
5
+ function decorateLanguageServiceHost(ts, language, languageServiceHost) {
6
+ const extensions = language.plugins
9
7
  .map(plugin => plugin.typescript?.extraFileExtensions.map(ext => '.' + ext.extension) ?? [])
10
8
  .flat();
11
9
  const scripts = new Map();
10
+ const crashFileNames = new Set();
12
11
  const readDirectory = languageServiceHost.readDirectory?.bind(languageServiceHost);
13
12
  const resolveModuleNameLiterals = languageServiceHost.resolveModuleNameLiterals?.bind(languageServiceHost);
14
13
  const resolveModuleNames = languageServiceHost.resolveModuleNames?.bind(languageServiceHost);
15
- const getProjectVersion = languageServiceHost.getProjectVersion?.bind(languageServiceHost);
16
14
  const getScriptSnapshot = languageServiceHost.getScriptSnapshot.bind(languageServiceHost);
17
15
  const getScriptKind = languageServiceHost.getScriptKind?.bind(languageServiceHost);
18
16
  // path completion
19
17
  if (readDirectory) {
20
18
  languageServiceHost.readDirectory = (path, extensions, exclude, include, depth) => {
21
19
  if (extensions) {
22
- for (const ext of exts) {
20
+ for (const ext of extensions) {
23
21
  if (!extensions.includes(ext)) {
24
22
  extensions = [...extensions, ...ext];
25
23
  }
@@ -28,34 +26,33 @@ function decorateLanguageServiceHost(language, languageServiceHost, ts) {
28
26
  return readDirectory(path, extensions, exclude, include, depth);
29
27
  };
30
28
  }
31
- if (language.plugins.some(language => language.typescript?.extraFileExtensions.length)) {
29
+ if (extensions.length) {
32
30
  const resolveModuleName = (0, resolveModuleName_1.createResolveModuleName)(ts, languageServiceHost, language.plugins, fileName => language.scripts.get(fileName));
31
+ const getCanonicalFileName = languageServiceHost.useCaseSensitiveFileNames?.()
32
+ ? (fileName) => fileName
33
+ : (fileName) => fileName.toLowerCase();
34
+ const moduleResolutionCache = ts.createModuleResolutionCache(languageServiceHost.getCurrentDirectory(), getCanonicalFileName, languageServiceHost.getCompilationSettings());
33
35
  if (resolveModuleNameLiterals) {
34
36
  languageServiceHost.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options, ...rest) => {
35
- if (moduleLiterals.every(name => !exts.some(ext => name.text.endsWith(ext)))) {
37
+ if (moduleLiterals.every(name => !extensions.some(ext => name.text.endsWith(ext)))) {
36
38
  return resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, ...rest);
37
39
  }
38
40
  return moduleLiterals.map(moduleLiteral => {
39
- return resolveModuleName(moduleLiteral.text, containingFile, options, undefined, redirectedReference);
41
+ return resolveModuleName(moduleLiteral.text, containingFile, options, moduleResolutionCache, redirectedReference);
40
42
  });
41
43
  };
42
44
  }
43
45
  if (resolveModuleNames) {
44
46
  languageServiceHost.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, options, containingSourceFile) => {
45
- if (moduleNames.every(name => !exts.some(ext => name.endsWith(ext)))) {
47
+ if (moduleNames.every(name => !extensions.some(ext => name.endsWith(ext)))) {
46
48
  return resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, options, containingSourceFile);
47
49
  }
48
50
  return moduleNames.map(moduleName => {
49
- return resolveModuleName(moduleName, containingFile, options, undefined, redirectedReference).resolvedModule;
51
+ return resolveModuleName(moduleName, containingFile, options, moduleResolutionCache, redirectedReference).resolvedModule;
50
52
  });
51
53
  };
52
54
  }
53
55
  }
54
- if (getProjectVersion) {
55
- languageServiceHost.getProjectVersion = () => {
56
- return getProjectVersion() + ':' + extraProjectVersion;
57
- };
58
- }
59
56
  languageServiceHost.getScriptSnapshot = fileName => {
60
57
  const virtualScript = updateVirtualScript(fileName);
61
58
  if (virtualScript) {
@@ -73,46 +70,44 @@ function decorateLanguageServiceHost(language, languageServiceHost, ts) {
73
70
  };
74
71
  }
75
72
  function updateVirtualScript(fileName) {
76
- const version = languageServiceHost.getScriptVersion(fileName);
77
- if (version !== scripts.get(fileName)?.[0]) {
78
- let extension = '.ts';
79
- let snapshotSnapshot;
80
- let scriptKind = ts.ScriptKind.TS;
81
- const snapshot = getScriptSnapshot(fileName);
82
- if (snapshot) {
83
- extraProjectVersion++;
84
- const sourceScript = language.scripts.set(fileName, (0, language_core_1.resolveCommonLanguageId)(fileName), snapshot);
85
- if (sourceScript.generated) {
86
- const text = snapshot.getText(0, snapshot.getLength());
87
- let patchedText = text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
88
- const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
89
- if (serviceScript) {
90
- extension = serviceScript.extension;
91
- scriptKind = serviceScript.scriptKind;
92
- patchedText += serviceScript.code.snapshot.getText(0, serviceScript.code.snapshot.getLength());
93
- }
94
- snapshotSnapshot = ts.ScriptSnapshot.fromString(patchedText);
95
- if (sourceScript.generated.languagePlugin.typescript?.getExtraServiceScripts) {
96
- console.warn('getExtraScripts() is not available in this use case.');
97
- }
73
+ if (crashFileNames.has(fileName)) {
74
+ return;
75
+ }
76
+ let version;
77
+ try {
78
+ version = languageServiceHost.getScriptVersion(fileName);
79
+ }
80
+ catch {
81
+ // fix https://github.com/vuejs/language-tools/issues/4278
82
+ crashFileNames.add(fileName);
83
+ }
84
+ if (version === undefined) {
85
+ // somehow getScriptVersion returns undefined
86
+ return;
87
+ }
88
+ let script = scripts.get(fileName);
89
+ if (!script || script[0] !== version) {
90
+ script = [version];
91
+ const sourceScript = language.scripts.get(fileName);
92
+ if (sourceScript?.generated) {
93
+ const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
94
+ if (serviceScript) {
95
+ const sourceContents = sourceScript.snapshot.getText(0, sourceScript.snapshot.getLength());
96
+ let virtualContents = sourceContents.split('\n').map(line => ' '.repeat(line.length)).join('\n');
97
+ virtualContents += serviceScript.code.snapshot.getText(0, serviceScript.code.snapshot.getLength());
98
+ script[1] = {
99
+ extension: serviceScript.extension,
100
+ kind: serviceScript.scriptKind,
101
+ snapshot: ts.ScriptSnapshot.fromString(virtualContents),
102
+ };
103
+ }
104
+ if (sourceScript.generated.languagePlugin.typescript?.getExtraServiceScripts) {
105
+ console.warn('getExtraServiceScripts() is not available in TS plugin.');
98
106
  }
99
107
  }
100
- else if (language.scripts.get(fileName)) {
101
- extraProjectVersion++;
102
- language.scripts.delete(fileName);
103
- }
104
- if (snapshotSnapshot) {
105
- scripts.set(fileName, [
106
- version,
107
- {
108
- extension,
109
- snapshot: snapshotSnapshot,
110
- kind: scriptKind,
111
- }
112
- ]);
113
- }
108
+ scripts.set(fileName, script);
114
109
  }
115
- return scripts.get(fileName)?.[1];
110
+ return script[1];
116
111
  }
117
112
  }
118
113
  exports.decorateLanguageServiceHost = decorateLanguageServiceHost;
@@ -9,6 +9,7 @@ function decorateProgram(language, program) {
9
9
  const getSyntacticDiagnostics = program.getSyntacticDiagnostics;
10
10
  const getSemanticDiagnostics = program.getSemanticDiagnostics;
11
11
  const getGlobalDiagnostics = program.getGlobalDiagnostics;
12
+ const getSourceFileByPath = program.getSourceFileByPath;
12
13
  // for tsc --noEmit --watch
13
14
  // @ts-ignore
14
15
  const getBindAndCheckDiagnostics = program.getBindAndCheckDiagnostics;
@@ -17,31 +18,39 @@ function decorateProgram(language, program) {
17
18
  return {
18
19
  ...result,
19
20
  diagnostics: result.diagnostics
20
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
21
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
21
22
  .filter(utils_1.notEmpty),
22
23
  };
23
24
  };
24
25
  program.getSyntacticDiagnostics = (sourceFile, cancellationToken) => {
25
26
  return getSyntacticDiagnostics(sourceFile, cancellationToken)
26
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
27
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
27
28
  .filter(utils_1.notEmpty);
28
29
  };
29
30
  program.getSemanticDiagnostics = (sourceFile, cancellationToken) => {
30
31
  return getSemanticDiagnostics(sourceFile, cancellationToken)
31
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
32
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
32
33
  .filter(utils_1.notEmpty);
33
34
  };
34
35
  program.getGlobalDiagnostics = cancellationToken => {
35
36
  return getGlobalDiagnostics(cancellationToken)
36
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
37
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
37
38
  .filter(utils_1.notEmpty);
38
39
  };
39
40
  // @ts-ignore
40
41
  program.getBindAndCheckDiagnostics = (sourceFile, cancellationToken) => {
41
42
  return getBindAndCheckDiagnostics(sourceFile, cancellationToken)
42
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
43
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
43
44
  .filter(utils_1.notEmpty);
44
45
  };
46
+ // fix https://github.com/vuejs/language-tools/issues/4099 with `incremental`
47
+ program.getSourceFileByPath = path => {
48
+ const sourceFile = getSourceFileByPath(path);
49
+ if (sourceFile) {
50
+ (0, transform_1.fillSourceFileText)(language, sourceFile);
51
+ }
52
+ return sourceFile;
53
+ };
45
54
  }
46
55
  exports.decorateProgram = decorateProgram;
47
56
  //# sourceMappingURL=decorateProgram.js.map
@@ -1,3 +1,2 @@
1
1
  import type * as ts from 'typescript';
2
- export declare function dedupeReferencedSymbols<T extends ts.ReferencedSymbol>(items: T[]): T[];
3
2
  export declare function dedupeDocumentSpans<T extends ts.DocumentSpan>(items: T[]): T[];
@@ -1,14 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dedupeDocumentSpans = exports.dedupeReferencedSymbols = void 0;
4
- function dedupeReferencedSymbols(items) {
5
- return dedupe(items, item => [
6
- item.definition.fileName,
7
- item.definition.textSpan.start,
8
- item.definition.textSpan.length,
9
- ].join(':'));
10
- }
11
- exports.dedupeReferencedSymbols = dedupeReferencedSymbols;
3
+ exports.dedupeDocumentSpans = void 0;
12
4
  function dedupeDocumentSpans(items) {
13
5
  return dedupe(items, item => [
14
6
  item.fileName,