@volar/typescript 2.2.0-alpha.9 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ import type { LanguagePlugin } from "@volar/language-core";
2
+ export declare const fileLanguageIdProviderPlugin: LanguagePlugin;
package/lib/common.js ADDED
@@ -0,0 +1,20 @@
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
+ case 'json': return 'json';
17
+ }
18
+ },
19
+ };
20
+ //# 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,16 @@ 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, mapping] of (0, transform_1.toGeneratedOffsets)(sourceScript, map, position)) {
320
+ if (!(0, language_core_1.isRenameEnabled)(mapping.data)) {
321
+ continue;
322
+ }
323
+ const info = getRenameInfo(fileName, generateOffset, options);
284
324
  if (info.canRename) {
285
325
  const span = (0, transform_1.transformTextSpan)(sourceScript, map, info.triggerSpan, language_core_1.isRenameEnabled);
286
326
  if (span) {
@@ -289,9 +329,12 @@ function decorateLanguageService(language, languageService) {
289
329
  }
290
330
  }
291
331
  else {
292
- return info;
332
+ failed = info;
293
333
  }
294
334
  }
335
+ if (failed) {
336
+ return failed;
337
+ }
295
338
  return {
296
339
  canRename: false,
297
340
  localizedErrorMessage: 'Failed to get rename locations',
@@ -301,8 +344,9 @@ function decorateLanguageService(language, languageService) {
301
344
  return getRenameInfo(fileName, position, options);
302
345
  }
303
346
  };
304
- languageService.getCodeFixesAtPosition = (fileName, start, end, errorCodes, formatOptions, preferences) => {
347
+ languageService.getCodeFixesAtPosition = (filePath, start, end, errorCodes, formatOptions, preferences) => {
305
348
  let fixes = [];
349
+ const fileName = filePath.replace(windowsPathReg, '/');
306
350
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
307
351
  if (serviceScript) {
308
352
  const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isCodeActionsEnabled);
@@ -320,7 +364,8 @@ function decorateLanguageService(language, languageService) {
320
364
  });
321
365
  return fixes;
322
366
  };
323
- languageService.getEncodedSemanticClassifications = (fileName, span, format) => {
367
+ languageService.getEncodedSemanticClassifications = (filePath, span, format) => {
368
+ const fileName = filePath.replace(windowsPathReg, '/');
324
369
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
325
370
  if (serviceScript) {
326
371
  let start;
@@ -354,22 +399,26 @@ function decorateLanguageService(language, languageService) {
354
399
  return getEncodedSemanticClassifications(fileName, span, format);
355
400
  }
356
401
  };
357
- languageService.getSyntacticDiagnostics = fileName => {
402
+ languageService.getSyntacticDiagnostics = filePath => {
403
+ const fileName = filePath.replace(windowsPathReg, '/');
358
404
  return getSyntacticDiagnostics(fileName)
359
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
405
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, false))
360
406
  .filter(utils_1.notEmpty);
361
407
  };
362
- languageService.getSemanticDiagnostics = fileName => {
408
+ languageService.getSemanticDiagnostics = filePath => {
409
+ const fileName = filePath.replace(windowsPathReg, '/');
363
410
  return getSemanticDiagnostics(fileName)
364
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
411
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, false))
365
412
  .filter(utils_1.notEmpty);
366
413
  };
367
- languageService.getSuggestionDiagnostics = fileName => {
414
+ languageService.getSuggestionDiagnostics = filePath => {
415
+ const fileName = filePath.replace(windowsPathReg, '/');
368
416
  return getSuggestionDiagnostics(fileName)
369
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
417
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, false))
370
418
  .filter(utils_1.notEmpty);
371
419
  };
372
- languageService.getDefinitionAndBoundSpan = (fileName, position) => {
420
+ languageService.getDefinitionAndBoundSpan = (filePath, position) => {
421
+ const fileName = filePath.replace(windowsPathReg, '/');
373
422
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAndBoundSpan(fileName, position), function* (result) {
374
423
  for (const ref of result.definitions ?? []) {
375
424
  yield [ref.fileName, ref.textSpan.start];
@@ -392,7 +441,8 @@ function decorateLanguageService(language, languageService) {
392
441
  definitions: (0, dedupe_1.dedupeDocumentSpans)(definitions),
393
442
  };
394
443
  };
395
- languageService.findReferences = (fileName, position) => {
444
+ languageService.findReferences = (filePath, position) => {
445
+ const fileName = filePath.replace(windowsPathReg, '/');
396
446
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => findReferences(fileName, position), function* (result) {
397
447
  for (const ref of result) {
398
448
  for (const reference of ref.references) {
@@ -403,20 +453,18 @@ function decorateLanguageService(language, languageService) {
403
453
  const resolved = unresolved
404
454
  .flat()
405
455
  .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);
456
+ const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled, true);
457
+ return {
458
+ definition,
459
+ references: symbol.references
460
+ .map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled))
461
+ .filter(utils_1.notEmpty),
462
+ };
463
+ });
464
+ return resolved;
418
465
  };
419
- languageService.getDefinitionAtPosition = (fileName, position) => {
466
+ languageService.getDefinitionAtPosition = (filePath, position) => {
467
+ const fileName = filePath.replace(windowsPathReg, '/');
420
468
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAtPosition(fileName, position), function* (result) {
421
469
  for (const ref of result) {
422
470
  yield [ref.fileName, ref.textSpan.start];
@@ -428,7 +476,8 @@ function decorateLanguageService(language, languageService) {
428
476
  .filter(utils_1.notEmpty);
429
477
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
430
478
  };
431
- languageService.getTypeDefinitionAtPosition = (fileName, position) => {
479
+ languageService.getTypeDefinitionAtPosition = (filePath, position) => {
480
+ const fileName = filePath.replace(windowsPathReg, '/');
432
481
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, position => getTypeDefinitionAtPosition(fileName, position), function* (result) {
433
482
  for (const ref of result) {
434
483
  yield [ref.fileName, ref.textSpan.start];
@@ -440,7 +489,8 @@ function decorateLanguageService(language, languageService) {
440
489
  .filter(utils_1.notEmpty);
441
490
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
442
491
  };
443
- languageService.getImplementationAtPosition = (fileName, position) => {
492
+ languageService.getImplementationAtPosition = (filePath, position) => {
493
+ const fileName = filePath.replace(windowsPathReg, '/');
444
494
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, position => getImplementationAtPosition(fileName, position), function* (result) {
445
495
  for (const ref of result) {
446
496
  yield [ref.fileName, ref.textSpan.start];
@@ -452,7 +502,8 @@ function decorateLanguageService(language, languageService) {
452
502
  .filter(utils_1.notEmpty);
453
503
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
454
504
  };
455
- languageService.findRenameLocations = (fileName, position, findInStrings, findInComments, preferences) => {
505
+ languageService.findRenameLocations = (filePath, position, findInStrings, findInComments, preferences) => {
506
+ const fileName = filePath.replace(windowsPathReg, '/');
456
507
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, position => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) {
457
508
  for (const ref of result) {
458
509
  yield [ref.fileName, ref.textSpan.start];
@@ -464,7 +515,8 @@ function decorateLanguageService(language, languageService) {
464
515
  .filter(utils_1.notEmpty);
465
516
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
466
517
  };
467
- languageService.getReferencesAtPosition = (fileName, position) => {
518
+ languageService.getReferencesAtPosition = (filePath, position) => {
519
+ const fileName = filePath.replace(windowsPathReg, '/');
468
520
  const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => getReferencesAtPosition(fileName, position), function* (result) {
469
521
  for (const ref of result) {
470
522
  yield [ref.fileName, ref.textSpan.start];
@@ -476,47 +528,41 @@ function decorateLanguageService(language, languageService) {
476
528
  .filter(utils_1.notEmpty);
477
529
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
478
530
  };
479
- languageService.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
531
+ languageService.getCompletionsAtPosition = (filePath, position, options, formattingSettings) => {
532
+ const fileName = filePath.replace(windowsPathReg, '/');
480
533
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
481
534
  if (serviceScript) {
482
- let mainResult;
483
- let additionalResults = [];
484
- let isAdditional;
485
- const generatedOffset = (0, transform_1.toGeneratedOffset)(sourceScript, 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;
535
+ const results = [];
536
+ for (const [generatedOffset, mapping] of (0, transform_1.toGeneratedOffsets)(sourceScript, map, position)) {
537
+ if (!(0, language_core_1.isCompletionEnabled)(mapping.data)) {
538
+ continue;
492
539
  }
493
- return true;
494
- });
495
- if (generatedOffset !== undefined) {
496
540
  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)(sourceScript, map, entry.replacementSpan, language_core_1.isCompletionEnabled);
500
- }
501
- result.optionalReplacementSpan = result.optionalReplacementSpan && (0, transform_1.transformTextSpan)(sourceScript, map, result.optionalReplacementSpan, language_core_1.isCompletionEnabled);
502
- if (isAdditional) {
503
- additionalResults.push(result);
504
- }
505
- else {
506
- mainResult = result;
507
- }
541
+ if (!result || !result.entries.length) {
542
+ continue;
543
+ }
544
+ if (typeof mapping.data.completion === 'object' && mapping.data.completion.onlyImport) {
545
+ result.entries = result.entries.filter(entry => !!entry.sourceDisplay);
546
+ }
547
+ for (const entry of result.entries) {
548
+ entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(sourceScript, map, entry.replacementSpan, language_core_1.isCompletionEnabled);
549
+ }
550
+ result.optionalReplacementSpan = result.optionalReplacementSpan
551
+ && (0, transform_1.transformTextSpan)(sourceScript, map, result.optionalReplacementSpan, language_core_1.isCompletionEnabled);
552
+ const isAdditional = typeof mapping.data.completion === 'object' && mapping.data.completion.isAdditional;
553
+ if (isAdditional) {
554
+ results.push(result);
555
+ }
556
+ else {
557
+ results.splice(0, 0, result);
508
558
  }
509
559
  }
510
- if (!mainResult && additionalResults.length) {
511
- mainResult = additionalResults.shift();
512
- }
513
- if (mainResult) {
560
+ if (results.length) {
514
561
  return {
515
- ...mainResult,
516
- entries: [
517
- ...mainResult.entries,
518
- ...additionalResults.map(additionalResult => additionalResult.entries).flat(),
519
- ],
562
+ ...results[0],
563
+ entries: results
564
+ .map(additionalResult => additionalResult.entries)
565
+ .flat(),
520
566
  };
521
567
  }
522
568
  }
@@ -524,8 +570,9 @@ function decorateLanguageService(language, languageService) {
524
570
  return getCompletionsAtPosition(fileName, position, options, formattingSettings);
525
571
  }
526
572
  };
527
- languageService.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
573
+ languageService.getCompletionEntryDetails = (filePath, position, entryName, formatOptions, source, preferences, data) => {
528
574
  let details;
575
+ const fileName = filePath.replace(windowsPathReg, '/');
529
576
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
530
577
  if (serviceScript) {
531
578
  const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCompletionEnabled);
@@ -543,7 +590,8 @@ function decorateLanguageService(language, languageService) {
543
590
  }
544
591
  return details;
545
592
  };
546
- languageService.provideInlayHints = (fileName, span, preferences) => {
593
+ languageService.provideInlayHints = (filePath, span, preferences) => {
594
+ const fileName = filePath.replace(windowsPathReg, '/');
547
595
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
548
596
  if (serviceScript) {
549
597
  let start;
@@ -579,7 +627,8 @@ function decorateLanguageService(language, languageService) {
579
627
  return provideInlayHints(fileName, span, preferences);
580
628
  }
581
629
  };
582
- languageService.getFileReferences = fileName => {
630
+ languageService.getFileReferences = filePath => {
631
+ const fileName = filePath.replace(windowsPathReg, '/');
583
632
  const unresolved = getFileReferences(fileName);
584
633
  const resolved = unresolved
585
634
  .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled))
@@ -587,7 +636,7 @@ function decorateLanguageService(language, languageService) {
587
636
  return (0, dedupe_1.dedupeDocumentSpans)(resolved);
588
637
  };
589
638
  function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
590
- let results = [];
639
+ const results = [];
591
640
  const processedFilePositions = new Set();
592
641
  const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName);
593
642
  if (serviceScript) {
@@ -610,7 +659,7 @@ function decorateLanguageService(language, languageService) {
610
659
  if (!result) {
611
660
  return;
612
661
  }
613
- results = results.concat(result);
662
+ results.push(result);
614
663
  for (const ref of getLinkedCodes(result)) {
615
664
  processedFilePositions.add(ref[0] + ':' + ref[1]);
616
665
  const [virtualFile, sourceScript] = (0, utils_1.getServiceScript)(language, ref[0]);
@@ -7,6 +7,7 @@ function decorateLanguageServiceHost(ts, language, languageServiceHost) {
7
7
  .map(plugin => plugin.typescript?.extraFileExtensions.map(ext => '.' + ext.extension) ?? [])
8
8
  .flat();
9
9
  const scripts = new Map();
10
+ const crashFileNames = new Set();
10
11
  const readDirectory = languageServiceHost.readDirectory?.bind(languageServiceHost);
11
12
  const resolveModuleNameLiterals = languageServiceHost.resolveModuleNameLiterals?.bind(languageServiceHost);
12
13
  const resolveModuleNames = languageServiceHost.resolveModuleNames?.bind(languageServiceHost);
@@ -69,8 +70,19 @@ function decorateLanguageServiceHost(ts, language, languageServiceHost) {
69
70
  };
70
71
  }
71
72
  function updateVirtualScript(fileName) {
72
- const version = languageServiceHost.getScriptVersion(fileName);
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
+ }
73
84
  if (version === undefined) {
85
+ // somehow getScriptVersion returns undefined
74
86
  return;
75
87
  }
76
88
  let script = scripts.get(fileName);
@@ -18,29 +18,29 @@ function decorateProgram(language, program) {
18
18
  return {
19
19
  ...result,
20
20
  diagnostics: result.diagnostics
21
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
21
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
22
22
  .filter(utils_1.notEmpty),
23
23
  };
24
24
  };
25
25
  program.getSyntacticDiagnostics = (sourceFile, cancellationToken) => {
26
26
  return getSyntacticDiagnostics(sourceFile, cancellationToken)
27
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
27
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
28
28
  .filter(utils_1.notEmpty);
29
29
  };
30
30
  program.getSemanticDiagnostics = (sourceFile, cancellationToken) => {
31
31
  return getSemanticDiagnostics(sourceFile, cancellationToken)
32
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
32
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
33
33
  .filter(utils_1.notEmpty);
34
34
  };
35
35
  program.getGlobalDiagnostics = cancellationToken => {
36
36
  return getGlobalDiagnostics(cancellationToken)
37
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
37
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
38
38
  .filter(utils_1.notEmpty);
39
39
  };
40
40
  // @ts-ignore
41
41
  program.getBindAndCheckDiagnostics = (sourceFile, cancellationToken) => {
42
42
  return getBindAndCheckDiagnostics(sourceFile, cancellationToken)
43
- .map(d => (0, transform_1.transformDiagnostic)(language, d))
43
+ .map(d => (0, transform_1.transformDiagnostic)(language, d, true))
44
44
  .filter(utils_1.notEmpty);
45
45
  };
46
46
  // fix https://github.com/vuejs/language-tools/issues/4099 with `incremental`
@@ -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,
@@ -1,3 +1,3 @@
1
1
  import { LanguagePlugin } from '@volar/language-core';
2
2
  import type * as ts from 'typescript';
3
- export declare function proxyCreateProgram(ts: typeof import('typescript'), original: typeof ts['createProgram'], getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[], getLanguageId: (fileName: string) => string): typeof import("typescript").createProgram;
3
+ export declare function proxyCreateProgram(ts: typeof import('typescript'), original: typeof ts['createProgram'], getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[]): typeof import("typescript").createProgram;
@@ -4,6 +4,7 @@ exports.proxyCreateProgram = void 0;
4
4
  const language_core_1 = require("@volar/language-core");
5
5
  const resolveModuleName_1 = require("../resolveModuleName");
6
6
  const decorateProgram_1 = require("./decorateProgram");
7
+ const common_1 = require("../common");
7
8
  const arrayEqual = (a, b) => {
8
9
  if (a.length !== b.length) {
9
10
  return false;
@@ -28,7 +29,7 @@ const objectEqual = (a, b) => {
28
29
  }
29
30
  return true;
30
31
  };
31
- function proxyCreateProgram(ts, original, getLanguagePlugins, getLanguageId) {
32
+ function proxyCreateProgram(ts, original, getLanguagePlugins) {
32
33
  const sourceFileSnapshots = new Map();
33
34
  const parsedSourceFiles = new WeakMap();
34
35
  let lastOptions;
@@ -47,7 +48,10 @@ function proxyCreateProgram(ts, original, getLanguagePlugins, getLanguageId) {
47
48
  moduleResolutionCache = ts.createModuleResolutionCache(options.host.getCurrentDirectory(), options.host.getCanonicalFileName, options.options);
48
49
  lastOptions = options;
49
50
  languagePlugins = getLanguagePlugins(ts, options);
50
- language = (0, language_core_1.createLanguage)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
51
+ language = (0, language_core_1.createLanguage)([
52
+ ...languagePlugins,
53
+ common_1.fileLanguageIdProviderPlugin,
54
+ ], ts.sys.useCaseSensitiveFileNames, fileName => {
51
55
  if (!sourceFileSnapshots.has(fileName)) {
52
56
  const sourceFileText = originalHost.readFile(fileName);
53
57
  if (sourceFileText !== undefined) {
@@ -69,7 +73,7 @@ function proxyCreateProgram(ts, original, getLanguagePlugins, getLanguageId) {
69
73
  }
70
74
  const snapshot = sourceFileSnapshots.get(fileName)?.[1];
71
75
  if (snapshot) {
72
- language.scripts.set(fileName, getLanguageId(fileName), snapshot);
76
+ language.scripts.set(fileName, snapshot);
73
77
  }
74
78
  else {
75
79
  language.scripts.delete(fileName);
@@ -1,7 +1,7 @@
1
1
  import { Language, CodeInformation, SourceMap, SourceScript } from '@volar/language-core';
2
2
  import type * as ts from 'typescript';
3
3
  export declare function transformCallHierarchyItem(language: Language, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem;
4
- export declare function transformDiagnostic<T extends ts.Diagnostic>(language: Language, diagnostic: T): T | undefined;
4
+ export declare function transformDiagnostic<T extends ts.Diagnostic>(language: Language, diagnostic: T, isTsc: boolean): T | undefined;
5
5
  export declare function fillSourceFileText(language: Language, sourceFile: ts.SourceFile): void;
6
6
  export declare function transformFileTextChanges(language: Language, changes: ts.FileTextChanges, filter: (data: CodeInformation) => boolean): ts.FileTextChanges | undefined;
7
7
  export declare function transformDocumentSpan<T extends ts.DocumentSpan>(language: Language, documentSpan: T, filter: (data: CodeInformation) => boolean, shouldFallback?: boolean): T | undefined;
@@ -13,3 +13,4 @@ export declare function transformTextChange(sourceScript: SourceScript, map: Sou
13
13
  export declare function transformTextSpan(sourceScript: SourceScript, map: SourceMap<CodeInformation>, textSpan: ts.TextSpan, filter: (data: CodeInformation) => boolean): ts.TextSpan | undefined;
14
14
  export declare function toSourceOffset(sourceScript: SourceScript, map: SourceMap, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
15
15
  export declare function toGeneratedOffset(sourceScript: SourceScript, map: SourceMap, position: number, filter: (data: CodeInformation) => boolean): number | undefined;
16
+ export declare function toGeneratedOffsets(sourceScript: SourceScript, map: SourceMap<CodeInformation>, position: number): Generator<readonly [number, import("@volar/language-core").Mapping<CodeInformation>], void, unknown>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toGeneratedOffset = exports.toSourceOffset = exports.transformTextSpan = exports.transformTextChange = exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = exports.fillSourceFileText = exports.transformDiagnostic = exports.transformCallHierarchyItem = void 0;
3
+ exports.toGeneratedOffsets = exports.toGeneratedOffset = exports.toSourceOffset = exports.transformTextSpan = exports.transformTextChange = exports.transformSpan = exports.transformDocumentSpan = exports.transformFileTextChanges = exports.fillSourceFileText = exports.transformDiagnostic = exports.transformCallHierarchyItem = void 0;
4
4
  const language_core_1 = require("@volar/language-core");
5
5
  const utils_1 = require("./utils");
6
6
  const transformedDiagnostics = new WeakMap();
@@ -15,13 +15,13 @@ function transformCallHierarchyItem(language, item, filter) {
15
15
  };
16
16
  }
17
17
  exports.transformCallHierarchyItem = transformCallHierarchyItem;
18
- function transformDiagnostic(language, diagnostic) {
18
+ function transformDiagnostic(language, diagnostic, isTsc) {
19
19
  if (!transformedDiagnostics.has(diagnostic)) {
20
20
  transformedDiagnostics.set(diagnostic, undefined);
21
21
  const { relatedInformation } = diagnostic;
22
22
  if (relatedInformation) {
23
23
  diagnostic.relatedInformation = relatedInformation
24
- .map(d => transformDiagnostic(language, d))
24
+ .map(d => transformDiagnostic(language, d, isTsc))
25
25
  .filter(utils_1.notEmpty);
26
26
  }
27
27
  if (diagnostic.file !== undefined
@@ -31,7 +31,9 @@ function transformDiagnostic(language, diagnostic) {
31
31
  if (serviceScript) {
32
32
  const sourceSpan = transformTextSpan(sourceScript, map, { start: diagnostic.start, length: diagnostic.length }, language_core_1.shouldReportDiagnostics);
33
33
  if (sourceSpan) {
34
- fillSourceFileText(language, diagnostic.file);
34
+ if (isTsc) {
35
+ fillSourceFileText(language, diagnostic.file);
36
+ }
35
37
  transformedDiagnostics.set(diagnostic, {
36
38
  ...diagnostic,
37
39
  start: sourceSpan.start,
@@ -61,7 +63,6 @@ function fillSourceFileText(language, sourceFile) {
61
63
  sourceFile.text = sourceScript.snapshot.getText(0, sourceScript.snapshot.getLength())
62
64
  + sourceFile.text.substring(sourceScript.snapshot.getLength());
63
65
  }
64
- return;
65
66
  }
66
67
  exports.fillSourceFileText = fillSourceFileText;
67
68
  function transformFileTextChanges(language, changes, filter) {
@@ -88,13 +89,10 @@ exports.transformFileTextChanges = transformFileTextChanges;
88
89
  function transformDocumentSpan(language, documentSpan, filter, shouldFallback) {
89
90
  let textSpan = transformSpan(language, documentSpan.fileName, documentSpan.textSpan, filter);
90
91
  if (!textSpan && shouldFallback) {
91
- const [serviceScript] = (0, utils_1.getServiceScript)(language, documentSpan.fileName);
92
- if (serviceScript) {
93
- textSpan = {
94
- fileName: documentSpan.fileName,
95
- textSpan: { start: 0, length: 0 },
96
- };
97
- }
92
+ textSpan = {
93
+ fileName: documentSpan.fileName,
94
+ textSpan: { start: 0, length: 0 },
95
+ };
98
96
  }
99
97
  if (!textSpan) {
100
98
  return;
@@ -174,4 +172,10 @@ function toGeneratedOffset(sourceScript, map, position, filter) {
174
172
  }
175
173
  }
176
174
  exports.toGeneratedOffset = toGeneratedOffset;
175
+ function* toGeneratedOffsets(sourceScript, map, position) {
176
+ for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
177
+ yield [generateOffset + sourceScript.snapshot.getLength(), mapping];
178
+ }
179
+ }
180
+ exports.toGeneratedOffsets = toGeneratedOffsets;
177
181
  //# sourceMappingURL=transform.js.map
@@ -5,10 +5,14 @@ const language_core_1 = require("@volar/language-core");
5
5
  const language_core_2 = require("@volar/language-core");
6
6
  const path = require("path-browserify");
7
7
  const resolveModuleName_1 = require("../resolveModuleName");
8
+ const common_1 = require("../common");
8
9
  const scriptVersions = new Map();
9
10
  const fsFileSnapshots = new Map();
10
11
  function createTypeScriptLanguage(ts, languagePlugins, projectHost) {
11
- const language = (0, language_core_1.createLanguage)(languagePlugins, projectHost.useCaseSensitiveFileNames, scriptId => {
12
+ const language = (0, language_core_1.createLanguage)([
13
+ ...languagePlugins,
14
+ common_1.fileLanguageIdProviderPlugin,
15
+ ], projectHost.useCaseSensitiveFileNames, scriptId => {
12
16
  const fileName = projectHost.scriptIdToFileName(scriptId);
13
17
  // opened files
14
18
  let snapshot = projectHost.getScriptSnapshot(fileName);
@@ -29,7 +33,7 @@ function createTypeScriptLanguage(ts, languagePlugins, projectHost) {
29
33
  snapshot = fsFileSnapshots.get(fileName)?.[1];
30
34
  }
31
35
  if (snapshot) {
32
- language.scripts.set(scriptId, projectHost.getLanguageId(scriptId), snapshot);
36
+ language.scripts.set(scriptId, snapshot);
33
37
  }
34
38
  else {
35
39
  language.scripts.delete(scriptId);
@@ -1,3 +1,3 @@
1
1
  import type * as ts from 'typescript';
2
2
  import { LanguagePlugin } from '@volar/language-core';
3
- export declare function createAsyncLanguageServicePlugin(extensions: string[], scriptKind: ts.ScriptKind, loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => Promise<LanguagePlugin[]>, getLanguageId: (fileName: string) => string): ts.server.PluginModuleFactory;
3
+ export declare function createAsyncLanguageServicePlugin(extensions: string[], scriptKind: ts.ScriptKind, loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => Promise<LanguagePlugin[]>): ts.server.PluginModuleFactory;
@@ -5,10 +5,11 @@ const decorateLanguageService_1 = require("../node/decorateLanguageService");
5
5
  const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
6
6
  const language_core_1 = require("@volar/language-core");
7
7
  const createLanguageServicePlugin_1 = require("./createLanguageServicePlugin");
8
+ const common_1 = require("../common");
8
9
  const externalFiles = new WeakMap();
9
10
  const decoratedLanguageServices = new WeakSet();
10
11
  const decoratedLanguageServiceHosts = new WeakSet();
11
- function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePlugins, getLanguageId) {
12
+ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePlugins) {
12
13
  return modules => {
13
14
  const { typescript: ts } = modules;
14
15
  const pluginModule = {
@@ -52,10 +53,19 @@ function createAsyncLanguageServicePlugin(extensions, scriptKind, loadLanguagePl
52
53
  };
53
54
  }
54
55
  loadLanguagePlugins(ts, info).then(languagePlugins => {
55
- const language = (0, language_core_1.createLanguage)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
56
+ const syncedScriptVersions = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
57
+ const language = (0, language_core_1.createLanguage)([
58
+ ...languagePlugins,
59
+ common_1.fileLanguageIdProviderPlugin,
60
+ ], ts.sys.useCaseSensitiveFileNames, fileName => {
61
+ const version = getScriptVersion(fileName);
62
+ if (syncedScriptVersions.get(fileName) === version) {
63
+ return;
64
+ }
65
+ syncedScriptVersions.set(fileName, version);
56
66
  const snapshot = getScriptSnapshot(fileName);
57
67
  if (snapshot) {
58
- language.scripts.set(fileName, getLanguageId(fileName), snapshot);
68
+ language.scripts.set(fileName, snapshot);
59
69
  }
60
70
  else {
61
71
  language.scripts.delete(fileName);
@@ -1,4 +1,4 @@
1
1
  import type * as ts from 'typescript';
2
2
  import { LanguagePlugin } from '@volar/language-core';
3
- export declare function createLanguageServicePlugin(loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => LanguagePlugin[], getLanguageId: (fileName: string) => string): ts.server.PluginModuleFactory;
3
+ export declare function createLanguageServicePlugin(loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => LanguagePlugin[]): ts.server.PluginModuleFactory;
4
4
  export declare function arrayItemsEqual(a: string[], b: string[]): boolean;
@@ -4,11 +4,12 @@ exports.arrayItemsEqual = exports.createLanguageServicePlugin = void 0;
4
4
  const decorateLanguageService_1 = require("../node/decorateLanguageService");
5
5
  const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
6
6
  const language_core_1 = require("@volar/language-core");
7
+ const common_1 = require("../common");
7
8
  const externalFiles = new WeakMap();
8
9
  const projectExternalFileExtensions = new WeakMap();
9
10
  const decoratedLanguageServices = new WeakSet();
10
11
  const decoratedLanguageServiceHosts = new WeakSet();
11
- function createLanguageServicePlugin(loadLanguagePlugins, getLanguageId) {
12
+ function createLanguageServicePlugin(loadLanguagePlugins) {
12
13
  return modules => {
13
14
  const { typescript: ts } = modules;
14
15
  const pluginModule = {
@@ -23,10 +24,20 @@ function createLanguageServicePlugin(loadLanguagePlugins, getLanguageId) {
23
24
  .flat();
24
25
  projectExternalFileExtensions.set(info.project, extensions);
25
26
  const getScriptSnapshot = info.languageServiceHost.getScriptSnapshot.bind(info.languageServiceHost);
26
- const language = (0, language_core_1.createLanguage)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
27
+ const getScriptVersion = info.languageServiceHost.getScriptVersion.bind(info.languageServiceHost);
28
+ const syncedScriptVersions = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
29
+ const language = (0, language_core_1.createLanguage)([
30
+ ...languagePlugins,
31
+ common_1.fileLanguageIdProviderPlugin,
32
+ ], ts.sys.useCaseSensitiveFileNames, fileName => {
33
+ const version = getScriptVersion(fileName);
34
+ if (syncedScriptVersions.get(fileName) === version) {
35
+ return;
36
+ }
37
+ syncedScriptVersions.set(fileName, version);
27
38
  const snapshot = getScriptSnapshot(fileName);
28
39
  if (snapshot) {
29
- language.scripts.set(fileName, getLanguageId(fileName), snapshot);
40
+ language.scripts.set(fileName, snapshot);
30
41
  }
31
42
  else {
32
43
  language.scripts.delete(fileName);
@@ -1,5 +1,4 @@
1
1
  import type * as ts from 'typescript';
2
2
  import type { LanguagePlugin } from '@volar/language-core';
3
3
  export declare let getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[];
4
- export declare let getLanguageId: (fileName: string) => string;
5
- export declare function runTsc(tscPath: string, extensions: string[], _getLanguagePlugins: typeof getLanguagePlugins, _getLanguageId: typeof getLanguageId): void;
4
+ export declare function runTsc(tscPath: string, extensions: string[], _getLanguagePlugins: typeof getLanguagePlugins): void;
@@ -1,14 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runTsc = exports.getLanguageId = exports.getLanguagePlugins = void 0;
3
+ exports.runTsc = exports.getLanguagePlugins = void 0;
4
4
  const fs = require("fs");
5
5
  let getLanguagePlugins = () => [];
6
6
  exports.getLanguagePlugins = getLanguagePlugins;
7
- let getLanguageId = () => 'ts';
8
- exports.getLanguageId = getLanguageId;
9
- function runTsc(tscPath, extensions, _getLanguagePlugins, _getLanguageId) {
7
+ function runTsc(tscPath, extensions, _getLanguagePlugins) {
10
8
  exports.getLanguagePlugins = _getLanguagePlugins;
11
- exports.getLanguageId = _getLanguageId;
12
9
  const proxyApiPath = require.resolve('../node/proxyCreateProgram');
13
10
  const readFileSync = fs.readFileSync;
14
11
  fs.readFileSync = (...args) => {
@@ -25,7 +22,6 @@ function runTsc(tscPath, extensions, _getLanguagePlugins, _getLanguageId) {
25
22
  `new Proxy({}, { get(_target, p, _receiver) { return eval(p); } } )`,
26
23
  `_createProgram`,
27
24
  `require(${JSON.stringify(__filename)}).getLanguagePlugins`,
28
- `require(${JSON.stringify(__filename)}).getLanguageId`,
29
25
  ].join(', ')
30
26
  + `);\n`
31
27
  + s.replace('createProgram', '_createProgram'));
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createResolveModuleName = void 0;
4
4
  function createResolveModuleName(ts, host, languagePlugins, getSourceScript) {
5
- const toPatchResults = new Map();
5
+ const toSourceFileInfo = new Map();
6
6
  const moduleResolutionHost = {
7
7
  readFile: host.readFile.bind(host),
8
8
  directoryExists: host.directoryExists?.bind(host),
@@ -19,10 +19,28 @@ function createResolveModuleName(ts, host, languagePlugins, getSourceScript) {
19
19
  }
20
20
  for (const { extension } of typescript.extraFileExtensions) {
21
21
  if (fileName.endsWith(`.d.${extension}.ts`)) {
22
- const patchFileName = fileName.slice(0, -`.d.${extension}.ts`.length) + `.${extension}`;
23
- if (fileExists(patchFileName)) {
24
- toPatchResults.set(fileName, patchFileName);
25
- return true;
22
+ const sourceFileName = fileName.slice(0, -`.d.${extension}.ts`.length) + `.${extension}`;
23
+ if (fileExists(sourceFileName)) {
24
+ const sourceScript = getSourceScript(sourceFileName);
25
+ if (sourceScript?.generated) {
26
+ const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
27
+ if (serviceScript) {
28
+ const dtsPath = sourceFileName + '.d.ts';
29
+ if ((serviceScript.extension === '.js' || serviceScript.extension === '.jsx') && fileExists(dtsPath)) {
30
+ toSourceFileInfo.set(fileName, {
31
+ sourceFileName: dtsPath,
32
+ extension: '.ts',
33
+ });
34
+ }
35
+ else {
36
+ toSourceFileInfo.set(fileName, {
37
+ sourceFileName,
38
+ extension: serviceScript.extension,
39
+ });
40
+ }
41
+ return true;
42
+ }
43
+ }
26
44
  }
27
45
  }
28
46
  }
@@ -32,17 +50,14 @@ function createResolveModuleName(ts, host, languagePlugins, getSourceScript) {
32
50
  };
33
51
  return (moduleName, containingFile, compilerOptions, cache, redirectedReference, resolutionMode) => {
34
52
  const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost, cache, redirectedReference, resolutionMode);
35
- if (result.resolvedModule && toPatchResults.has(result.resolvedModule.resolvedFileName)) {
36
- result.resolvedModule.resolvedFileName = toPatchResults.get(result.resolvedModule.resolvedFileName);
37
- const sourceScript = getSourceScript(result.resolvedModule.resolvedFileName);
38
- if (sourceScript?.generated) {
39
- const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root);
40
- if (serviceScript) {
41
- result.resolvedModule.extension = serviceScript.extension;
42
- }
53
+ if (result.resolvedModule) {
54
+ const sourceFileInfo = toSourceFileInfo.get(result.resolvedModule.resolvedFileName);
55
+ if (sourceFileInfo) {
56
+ result.resolvedModule.resolvedFileName = sourceFileInfo.sourceFileName;
57
+ result.resolvedModule.extension = sourceFileInfo.extension;
43
58
  }
44
59
  }
45
- toPatchResults.clear();
60
+ toSourceFileInfo.clear();
46
61
  return result;
47
62
  };
48
63
  // fix https://github.com/vuejs/language-tools/issues/3332
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/typescript",
3
- "version": "2.2.0-alpha.9",
3
+ "version": "2.2.1",
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.2.0-alpha.9",
15
+ "@volar/language-core": "2.2.1",
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.2.0-alpha.9"
21
+ "@volar/language-service": "2.2.1"
22
22
  },
23
- "gitHead": "7373fb794012e219aae3948c730c004827b03021"
23
+ "gitHead": "629f686bda694077b236a0bcd0304437bb2eabf5"
24
24
  }
@@ -1,2 +0,0 @@
1
- import type * as ts from 'typescript';
2
- export declare function getDocumentRegistry(ts: typeof import('typescript'), useCaseSensitiveFileNames: boolean, currentDirectory: string): ts.DocumentRegistry;
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getDocumentRegistry = void 0;
4
- const documentRegistries = [];
5
- function getDocumentRegistry(ts, useCaseSensitiveFileNames, currentDirectory) {
6
- let documentRegistry = documentRegistries.find(item => item[0] === useCaseSensitiveFileNames && item[1] === currentDirectory)?.[2];
7
- if (!documentRegistry) {
8
- documentRegistry = ts.createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory);
9
- documentRegistries.push([useCaseSensitiveFileNames, currentDirectory, documentRegistry]);
10
- }
11
- return documentRegistry;
12
- }
13
- exports.getDocumentRegistry = getDocumentRegistry;
14
- //# sourceMappingURL=documentRegistry.js.map