@volar/typescript 2.0.0-alpha.9 → 2.0.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.
- package/lib/documentRegistry.d.ts +2 -2
- package/lib/node/decorateLanguageService.d.ts +3 -3
- package/lib/node/decorateLanguageService.js +47 -42
- package/lib/node/decorateLanguageServiceHost.d.ts +4 -4
- package/lib/node/decorateLanguageServiceHost.js +18 -15
- package/lib/node/decorateProgram.d.ts +3 -3
- package/lib/node/decorateProgram.js +1 -1
- package/lib/node/dedupe.d.ts +1 -1
- package/lib/node/proxyCreateProgram.d.ts +2 -2
- package/lib/node/proxyCreateProgram.js +15 -13
- package/lib/node/transform.d.ts +7 -7
- package/lib/node/transform.js +12 -10
- package/lib/node/utils.d.ts +2 -2
- package/lib/node/utils.js +7 -10
- package/lib/protocol/createProject.d.ts +6 -3
- package/lib/protocol/createProject.js +129 -122
- package/lib/protocol/createSys.d.ts +3 -3
- package/lib/protocol/createSys.js +11 -11
- package/lib/quickstart/createAsyncLanguageServicePlugin.d.ts +3 -0
- package/lib/quickstart/createAsyncLanguageServicePlugin.js +89 -0
- package/lib/quickstart/createLanguageServicePlugin.d.ts +4 -0
- package/lib/quickstart/createLanguageServicePlugin.js +70 -0
- package/lib/{starters → quickstart}/runTsc.d.ts +2 -2
- package/lib/{starters → quickstart}/runTsc.js +1 -1
- package/lib/typescript/core.js +16 -8
- package/lib/typescript/path.js +42 -21
- package/lib/typescript/utilities.js +6 -3
- package/package.json +4 -4
- package/lib/protocol/getProgram.d.ts +0 -3
- package/lib/protocol/getProgram.js +0 -146
- package/lib/starters/createAsyncTSServerPlugin.d.ts +0 -3
- package/lib/starters/createAsyncTSServerPlugin.js +0 -82
- package/lib/starters/createTSServerPlugin.d.ts +0 -7
- package/lib/starters/createTSServerPlugin.js +0 -60
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type * as ts from 'typescript
|
|
2
|
-
export declare function getDocumentRegistry(ts: typeof import('typescript
|
|
1
|
+
import type * as ts from 'typescript';
|
|
2
|
+
export declare function getDocumentRegistry(ts: typeof import('typescript'), useCaseSensitiveFileNames: boolean, currentDirectory: string): ts.DocumentRegistry;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type * as ts from 'typescript
|
|
3
|
-
export declare function decorateLanguageService(files:
|
|
1
|
+
import { FileRegistry } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
export declare function decorateLanguageService(files: FileRegistry, languageService: ts.LanguageService): void;
|
|
@@ -8,9 +8,9 @@ const transform_1 = require("./transform");
|
|
|
8
8
|
function decorateLanguageService(files, languageService) {
|
|
9
9
|
// ignored methods
|
|
10
10
|
const { getNavigationTree, getOutliningSpans, } = languageService;
|
|
11
|
-
languageService.getNavigationTree =
|
|
12
|
-
const [
|
|
13
|
-
if (
|
|
11
|
+
languageService.getNavigationTree = fileName => {
|
|
12
|
+
const [virtualCode] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
13
|
+
if (virtualCode) {
|
|
14
14
|
const tree = getNavigationTree(fileName);
|
|
15
15
|
tree.childItems = undefined;
|
|
16
16
|
return tree;
|
|
@@ -19,9 +19,9 @@ function decorateLanguageService(files, languageService) {
|
|
|
19
19
|
return getNavigationTree(fileName);
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
-
languageService.getOutliningSpans =
|
|
23
|
-
const [
|
|
24
|
-
if (
|
|
22
|
+
languageService.getOutliningSpans = fileName => {
|
|
23
|
+
const [virtualCode] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
24
|
+
if (virtualCode) {
|
|
25
25
|
return [];
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
@@ -31,8 +31,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
31
31
|
// methods
|
|
32
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;
|
|
33
33
|
languageService.prepareCallHierarchy = (fileName, position) => {
|
|
34
|
-
const [
|
|
35
|
-
if (
|
|
34
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
35
|
+
if (virtualCode) {
|
|
36
36
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
37
37
|
if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
|
|
38
38
|
const item = prepareCallHierarchy(fileName, generateOffset + sourceFile.snapshot.getLength());
|
|
@@ -51,8 +51,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
51
51
|
};
|
|
52
52
|
languageService.provideCallHierarchyIncomingCalls = (fileName, position) => {
|
|
53
53
|
let calls = [];
|
|
54
|
-
const [
|
|
55
|
-
if (
|
|
54
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
55
|
+
if (virtualCode) {
|
|
56
56
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
57
57
|
if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
|
|
58
58
|
calls = provideCallHierarchyIncomingCalls(fileName, generateOffset + sourceFile.snapshot.getLength());
|
|
@@ -76,8 +76,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
76
76
|
};
|
|
77
77
|
languageService.provideCallHierarchyOutgoingCalls = (fileName, position) => {
|
|
78
78
|
let calls = [];
|
|
79
|
-
const [
|
|
80
|
-
if (
|
|
79
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
80
|
+
if (virtualCode) {
|
|
81
81
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
82
82
|
if ((0, language_core_1.isCallHierarchyEnabled)(mapping.data)) {
|
|
83
83
|
calls = provideCallHierarchyOutgoingCalls(fileName, generateOffset + sourceFile.snapshot.getLength());
|
|
@@ -107,8 +107,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
107
107
|
return resolved;
|
|
108
108
|
};
|
|
109
109
|
languageService.getQuickInfoAtPosition = (fileName, position) => {
|
|
110
|
-
const [
|
|
111
|
-
if (
|
|
110
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
111
|
+
if (virtualCode) {
|
|
112
112
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
113
113
|
if ((0, language_core_1.isHoverEnabled)(mapping.data)) {
|
|
114
114
|
const result = getQuickInfoAtPosition(fileName, generateOffset + sourceFile.snapshot.getLength());
|
|
@@ -158,8 +158,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
158
158
|
return resolved;
|
|
159
159
|
};
|
|
160
160
|
languageService.getApplicableRefactors = (fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => {
|
|
161
|
-
const [
|
|
162
|
-
if (
|
|
161
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
162
|
+
if (virtualCode) {
|
|
163
163
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos)) {
|
|
164
164
|
if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
|
|
165
165
|
const por = typeof positionOrRange === 'number'
|
|
@@ -179,8 +179,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
179
179
|
};
|
|
180
180
|
languageService.getEditsForRefactor = (fileName, formatOptions, positionOrRange, refactorName, actionName, preferences) => {
|
|
181
181
|
let edits;
|
|
182
|
-
const [
|
|
183
|
-
if (
|
|
182
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
183
|
+
if (virtualCode) {
|
|
184
184
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos)) {
|
|
185
185
|
if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
|
|
186
186
|
const por = typeof positionOrRange === 'number'
|
|
@@ -204,8 +204,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
204
204
|
}
|
|
205
205
|
};
|
|
206
206
|
languageService.getRenameInfo = (fileName, position, options) => {
|
|
207
|
-
const [
|
|
208
|
-
if (
|
|
207
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
208
|
+
if (virtualCode) {
|
|
209
209
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
210
210
|
if ((0, language_core_1.isRenameEnabled)(mapping.data)) {
|
|
211
211
|
const info = getRenameInfo(fileName, generateOffset + sourceFile.snapshot.getLength(), options);
|
|
@@ -232,8 +232,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
232
232
|
};
|
|
233
233
|
languageService.getCodeFixesAtPosition = (fileName, start, end, errorCodes, formatOptions, preferences) => {
|
|
234
234
|
let fixes = [];
|
|
235
|
-
const [
|
|
236
|
-
if (
|
|
235
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
236
|
+
if (virtualCode) {
|
|
237
237
|
for (const [generateStart, mapping] of map.getGeneratedOffsets(start)) {
|
|
238
238
|
if ((0, language_core_1.isCodeActionsEnabled)(mapping.data)) {
|
|
239
239
|
for (const [generateEnd, mapping] of map.getGeneratedOffsets(end)) {
|
|
@@ -256,8 +256,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
256
256
|
return fixes;
|
|
257
257
|
};
|
|
258
258
|
languageService.getEncodedSemanticClassifications = (fileName, span, format) => {
|
|
259
|
-
const [
|
|
260
|
-
if (
|
|
259
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
260
|
+
if (virtualCode) {
|
|
261
261
|
let start;
|
|
262
262
|
let end;
|
|
263
263
|
for (const mapping of map.mappings) {
|
|
@@ -296,17 +296,17 @@ function decorateLanguageService(files, languageService) {
|
|
|
296
296
|
return getEncodedSemanticClassifications(fileName, span);
|
|
297
297
|
}
|
|
298
298
|
};
|
|
299
|
-
languageService.getSyntacticDiagnostics =
|
|
299
|
+
languageService.getSyntacticDiagnostics = fileName => {
|
|
300
300
|
return getSyntacticDiagnostics(fileName)
|
|
301
301
|
.map(d => (0, transform_1.transformDiagnostic)(files, d))
|
|
302
302
|
.filter(utils_1.notEmpty);
|
|
303
303
|
};
|
|
304
|
-
languageService.getSemanticDiagnostics =
|
|
304
|
+
languageService.getSemanticDiagnostics = fileName => {
|
|
305
305
|
return getSemanticDiagnostics(fileName)
|
|
306
306
|
.map(d => (0, transform_1.transformDiagnostic)(files, d))
|
|
307
307
|
.filter(utils_1.notEmpty);
|
|
308
308
|
};
|
|
309
|
-
languageService.getSuggestionDiagnostics =
|
|
309
|
+
languageService.getSuggestionDiagnostics = fileName => {
|
|
310
310
|
return getSuggestionDiagnostics(fileName)
|
|
311
311
|
.map(d => (0, transform_1.transformDiagnostic)(files, d))
|
|
312
312
|
.filter(utils_1.notEmpty);
|
|
@@ -320,8 +320,9 @@ function decorateLanguageService(files, languageService) {
|
|
|
320
320
|
const textSpan = unresolved
|
|
321
321
|
.map(s => (0, transform_1.transformSpan)(files, fileName, s.textSpan, language_core_1.isDefinitionEnabled)?.textSpan)
|
|
322
322
|
.filter(utils_1.notEmpty)[0];
|
|
323
|
-
if (!textSpan)
|
|
323
|
+
if (!textSpan) {
|
|
324
324
|
return;
|
|
325
|
+
}
|
|
325
326
|
const definitions = unresolved
|
|
326
327
|
.map(s => s.definitions
|
|
327
328
|
?.map(s => (0, transform_1.transformDocumentSpan)(files, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName))
|
|
@@ -418,8 +419,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
418
419
|
return (0, dedupe_1.dedupeDocumentSpans)(resolved);
|
|
419
420
|
};
|
|
420
421
|
languageService.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
|
|
421
|
-
const [
|
|
422
|
-
if (
|
|
422
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
423
|
+
if (virtualCode) {
|
|
423
424
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
424
425
|
if ((0, language_core_1.isCompletionEnabled)(mapping.data)) {
|
|
425
426
|
const result = getCompletionsAtPosition(fileName, generateOffset + sourceFile.snapshot.getLength(), options, formattingSettings);
|
|
@@ -439,8 +440,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
439
440
|
};
|
|
440
441
|
languageService.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
|
|
441
442
|
let details;
|
|
442
|
-
const [
|
|
443
|
-
if (
|
|
443
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
444
|
+
if (virtualCode) {
|
|
444
445
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
445
446
|
if ((0, language_core_1.isCompletionEnabled)(mapping.data)) {
|
|
446
447
|
details = getCompletionEntryDetails(fileName, generateOffset + sourceFile.snapshot.getLength(), entryName, formatOptions, source, preferences, data);
|
|
@@ -459,8 +460,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
459
460
|
return details;
|
|
460
461
|
};
|
|
461
462
|
languageService.provideInlayHints = (fileName, span, preferences) => {
|
|
462
|
-
const [
|
|
463
|
-
if (
|
|
463
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
464
|
+
if (virtualCode) {
|
|
464
465
|
let start;
|
|
465
466
|
let end;
|
|
466
467
|
for (const mapping of map.mappings) {
|
|
@@ -496,7 +497,7 @@ function decorateLanguageService(files, languageService) {
|
|
|
496
497
|
return provideInlayHints(fileName, span, preferences);
|
|
497
498
|
}
|
|
498
499
|
};
|
|
499
|
-
languageService.getFileReferences =
|
|
500
|
+
languageService.getFileReferences = fileName => {
|
|
500
501
|
const unresolved = getFileReferences(fileName);
|
|
501
502
|
const resolved = unresolved
|
|
502
503
|
.map(s => (0, transform_1.transformDocumentSpan)(files, s, language_core_1.isReferencesEnabled))
|
|
@@ -506,8 +507,8 @@ function decorateLanguageService(files, languageService) {
|
|
|
506
507
|
function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) {
|
|
507
508
|
let results = [];
|
|
508
509
|
const processedFilePositions = new Set();
|
|
509
|
-
const [
|
|
510
|
-
if (
|
|
510
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
511
|
+
if (virtualCode) {
|
|
511
512
|
for (const [generateOffset, mapping] of map.getGeneratedOffsets(position)) {
|
|
512
513
|
if (filter(mapping.data)) {
|
|
513
514
|
process(fileName, generateOffset + sourceFile.snapshot.getLength());
|
|
@@ -519,21 +520,25 @@ function decorateLanguageService(files, languageService) {
|
|
|
519
520
|
}
|
|
520
521
|
return results;
|
|
521
522
|
function process(fileName, position) {
|
|
522
|
-
if (processedFilePositions.has(fileName + ':' + position))
|
|
523
|
+
if (processedFilePositions.has(fileName + ':' + position)) {
|
|
523
524
|
return;
|
|
525
|
+
}
|
|
524
526
|
processedFilePositions.add(fileName + ':' + position);
|
|
525
527
|
const result = worker(position);
|
|
526
|
-
if (!result)
|
|
528
|
+
if (!result) {
|
|
527
529
|
return;
|
|
530
|
+
}
|
|
528
531
|
results = results.concat(result);
|
|
529
532
|
for (const ref of getLinkedCodes(result)) {
|
|
530
533
|
processedFilePositions.add(ref[0] + ':' + ref[1]);
|
|
531
534
|
const [virtualFile, sourceFile] = (0, utils_1.getVirtualFileAndMap)(files, ref[0]);
|
|
532
|
-
if (!virtualFile)
|
|
535
|
+
if (!virtualFile) {
|
|
533
536
|
continue;
|
|
534
|
-
|
|
535
|
-
|
|
537
|
+
}
|
|
538
|
+
const linkedCodeMap = files.getLinkedCodeMap(virtualFile.code);
|
|
539
|
+
if (!linkedCodeMap) {
|
|
536
540
|
continue;
|
|
541
|
+
}
|
|
537
542
|
for (const linkedCodeOffset of linkedCodeMap.getLinkedOffsets(ref[1] - sourceFile.snapshot.getLength())) {
|
|
538
543
|
process(ref[0], linkedCodeOffset + sourceFile.snapshot.getLength());
|
|
539
544
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type * as ts from 'typescript
|
|
3
|
-
export declare function decorateLanguageServiceHost(virtualFiles:
|
|
4
|
-
export declare function searchExternalFiles(ts: typeof import('typescript
|
|
1
|
+
import type { FileRegistry } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
export declare function decorateLanguageServiceHost(virtualFiles: FileRegistry, languageServiceHost: ts.LanguageServiceHost, ts: typeof import('typescript')): void;
|
|
4
|
+
export declare function searchExternalFiles(ts: typeof import('typescript'), project: ts.server.Project, exts: string[]): string[];
|
|
@@ -1,10 +1,12 @@
|
|
|
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 language_service_1 = require("@volar/language-service");
|
|
6
|
-
function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts
|
|
5
|
+
function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts) {
|
|
7
6
|
let extraProjectVersion = 0;
|
|
7
|
+
const exts = virtualFiles.languagePlugins
|
|
8
|
+
.map(plugin => plugin.typescript?.extraFileExtensions.map(ext => '.' + ext.extension) ?? [])
|
|
9
|
+
.flat();
|
|
8
10
|
const scripts = new Map();
|
|
9
11
|
const readDirectory = languageServiceHost.readDirectory?.bind(languageServiceHost);
|
|
10
12
|
const resolveModuleNameLiterals = languageServiceHost.resolveModuleNameLiterals?.bind(languageServiceHost);
|
|
@@ -58,7 +60,7 @@ function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts, exts
|
|
|
58
60
|
return getProjectVersion() + ':' + extraProjectVersion;
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
|
-
languageServiceHost.getScriptSnapshot =
|
|
63
|
+
languageServiceHost.getScriptSnapshot = fileName => {
|
|
62
64
|
if (exts.some(ext => fileName.endsWith(ext))) {
|
|
63
65
|
updateScript(fileName);
|
|
64
66
|
return scripts.get(fileName)?.snapshot;
|
|
@@ -66,7 +68,7 @@ function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts, exts
|
|
|
66
68
|
return getScriptSnapshot(fileName);
|
|
67
69
|
};
|
|
68
70
|
if (getScriptKind) {
|
|
69
|
-
languageServiceHost.getScriptKind =
|
|
71
|
+
languageServiceHost.getScriptKind = fileName => {
|
|
70
72
|
if (exts.some(ext => fileName.endsWith(ext))) {
|
|
71
73
|
updateScript(fileName);
|
|
72
74
|
const script = scripts.get(fileName);
|
|
@@ -116,24 +118,25 @@ function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts, exts
|
|
|
116
118
|
const snapshot = getScriptSnapshot(fileName);
|
|
117
119
|
if (snapshot) {
|
|
118
120
|
extraProjectVersion++;
|
|
119
|
-
const sourceFile = virtualFiles.
|
|
120
|
-
if (sourceFile.
|
|
121
|
+
const sourceFile = virtualFiles.set(fileName, (0, language_service_1.resolveCommonLanguageId)(fileName), snapshot);
|
|
122
|
+
if (sourceFile.generated) {
|
|
121
123
|
const text = snapshot.getText(0, snapshot.getLength());
|
|
122
124
|
let patchedText = text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
patchedText += file.snapshot.getText(0, file.snapshot.getLength());
|
|
129
|
-
}
|
|
125
|
+
const script = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
|
|
126
|
+
if (script) {
|
|
127
|
+
extension = script.extension;
|
|
128
|
+
scriptKind = script.scriptKind;
|
|
129
|
+
patchedText += script.code.snapshot.getText(0, script.code.snapshot.getLength());
|
|
130
130
|
}
|
|
131
131
|
snapshotSnapshot = ts.ScriptSnapshot.fromString(patchedText);
|
|
132
|
+
if (sourceFile.generated.languagePlugin.typescript?.getExtraScripts) {
|
|
133
|
+
console.warn('getExtraScripts() is not available in this use case.');
|
|
134
|
+
}
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
|
-
else if (virtualFiles.
|
|
137
|
+
else if (virtualFiles.get(fileName)) {
|
|
135
138
|
extraProjectVersion++;
|
|
136
|
-
virtualFiles.
|
|
139
|
+
virtualFiles.delete(fileName);
|
|
137
140
|
}
|
|
138
141
|
scripts.set(fileName, {
|
|
139
142
|
version,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type * as ts from 'typescript
|
|
3
|
-
export declare function decorateProgram(files:
|
|
1
|
+
import type { FileRegistry } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
export declare function decorateProgram(files: FileRegistry, program: ts.Program): void;
|
|
@@ -32,7 +32,7 @@ function decorateProgram(files, program) {
|
|
|
32
32
|
.map(d => (0, transform_1.transformDiagnostic)(files, d))
|
|
33
33
|
.filter(utils_1.notEmpty);
|
|
34
34
|
};
|
|
35
|
-
program.getGlobalDiagnostics =
|
|
35
|
+
program.getGlobalDiagnostics = cancellationToken => {
|
|
36
36
|
return getGlobalDiagnostics(cancellationToken)
|
|
37
37
|
.map(d => (0, transform_1.transformDiagnostic)(files, d))
|
|
38
38
|
.filter(utils_1.notEmpty);
|
package/lib/node/dedupe.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type * as ts from 'typescript
|
|
1
|
+
import type * as ts from 'typescript';
|
|
2
2
|
export declare function dedupeReferencedSymbols<T extends ts.ReferencedSymbol>(items: T[]): T[];
|
|
3
3
|
export declare function dedupeDocumentSpans<T extends ts.DocumentSpan>(items: T[]): T[];
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type * as ts from 'typescript
|
|
1
|
+
import type * as ts from 'typescript';
|
|
2
2
|
import { LanguagePlugin } from '@volar/language-core';
|
|
3
|
-
export declare function proxyCreateProgram(ts: typeof import('typescript'), original: typeof ts['createProgram'], extensions: string[], getLanguagePlugins: (ts: typeof import('typescript
|
|
3
|
+
export declare function proxyCreateProgram(ts: typeof import('typescript'), original: typeof ts['createProgram'], extensions: string[], getLanguagePlugins: (ts: typeof import('typescript'), options: ts.CreateProgramOptions) => LanguagePlugin[]): typeof import("typescript").createProgram;
|
|
@@ -9,7 +9,7 @@ function proxyCreateProgram(ts, original, extensions, getLanguagePlugins) {
|
|
|
9
9
|
const options = args[0];
|
|
10
10
|
assert(!!options.host, '!!options.host');
|
|
11
11
|
const sourceFileToSnapshotMap = new WeakMap();
|
|
12
|
-
const files = (0, language_core_1.
|
|
12
|
+
const files = (0, language_core_1.createFileRegistry)(getLanguagePlugins(ts, options), ts.sys.useCaseSensitiveFileNames, fileName => {
|
|
13
13
|
let snapshot;
|
|
14
14
|
assert(originalSourceFiles.has(fileName), `originalSourceFiles.has(${fileName})`);
|
|
15
15
|
const sourceFile = originalSourceFiles.get(fileName);
|
|
@@ -31,10 +31,10 @@ function proxyCreateProgram(ts, original, extensions, getLanguagePlugins) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
if (snapshot) {
|
|
34
|
-
files.
|
|
34
|
+
files.set(fileName, (0, language_core_1.resolveCommonLanguageId)(fileName), snapshot);
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
files.
|
|
37
|
+
files.delete(fileName);
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
const originalSourceFiles = new Map();
|
|
@@ -60,21 +60,22 @@ function proxyCreateProgram(ts, original, extensions, getLanguagePlugins) {
|
|
|
60
60
|
if (originalSourceFile && extensions.some(ext => fileName.endsWith(ext))) {
|
|
61
61
|
let sourceFile2 = parsedSourceFiles.get(originalSourceFile);
|
|
62
62
|
if (!sourceFile2) {
|
|
63
|
-
const sourceFile = files.
|
|
63
|
+
const sourceFile = files.get(fileName);
|
|
64
64
|
assert(!!sourceFile, '!!sourceFile');
|
|
65
65
|
let patchedText = originalSourceFile.text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
|
|
66
66
|
let scriptKind = ts.ScriptKind.TS;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
if (sourceFile.generated?.languagePlugin.typescript) {
|
|
68
|
+
const { getScript, getExtraScripts } = sourceFile.generated.languagePlugin.typescript;
|
|
69
|
+
const script = getScript(sourceFile.generated.code);
|
|
70
|
+
if (script) {
|
|
71
|
+
scriptKind = script.scriptKind;
|
|
72
|
+
patchedText += script.code.snapshot.getText(0, script.code.snapshot.getLength());
|
|
73
|
+
}
|
|
74
|
+
if (getExtraScripts) {
|
|
75
|
+
console.warn('getExtraScripts() is not available in this use case.');
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
|
-
sourceFile2 = ts.createSourceFile(
|
|
78
|
+
sourceFile2 = ts.createSourceFile(fileName, patchedText, 99, true, scriptKind);
|
|
78
79
|
// @ts-expect-error
|
|
79
80
|
sourceFile2.version = originalSourceFile.version;
|
|
80
81
|
parsedSourceFiles.set(originalSourceFile, sourceFile2);
|
|
@@ -95,6 +96,7 @@ function proxyCreateProgram(ts, original, extensions, getLanguagePlugins) {
|
|
|
95
96
|
};
|
|
96
97
|
const program = Reflect.apply(target, thisArg, [options]);
|
|
97
98
|
(0, decorateProgram_1.decorateProgram)(files, program);
|
|
99
|
+
program.__volar__ = { files };
|
|
98
100
|
return program;
|
|
99
101
|
function resolveModuleName(name, containingFile, options, redirectedReference) {
|
|
100
102
|
const resolved = ts.resolveModuleName(name, containingFile, options, moduleResolutionHost, originalHost.getModuleResolutionCache?.(), redirectedReference);
|
package/lib/node/transform.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type * as ts from 'typescript
|
|
3
|
-
export declare function transformCallHierarchyItem(files:
|
|
4
|
-
export declare function transformDiagnostic<T extends ts.Diagnostic>(files:
|
|
5
|
-
export declare function transformFileTextChanges(files:
|
|
6
|
-
export declare function transformDocumentSpan<T extends ts.DocumentSpan>(files:
|
|
7
|
-
export declare function transformSpan(files:
|
|
1
|
+
import { FileRegistry, CodeInformation } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
export declare function transformCallHierarchyItem(files: FileRegistry, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem;
|
|
4
|
+
export declare function transformDiagnostic<T extends ts.Diagnostic>(files: FileRegistry, diagnostic: T): T | undefined;
|
|
5
|
+
export declare function transformFileTextChanges(files: FileRegistry, changes: ts.FileTextChanges, filter: (data: CodeInformation) => boolean): ts.FileTextChanges | undefined;
|
|
6
|
+
export declare function transformDocumentSpan<T extends ts.DocumentSpan>(files: FileRegistry, documentSpan: T, filter: (data: CodeInformation) => boolean, shouldFallback?: boolean): T | undefined;
|
|
7
|
+
export declare function transformSpan(files: FileRegistry, fileName: string | undefined, textSpan: ts.TextSpan | undefined, filter: (data: CodeInformation) => boolean): {
|
|
8
8
|
fileName: string;
|
|
9
9
|
textSpan: ts.TextSpan;
|
|
10
10
|
} | undefined;
|
package/lib/node/transform.js
CHANGED
|
@@ -26,8 +26,8 @@ function transformDiagnostic(files, diagnostic) {
|
|
|
26
26
|
if (diagnostic.file !== undefined
|
|
27
27
|
&& diagnostic.start !== undefined
|
|
28
28
|
&& diagnostic.length !== undefined) {
|
|
29
|
-
const [
|
|
30
|
-
if (
|
|
29
|
+
const [virtualCode, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, diagnostic.file.fileName);
|
|
30
|
+
if (virtualCode) {
|
|
31
31
|
const sourceRange = transformRange(sourceFile, map, diagnostic.start, diagnostic.start + diagnostic.length, language_core_1.shouldReportDiagnostics);
|
|
32
32
|
if (sourceRange) {
|
|
33
33
|
transformedDiagnostics.set(diagnostic, {
|
|
@@ -53,7 +53,6 @@ function transformFileTextChanges(files, changes, filter) {
|
|
|
53
53
|
if (source) {
|
|
54
54
|
return {
|
|
55
55
|
...changes,
|
|
56
|
-
fileName: source.fileName,
|
|
57
56
|
textChanges: changes.textChanges.map(c => {
|
|
58
57
|
const span = transformSpan(files, changes.fileName, c.span, filter);
|
|
59
58
|
if (span) {
|
|
@@ -73,16 +72,17 @@ exports.transformFileTextChanges = transformFileTextChanges;
|
|
|
73
72
|
function transformDocumentSpan(files, documentSpan, filter, shouldFallback) {
|
|
74
73
|
let textSpan = transformSpan(files, documentSpan.fileName, documentSpan.textSpan, filter);
|
|
75
74
|
if (!textSpan && shouldFallback) {
|
|
76
|
-
const [
|
|
77
|
-
if (
|
|
75
|
+
const [virtualCode] = (0, utils_1.getVirtualFileAndMap)(files, documentSpan.fileName);
|
|
76
|
+
if (virtualCode) {
|
|
78
77
|
textSpan = {
|
|
79
|
-
fileName:
|
|
78
|
+
fileName: documentSpan.fileName,
|
|
80
79
|
textSpan: { start: 0, length: 0 },
|
|
81
80
|
};
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
|
-
if (!textSpan)
|
|
83
|
+
if (!textSpan) {
|
|
85
84
|
return;
|
|
85
|
+
}
|
|
86
86
|
const contextSpan = transformSpan(files, documentSpan.fileName, documentSpan.contextSpan, filter);
|
|
87
87
|
const originalTextSpan = transformSpan(files, documentSpan.originalFileName, documentSpan.originalTextSpan, filter);
|
|
88
88
|
const originalContextSpan = transformSpan(files, documentSpan.originalFileName, documentSpan.originalContextSpan, filter);
|
|
@@ -98,16 +98,18 @@ function transformDocumentSpan(files, documentSpan, filter, shouldFallback) {
|
|
|
98
98
|
}
|
|
99
99
|
exports.transformDocumentSpan = transformDocumentSpan;
|
|
100
100
|
function transformSpan(files, fileName, textSpan, filter) {
|
|
101
|
-
if (!fileName)
|
|
101
|
+
if (!fileName) {
|
|
102
102
|
return;
|
|
103
|
-
|
|
103
|
+
}
|
|
104
|
+
if (!textSpan) {
|
|
104
105
|
return;
|
|
106
|
+
}
|
|
105
107
|
const [virtualFile, sourceFile, map] = (0, utils_1.getVirtualFileAndMap)(files, fileName);
|
|
106
108
|
if (virtualFile) {
|
|
107
109
|
const sourceRange = transformRange(sourceFile, map, textSpan.start, textSpan.start + textSpan.length, filter);
|
|
108
110
|
if (sourceRange) {
|
|
109
111
|
return {
|
|
110
|
-
fileName
|
|
112
|
+
fileName,
|
|
111
113
|
textSpan: {
|
|
112
114
|
start: sourceRange[0],
|
|
113
115
|
length: sourceRange[1] - sourceRange[0],
|
package/lib/node/utils.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FileRegistry } from '@volar/language-core';
|
|
2
2
|
export declare function notEmpty<T>(value: T | null | undefined): value is T;
|
|
3
|
-
export declare function getVirtualFileAndMap(files:
|
|
3
|
+
export declare function getVirtualFileAndMap(files: FileRegistry, fileName: string): readonly [import("@volar/language-core").ServiceScript, import("@volar/language-core").SourceFile, import("@volar/language-core").SourceMap<import("@volar/language-core").CodeInformation>] | readonly [undefined, undefined, undefined];
|
package/lib/node/utils.js
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getVirtualFileAndMap = exports.notEmpty = void 0;
|
|
4
|
-
const language_core_1 = require("@volar/language-core");
|
|
5
4
|
function notEmpty(value) {
|
|
6
5
|
return value !== null && value !== undefined;
|
|
7
6
|
}
|
|
8
7
|
exports.notEmpty = notEmpty;
|
|
9
8
|
function getVirtualFileAndMap(files, fileName) {
|
|
10
|
-
const sourceFile = files.
|
|
11
|
-
if (sourceFile?.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return [virtualFile, sourceFile, map[1][1]];
|
|
18
|
-
}
|
|
9
|
+
const sourceFile = files.get(fileName);
|
|
10
|
+
if (sourceFile?.generated) {
|
|
11
|
+
const script = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
|
|
12
|
+
if (script) {
|
|
13
|
+
for (const map of files.getMaps(script.code)) {
|
|
14
|
+
if (map[1][0] === sourceFile.snapshot) {
|
|
15
|
+
return [script, sourceFile, map[1][1]];
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
18
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { LanguagePlugin,
|
|
2
|
-
import type * as ts from 'typescript
|
|
1
|
+
import { LanguagePlugin, LanguageContext, TypeScriptProjectHost } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
3
|
import type { createSys } from './createSys';
|
|
4
|
-
export declare function createLanguage(ts: typeof import('typescript
|
|
4
|
+
export declare function createLanguage(ts: typeof import('typescript'), sys: ReturnType<typeof createSys> | ts.System, languagePlugins: LanguagePlugin<any>[], configFileName: string | undefined, projectHost: TypeScriptProjectHost, { fileIdToFileName, fileNameToFileId }: {
|
|
5
|
+
fileIdToFileName: (uri: string) => string;
|
|
6
|
+
fileNameToFileId: (fileName: string) => string;
|
|
7
|
+
}): LanguageContext;
|