@volar/typescript 1.7.6 → 1.7.8
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/out/dtsHost.d.ts +1 -19
- package/out/getProgram.d.ts +1 -1
- package/out/getProgram.js +6 -6
- package/out/index.d.ts +2 -0
- package/out/index.js +2 -0
- package/out/languageService.d.ts +2 -8
- package/out/languageService.js +77 -71
- package/out/languageServiceHost.js +59 -1
- package/out/serverPlugin.d.ts +3 -0
- package/out/serverPlugin.js +92 -0
- package/out/sys.d.ts +2 -2
- package/out/sys.js +43 -42
- package/package.json +4 -4
package/out/dtsHost.d.ts
CHANGED
|
@@ -4,23 +4,5 @@ export interface IDtsHost {
|
|
|
4
4
|
readFile(fileName: string): Promise<string | undefined>;
|
|
5
5
|
readDirectory(dirName: string): Promise<[string, FileType][]>;
|
|
6
6
|
}
|
|
7
|
-
export declare function createJsDelivrDtsHost(versions?: Record<string, string>, onFetch?: (fileName: string, text: string) => void):
|
|
8
|
-
declare class DtsHost implements IDtsHost {
|
|
9
|
-
private fetchText;
|
|
10
|
-
private flat;
|
|
11
|
-
fetchResults: Map<string, Promise<string | undefined>>;
|
|
12
|
-
flatResults: Map<string, Promise<string[]>>;
|
|
13
|
-
constructor(fetchText: (path: string) => Promise<string | undefined>, flat: (pkg: string) => Promise<string[]>);
|
|
14
|
-
stat(fileName: string): Promise<{
|
|
15
|
-
type: number;
|
|
16
|
-
ctime: number;
|
|
17
|
-
mtime: number;
|
|
18
|
-
size: number;
|
|
19
|
-
} | undefined>;
|
|
20
|
-
readDirectory(dirName: string): Promise<[string, FileType][]>;
|
|
21
|
-
readFile(fileName: string): Promise<string | undefined>;
|
|
22
|
-
fetchFile(fileName: string): Promise<string | undefined>;
|
|
23
|
-
valid(fileName: string): Promise<boolean>;
|
|
24
|
-
}
|
|
7
|
+
export declare function createJsDelivrDtsHost(versions?: Record<string, string>, onFetch?: (fileName: string, text: string) => void): IDtsHost;
|
|
25
8
|
export declare function getPackageNameOfDtsPath(path: string): string | undefined;
|
|
26
|
-
export {};
|
package/out/getProgram.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type * as ts from 'typescript/lib/tsserverlibrary';
|
|
2
2
|
import type * as embedded from '@volar/language-core';
|
|
3
|
-
export declare function getProgram(ts: typeof import('typescript/lib/tsserverlibrary'), core: embedded.LanguageContext, ls: ts.LanguageService,
|
|
3
|
+
export declare function getProgram(ts: typeof import('typescript/lib/tsserverlibrary'), core: embedded.LanguageContext, ls: ts.LanguageService, sys: ts.System): ts.Program;
|
package/out/getProgram.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getProgram = void 0;
|
|
4
|
-
function getProgram(ts, core, ls,
|
|
4
|
+
function getProgram(ts, core, ls, sys) {
|
|
5
5
|
const proxy = {
|
|
6
6
|
getRootFileNames,
|
|
7
7
|
emit,
|
|
@@ -34,7 +34,7 @@ function getProgram(ts, core, ls, lsHost) {
|
|
|
34
34
|
return ls.getProgram();
|
|
35
35
|
}
|
|
36
36
|
function getRootFileNames() {
|
|
37
|
-
return getProgram().getRootFileNames().filter(fileName =>
|
|
37
|
+
return getProgram().getRootFileNames().filter(fileName => sys.fileExists?.(fileName));
|
|
38
38
|
}
|
|
39
39
|
// for vue-tsc --noEmit --watch
|
|
40
40
|
function getBindAndCheckDiagnostics(sourceFile, cancellationToken) {
|
|
@@ -63,7 +63,7 @@ function getProgram(ts, core, ls, lsHost) {
|
|
|
63
63
|
return transformDiagnostics(getProgram().getGlobalDiagnostics(cancellationToken) ?? []);
|
|
64
64
|
}
|
|
65
65
|
function emit(targetSourceFile, _writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
|
|
66
|
-
const scriptResult = getProgram().emit(targetSourceFile, (
|
|
66
|
+
const scriptResult = getProgram().emit(targetSourceFile, (sys.writeFile ?? ts.sys.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
|
|
67
67
|
return {
|
|
68
68
|
emitSkipped: scriptResult.emitSkipped,
|
|
69
69
|
emittedFiles: scriptResult.emittedFiles,
|
|
@@ -79,7 +79,7 @@ function getProgram(ts, core, ls, lsHost) {
|
|
|
79
79
|
&& diagnostic.length !== undefined) {
|
|
80
80
|
const [virtualFile, source] = core.virtualFiles.getVirtualFile(diagnostic.file.fileName);
|
|
81
81
|
if (virtualFile && source) {
|
|
82
|
-
if (
|
|
82
|
+
if (sys.fileExists?.(source.fileName) === false)
|
|
83
83
|
continue;
|
|
84
84
|
for (const [_, [sourceSnapshot, map]] of core.virtualFiles.getMaps(virtualFile)) {
|
|
85
85
|
if (sourceSnapshot !== source.snapshot)
|
|
@@ -100,7 +100,7 @@ function getProgram(ts, core, ls, lsHost) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
if (
|
|
103
|
+
if (sys.fileExists?.(diagnostic.file.fileName) === false)
|
|
104
104
|
continue;
|
|
105
105
|
onMapping(diagnostic, diagnostic.file.fileName, diagnostic.start, diagnostic.start + diagnostic.length, diagnostic.file.text);
|
|
106
106
|
}
|
|
@@ -116,7 +116,7 @@ function getProgram(ts, core, ls, lsHost) {
|
|
|
116
116
|
: undefined;
|
|
117
117
|
if (!file) {
|
|
118
118
|
if (docText === undefined) {
|
|
119
|
-
const snapshot =
|
|
119
|
+
const snapshot = core.host.getScriptSnapshot(fileName);
|
|
120
120
|
if (snapshot) {
|
|
121
121
|
docText = snapshot.getText(0, snapshot.getLength());
|
|
122
122
|
}
|
package/out/index.d.ts
CHANGED
package/out/index.js
CHANGED
|
@@ -19,4 +19,6 @@ __exportStar(require("./dtsHost"), exports);
|
|
|
19
19
|
__exportStar(require("./languageService"), exports);
|
|
20
20
|
__exportStar(require("./languageServiceHost"), exports);
|
|
21
21
|
__exportStar(require("./sys"), exports);
|
|
22
|
+
__exportStar(require("./getProgram"), exports);
|
|
23
|
+
__exportStar(require("./serverPlugin"), exports);
|
|
22
24
|
//# sourceMappingURL=index.js.map
|
package/out/languageService.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VirtualFiles } from '@volar/language-core';
|
|
2
2
|
import type * as ts from 'typescript/lib/tsserverlibrary';
|
|
3
|
-
export declare function
|
|
4
|
-
__internal__: {
|
|
5
|
-
languageServiceHost: ts.LanguageServiceHost;
|
|
6
|
-
languageService: ts.LanguageService;
|
|
7
|
-
context: LanguageContext;
|
|
8
|
-
};
|
|
9
|
-
} & ts.LanguageService;
|
|
3
|
+
export declare function decorateLanguageService(virtualFiles: VirtualFiles, languageService: ts.LanguageService, isTsPlugin: boolean): void;
|
package/out/languageService.js
CHANGED
|
@@ -1,59 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.decorateLanguageService = void 0;
|
|
4
4
|
const language_core_1 = require("@volar/language-core");
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
getReferencesAtPosition,
|
|
23
|
-
findReferences,
|
|
24
|
-
// TODO: now is handled by vue server
|
|
25
|
-
// prepareCallHierarchy: tsLanguageService.rawLs.prepareCallHierarchy,
|
|
26
|
-
// provideCallHierarchyIncomingCalls: tsLanguageService.rawLs.provideCallHierarchyIncomingCalls,
|
|
27
|
-
// provideCallHierarchyOutgoingCalls: tsLanguageService.rawLs.provideCallHierarchyOutgoingCalls,
|
|
28
|
-
// getEditsForFileRename: tsLanguageService.rawLs.getEditsForFileRename,
|
|
29
|
-
// TODO
|
|
30
|
-
// getCodeFixesAtPosition: tsLanguageService.rawLs.getCodeFixesAtPosition,
|
|
31
|
-
// getCombinedCodeFix: tsLanguageService.rawLs.getCombinedCodeFix,
|
|
32
|
-
// applyCodeActionCommand: tsLanguageService.rawLs.applyCodeActionCommand,
|
|
33
|
-
// getApplicableRefactors: tsLanguageService.rawLs.getApplicableRefactors,
|
|
34
|
-
// getEditsForRefactor: tsLanguageService.rawLs.getEditsForRefactor,
|
|
35
|
-
getProgram: () => (0, getProgram_1.getProgram)(ts, core, ls, lsHost),
|
|
36
|
-
__internal__: {
|
|
37
|
-
context: core,
|
|
38
|
-
languageService: ls,
|
|
39
|
-
languageServiceHost: lsHost,
|
|
40
|
-
},
|
|
41
|
-
}, {
|
|
42
|
-
get: (target, property) => {
|
|
43
|
-
if (property in target) {
|
|
44
|
-
return target[property];
|
|
45
|
-
}
|
|
46
|
-
return ls[property];
|
|
47
|
-
},
|
|
48
|
-
});
|
|
5
|
+
function decorateLanguageService(virtualFiles, languageService, isTsPlugin) {
|
|
6
|
+
const _organizeImports = languageService.organizeImports.bind(languageService);
|
|
7
|
+
const _getDefinitionAtPosition = languageService.getDefinitionAtPosition.bind(languageService);
|
|
8
|
+
const _getDefinitionAndBoundSpan = languageService.getDefinitionAndBoundSpan.bind(languageService);
|
|
9
|
+
const _getTypeDefinitionAtPosition = languageService.getTypeDefinitionAtPosition.bind(languageService);
|
|
10
|
+
const _getImplementationAtPosition = languageService.getImplementationAtPosition.bind(languageService);
|
|
11
|
+
const _findRenameLocations = languageService.findRenameLocations.bind(languageService);
|
|
12
|
+
const _getReferencesAtPosition = languageService.getReferencesAtPosition.bind(languageService);
|
|
13
|
+
const _findReferences = languageService.findReferences.bind(languageService);
|
|
14
|
+
languageService.organizeImports = organizeImports;
|
|
15
|
+
languageService.getDefinitionAtPosition = getDefinitionAtPosition;
|
|
16
|
+
languageService.getDefinitionAndBoundSpan = getDefinitionAndBoundSpan;
|
|
17
|
+
languageService.getTypeDefinitionAtPosition = getTypeDefinitionAtPosition;
|
|
18
|
+
languageService.getImplementationAtPosition = getImplementationAtPosition;
|
|
19
|
+
languageService.findRenameLocations = findRenameLocations;
|
|
20
|
+
languageService.getReferencesAtPosition = getReferencesAtPosition;
|
|
21
|
+
languageService.findReferences = findReferences;
|
|
49
22
|
// apis
|
|
50
23
|
function organizeImports(args, formatOptions, preferences) {
|
|
51
24
|
let edits = [];
|
|
52
|
-
const file =
|
|
25
|
+
const file = virtualFiles.getSource(args.fileName)?.root;
|
|
53
26
|
if (file) {
|
|
54
27
|
(0, language_core_1.forEachEmbeddedFile)(file, embeddedFile => {
|
|
55
28
|
if (embeddedFile.kind === language_core_1.FileKind.TypeScriptHostFile && embeddedFile.capabilities.codeAction) {
|
|
56
|
-
edits = edits.concat(
|
|
29
|
+
edits = edits.concat(_organizeImports({
|
|
57
30
|
...args,
|
|
58
31
|
fileName: embeddedFile.fileName,
|
|
59
32
|
}, formatOptions, preferences));
|
|
@@ -61,7 +34,7 @@ function createLanguageService(core, ts, sys) {
|
|
|
61
34
|
});
|
|
62
35
|
}
|
|
63
36
|
else {
|
|
64
|
-
return
|
|
37
|
+
return _organizeImports(args, formatOptions, preferences);
|
|
65
38
|
}
|
|
66
39
|
return edits.map(transformFileTextChanges).filter(notEmpty);
|
|
67
40
|
}
|
|
@@ -84,26 +57,26 @@ function createLanguageService(core, ts, sys) {
|
|
|
84
57
|
const loopChecker = new Set();
|
|
85
58
|
let symbols = [];
|
|
86
59
|
withMirrors(fileName, position);
|
|
87
|
-
return symbols.map(s => transformDocumentSpanLike(s)).filter(notEmpty);
|
|
60
|
+
return symbols.map(s => transformDocumentSpanLike(s, mode === 'definition')).filter(notEmpty);
|
|
88
61
|
function withMirrors(fileName, position) {
|
|
89
62
|
if (loopChecker.has(fileName + ':' + position))
|
|
90
63
|
return;
|
|
91
64
|
loopChecker.add(fileName + ':' + position);
|
|
92
|
-
const _symbols = mode === 'definition' ?
|
|
93
|
-
: mode === 'typeDefinition' ?
|
|
94
|
-
: mode === 'references' ?
|
|
95
|
-
: mode === 'implementation' ?
|
|
96
|
-
: mode === 'rename' && preferences ?
|
|
65
|
+
const _symbols = mode === 'definition' ? _getDefinitionAtPosition(fileName, position)
|
|
66
|
+
: mode === 'typeDefinition' ? _getTypeDefinitionAtPosition(fileName, position)
|
|
67
|
+
: mode === 'references' ? _getReferencesAtPosition(fileName, position)
|
|
68
|
+
: mode === 'implementation' ? _getImplementationAtPosition(fileName, position)
|
|
69
|
+
: mode === 'rename' && preferences ? _findRenameLocations(fileName, position, findInStrings, findInComments, preferences)
|
|
97
70
|
: undefined;
|
|
98
71
|
if (!_symbols)
|
|
99
72
|
return;
|
|
100
73
|
symbols = symbols.concat(_symbols);
|
|
101
74
|
for (const ref of _symbols) {
|
|
102
75
|
loopChecker.add(ref.fileName + ':' + ref.textSpan.start);
|
|
103
|
-
const [virtualFile] =
|
|
76
|
+
const [virtualFile] = getVirtualFile(ref.fileName);
|
|
104
77
|
if (!virtualFile)
|
|
105
78
|
continue;
|
|
106
|
-
const mirrorMap =
|
|
79
|
+
const mirrorMap = virtualFiles.getMirrorMap(virtualFile);
|
|
107
80
|
if (!mirrorMap)
|
|
108
81
|
continue;
|
|
109
82
|
for (const [mirrorOffset, data] of mirrorMap.findMirrorOffsets(ref.textSpan.start)) {
|
|
@@ -129,13 +102,13 @@ function createLanguageService(core, ts, sys) {
|
|
|
129
102
|
return;
|
|
130
103
|
return {
|
|
131
104
|
textSpan: textSpan,
|
|
132
|
-
definitions: symbols?.map(s => transformDocumentSpanLike(s)).filter(notEmpty),
|
|
105
|
+
definitions: symbols?.map(s => transformDocumentSpanLike(s, true)).filter(notEmpty),
|
|
133
106
|
};
|
|
134
107
|
function withMirrors(fileName, position) {
|
|
135
108
|
if (loopChecker.has(fileName + ':' + position))
|
|
136
109
|
return;
|
|
137
110
|
loopChecker.add(fileName + ':' + position);
|
|
138
|
-
const _symbols =
|
|
111
|
+
const _symbols = _getDefinitionAndBoundSpan(fileName, position);
|
|
139
112
|
if (!_symbols)
|
|
140
113
|
return;
|
|
141
114
|
if (!textSpan) {
|
|
@@ -146,10 +119,10 @@ function createLanguageService(core, ts, sys) {
|
|
|
146
119
|
symbols = symbols.concat(_symbols.definitions);
|
|
147
120
|
for (const ref of _symbols.definitions) {
|
|
148
121
|
loopChecker.add(ref.fileName + ':' + ref.textSpan.start);
|
|
149
|
-
const [virtualFile] =
|
|
122
|
+
const [virtualFile] = getVirtualFile(ref.fileName);
|
|
150
123
|
if (!virtualFile)
|
|
151
124
|
continue;
|
|
152
|
-
const mirrorMap =
|
|
125
|
+
const mirrorMap = virtualFiles.getMirrorMap(virtualFile);
|
|
153
126
|
if (!mirrorMap)
|
|
154
127
|
continue;
|
|
155
128
|
for (const [mirrorOffset, data] of mirrorMap.findMirrorOffsets(ref.textSpan.start)) {
|
|
@@ -171,17 +144,17 @@ function createLanguageService(core, ts, sys) {
|
|
|
171
144
|
if (loopChecker.has(fileName + ':' + position))
|
|
172
145
|
return;
|
|
173
146
|
loopChecker.add(fileName + ':' + position);
|
|
174
|
-
const _symbols =
|
|
147
|
+
const _symbols = _findReferences(fileName, position);
|
|
175
148
|
if (!_symbols)
|
|
176
149
|
return;
|
|
177
150
|
symbols = symbols.concat(_symbols);
|
|
178
151
|
for (const symbol of _symbols) {
|
|
179
152
|
for (const ref of symbol.references) {
|
|
180
153
|
loopChecker.add(ref.fileName + ':' + ref.textSpan.start);
|
|
181
|
-
const [virtualFile] =
|
|
154
|
+
const [virtualFile] = getVirtualFile(ref.fileName);
|
|
182
155
|
if (!virtualFile)
|
|
183
156
|
continue;
|
|
184
|
-
const mirrorMap =
|
|
157
|
+
const mirrorMap = virtualFiles.getMirrorMap(virtualFile);
|
|
185
158
|
if (!mirrorMap)
|
|
186
159
|
continue;
|
|
187
160
|
for (const [mirrorOffset, data] of mirrorMap.findMirrorOffsets(ref.textSpan.start)) {
|
|
@@ -197,7 +170,7 @@ function createLanguageService(core, ts, sys) {
|
|
|
197
170
|
}
|
|
198
171
|
// transforms
|
|
199
172
|
function transformFileTextChanges(changes) {
|
|
200
|
-
const [_, source] =
|
|
173
|
+
const [_, source] = getVirtualFile(changes.fileName);
|
|
201
174
|
if (source) {
|
|
202
175
|
return {
|
|
203
176
|
...changes,
|
|
@@ -218,8 +191,8 @@ function createLanguageService(core, ts, sys) {
|
|
|
218
191
|
}
|
|
219
192
|
}
|
|
220
193
|
function transformReferencedSymbol(symbol) {
|
|
221
|
-
const definition = transformDocumentSpanLike(symbol.definition);
|
|
222
|
-
const references = symbol.references.map(r => transformDocumentSpanLike(r)).filter(notEmpty);
|
|
194
|
+
const definition = transformDocumentSpanLike(symbol.definition, false);
|
|
195
|
+
const references = symbol.references.map(r => transformDocumentSpanLike(r, false)).filter(notEmpty);
|
|
223
196
|
if (definition) {
|
|
224
197
|
return {
|
|
225
198
|
definition,
|
|
@@ -237,8 +210,17 @@ function createLanguageService(core, ts, sys) {
|
|
|
237
210
|
};
|
|
238
211
|
}
|
|
239
212
|
}
|
|
240
|
-
function transformDocumentSpanLike(documentSpan) {
|
|
241
|
-
|
|
213
|
+
function transformDocumentSpanLike(documentSpan, isDefinition) {
|
|
214
|
+
let textSpan = transformSpan(documentSpan.fileName, documentSpan.textSpan);
|
|
215
|
+
if (isDefinition && !textSpan) {
|
|
216
|
+
const [virtualFile, source] = getVirtualFile(documentSpan.fileName);
|
|
217
|
+
if (virtualFile && source) {
|
|
218
|
+
textSpan = {
|
|
219
|
+
fileName: source.fileName,
|
|
220
|
+
textSpan: { start: 0, length: 0 },
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
242
224
|
if (!textSpan)
|
|
243
225
|
return;
|
|
244
226
|
const contextSpan = transformSpan(documentSpan.fileName, documentSpan.contextSpan);
|
|
@@ -259,9 +241,15 @@ function createLanguageService(core, ts, sys) {
|
|
|
259
241
|
return;
|
|
260
242
|
if (!textSpan)
|
|
261
243
|
return;
|
|
262
|
-
const [virtualFile, source] =
|
|
244
|
+
const [virtualFile, source] = getVirtualFile(fileName);
|
|
263
245
|
if (virtualFile && source) {
|
|
264
|
-
|
|
246
|
+
if (isTsPlugin) {
|
|
247
|
+
textSpan = {
|
|
248
|
+
start: textSpan.start - source.snapshot.getLength(),
|
|
249
|
+
length: textSpan.length,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
for (const [_, [sourceSnapshot, map]] of virtualFiles.getMaps(virtualFile)) {
|
|
265
253
|
if (source.snapshot !== sourceSnapshot)
|
|
266
254
|
continue;
|
|
267
255
|
const sourceLoc = map.toSourceOffset(textSpan.start);
|
|
@@ -283,8 +271,26 @@ function createLanguageService(core, ts, sys) {
|
|
|
283
271
|
};
|
|
284
272
|
}
|
|
285
273
|
}
|
|
274
|
+
function getVirtualFile(fileName) {
|
|
275
|
+
if (isTsPlugin) {
|
|
276
|
+
let result;
|
|
277
|
+
const source = virtualFiles.getSource(fileName);
|
|
278
|
+
if (source) {
|
|
279
|
+
(0, language_core_1.forEachEmbeddedFile)(source.root, file => {
|
|
280
|
+
const ext = file.fileName.replace(fileName, '');
|
|
281
|
+
if (file.kind === language_core_1.FileKind.TypeScriptHostFile && (ext === '.d.ts' || ext.match(/^\.(js|ts)x?$/))) {
|
|
282
|
+
result = file;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
return [result, source];
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
return virtualFiles.getVirtualFile(fileName);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
286
292
|
}
|
|
287
|
-
exports.
|
|
293
|
+
exports.decorateLanguageService = decorateLanguageService;
|
|
288
294
|
function notEmpty(value) {
|
|
289
295
|
return value !== null && value !== undefined;
|
|
290
296
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createLanguageServiceHost = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
|
+
const utilities_1 = require("./typescript/utilities");
|
|
5
6
|
function createLanguageServiceHost(ctx, ts, sys) {
|
|
6
7
|
let lastProjectVersion;
|
|
7
8
|
let tsProjectVersion = 0;
|
|
@@ -31,9 +32,12 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
31
32
|
return snapshot.getText(0, snapshot.getLength());
|
|
32
33
|
}
|
|
33
34
|
},
|
|
35
|
+
readDirectory,
|
|
36
|
+
getDirectories,
|
|
37
|
+
directoryExists,
|
|
34
38
|
fileExists,
|
|
35
39
|
getProjectVersion: () => {
|
|
36
|
-
return tsProjectVersion
|
|
40
|
+
return tsProjectVersion + ':' + sys.version;
|
|
37
41
|
},
|
|
38
42
|
getTypeRootsVersion: () => {
|
|
39
43
|
return sys.version ?? -1; // TODO: only update for /node_modules changes?
|
|
@@ -99,6 +103,54 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
99
103
|
oldTsVirtualFileSnapshots = newTsVirtualFileSnapshots;
|
|
100
104
|
oldOtherVirtualFileSnapshots = newOtherVirtualFileSnapshots;
|
|
101
105
|
}
|
|
106
|
+
function readDirectory(dirName, extensions, excludes, includes, depth) {
|
|
107
|
+
let matches = (0, utilities_1.matchFiles)(dirName, extensions, excludes, includes, sys?.useCaseSensitiveFileNames ?? false, ctx.host.getCurrentDirectory(), depth, (dirPath) => {
|
|
108
|
+
const files = [];
|
|
109
|
+
for (const fileName of getScriptFileNames()) {
|
|
110
|
+
if (fileName.toLowerCase().startsWith(dirPath.toLowerCase())) {
|
|
111
|
+
const baseName = fileName.substring(dirPath.length);
|
|
112
|
+
if (baseName.indexOf('/') === -1) {
|
|
113
|
+
files.push(baseName);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
files,
|
|
119
|
+
directories: getVirtualFileDirectories(dirPath),
|
|
120
|
+
};
|
|
121
|
+
}, sys?.realpath ? (path => sys.realpath(path)) : (path => path));
|
|
122
|
+
if (ctx) {
|
|
123
|
+
matches = matches.map(match => {
|
|
124
|
+
const [_, source] = ctx.virtualFiles.getVirtualFile(match);
|
|
125
|
+
if (source) {
|
|
126
|
+
return source.fileName;
|
|
127
|
+
}
|
|
128
|
+
return match;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return [...new Set([
|
|
132
|
+
...matches,
|
|
133
|
+
...sys.readDirectory(dirName, extensions, excludes, includes, depth),
|
|
134
|
+
])];
|
|
135
|
+
}
|
|
136
|
+
function getDirectories(dirName) {
|
|
137
|
+
return [...new Set([
|
|
138
|
+
...getVirtualFileDirectories(dirName),
|
|
139
|
+
...sys.getDirectories(dirName),
|
|
140
|
+
])];
|
|
141
|
+
}
|
|
142
|
+
function getVirtualFileDirectories(dirName) {
|
|
143
|
+
const names = new Set();
|
|
144
|
+
for (const fileName of getScriptFileNames()) {
|
|
145
|
+
if (fileName.toLowerCase().startsWith(dirName.toLowerCase())) {
|
|
146
|
+
const path = fileName.substring(dirName.length);
|
|
147
|
+
if (path.indexOf('/') >= 0) {
|
|
148
|
+
names.add(path.split('/')[0]);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return [...names];
|
|
153
|
+
}
|
|
102
154
|
function getScriptFileNames() {
|
|
103
155
|
const tsFileNames = new Set();
|
|
104
156
|
for (const { root } of ctx.virtualFiles.allSources()) {
|
|
@@ -159,6 +211,12 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
159
211
|
// fs files
|
|
160
212
|
return sys.getModifiedTime?.(fileName)?.valueOf().toString() ?? '';
|
|
161
213
|
}
|
|
214
|
+
function directoryExists(dirName) {
|
|
215
|
+
if (getScriptFileNames().some(fileName => fileName.toLowerCase().startsWith(dirName.toLowerCase()))) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
return sys.directoryExists(dirName);
|
|
219
|
+
}
|
|
162
220
|
function fileExists(fileName) {
|
|
163
221
|
// fill external virtual files
|
|
164
222
|
const ext = fileName.substring(fileName.lastIndexOf('.'));
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { VirtualFiles } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript/lib/tsserverlibrary';
|
|
3
|
+
export declare function decorateLanguageServiceHost(virtualFiles: VirtualFiles, languageServiceHost: ts.LanguageServiceHost, ts: typeof import('typescript/lib/tsserverlibrary'), exts: string[]): void;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decorateLanguageServiceHost = void 0;
|
|
4
|
+
const language_core_1 = require("@volar/language-core");
|
|
5
|
+
function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts, exts) {
|
|
6
|
+
const scripts = new Map();
|
|
7
|
+
const resolveModuleNameLiterals = languageServiceHost.resolveModuleNameLiterals?.bind(languageServiceHost);
|
|
8
|
+
const resolveModuleNames = languageServiceHost.resolveModuleNames?.bind(languageServiceHost);
|
|
9
|
+
const getScriptSnapshot = languageServiceHost.getScriptSnapshot.bind(languageServiceHost);
|
|
10
|
+
if (resolveModuleNameLiterals) {
|
|
11
|
+
languageServiceHost.resolveModuleNameLiterals = (moduleNames, containingFile, redirectedReference, options, ...rest) => {
|
|
12
|
+
const resolvedModules = resolveModuleNameLiterals(moduleNames, containingFile, redirectedReference, options, ...rest);
|
|
13
|
+
return moduleNames.map((name, i) => {
|
|
14
|
+
if (exts.some(ext => name.text.endsWith(ext))) {
|
|
15
|
+
return resolveModuleName(name.text, containingFile, options, redirectedReference);
|
|
16
|
+
}
|
|
17
|
+
return resolvedModules[i];
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
else if (resolveModuleNames) {
|
|
22
|
+
languageServiceHost.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, options, containingSourceFile) => {
|
|
23
|
+
const resolvedModules = resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, options, containingSourceFile);
|
|
24
|
+
return moduleNames.map((name, i) => {
|
|
25
|
+
if (exts.some(ext => name.endsWith(ext))) {
|
|
26
|
+
return resolveModuleName(name, containingFile, options, redirectedReference).resolvedModule;
|
|
27
|
+
}
|
|
28
|
+
return resolvedModules[i];
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
languageServiceHost.getScriptSnapshot = (fileName) => {
|
|
33
|
+
if (scripts.has(fileName)) {
|
|
34
|
+
updateScript(fileName);
|
|
35
|
+
}
|
|
36
|
+
return scripts.get(fileName)?.snapshot ?? getScriptSnapshot(fileName);
|
|
37
|
+
};
|
|
38
|
+
function resolveModuleName(name, containingFile, options, redirectedReference) {
|
|
39
|
+
const resolved = ts.resolveModuleName(name, containingFile, options, {
|
|
40
|
+
readFile(fileName) {
|
|
41
|
+
return languageServiceHost.readFile(fileName);
|
|
42
|
+
},
|
|
43
|
+
fileExists(fileName) {
|
|
44
|
+
if (exts.some(ext => fileName.endsWith(ext + '.d.ts'))) {
|
|
45
|
+
return languageServiceHost.fileExists(fileName.slice(0, -'.d.ts'.length));
|
|
46
|
+
}
|
|
47
|
+
return languageServiceHost.fileExists(fileName);
|
|
48
|
+
},
|
|
49
|
+
}, undefined, redirectedReference);
|
|
50
|
+
if (resolved.resolvedModule) {
|
|
51
|
+
resolved.resolvedModule.resolvedFileName = resolved.resolvedModule.resolvedFileName.slice(0, -'.d.ts'.length);
|
|
52
|
+
const script = updateScript(resolved.resolvedModule.resolvedFileName);
|
|
53
|
+
if (script) {
|
|
54
|
+
resolved.resolvedModule.extension = script.extension;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return resolved;
|
|
58
|
+
}
|
|
59
|
+
function updateScript(fileName) {
|
|
60
|
+
const version = languageServiceHost.getScriptVersion(fileName);
|
|
61
|
+
if (version !== scripts.get(fileName)?.version) {
|
|
62
|
+
const text = languageServiceHost.readFile(fileName);
|
|
63
|
+
let snapshot;
|
|
64
|
+
let extension = '.ts';
|
|
65
|
+
if (text !== undefined) {
|
|
66
|
+
const virtualFile = virtualFiles.updateSource(fileName, ts.ScriptSnapshot.fromString(text), undefined);
|
|
67
|
+
if (virtualFile) {
|
|
68
|
+
let patchedText = text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
|
|
69
|
+
(0, language_core_1.forEachEmbeddedFile)(virtualFile, file => {
|
|
70
|
+
const ext = file.fileName.replace(fileName, '');
|
|
71
|
+
if (file.kind === language_core_1.FileKind.TypeScriptHostFile && (ext === '.d.ts' || ext.match(/^\.(js|ts)x?$/))) {
|
|
72
|
+
extension = ext;
|
|
73
|
+
patchedText += file.snapshot.getText(0, file.snapshot.getLength());
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
snapshot = ts.ScriptSnapshot.fromString(patchedText);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
virtualFiles.deleteSource(fileName);
|
|
81
|
+
}
|
|
82
|
+
scripts.set(fileName, {
|
|
83
|
+
version,
|
|
84
|
+
snapshot,
|
|
85
|
+
extension,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return scripts.get(fileName);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.decorateLanguageServiceHost = decorateLanguageServiceHost;
|
|
92
|
+
//# sourceMappingURL=serverPlugin.js.map
|
package/out/sys.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ServiceEnvironment, Disposable
|
|
1
|
+
import type { ServiceEnvironment, Disposable } from '@volar/language-service';
|
|
2
2
|
import type * as ts from 'typescript/lib/tsserverlibrary';
|
|
3
3
|
import { IDtsHost } from './dtsHost';
|
|
4
|
-
export declare function createSys(
|
|
4
|
+
export declare function createSys(ts: typeof import('typescript/lib/tsserverlibrary'), env: ServiceEnvironment, dtsHost?: IDtsHost): ts.System & {
|
|
5
5
|
version: number;
|
|
6
6
|
sync(): Promise<number>;
|
|
7
7
|
} & Disposable;
|
package/out/sys.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createSys = void 0;
|
|
4
|
-
const language_core_1 = require("@volar/language-core");
|
|
5
4
|
const path_1 = require("path");
|
|
6
5
|
const utilities_1 = require("./typescript/utilities");
|
|
7
6
|
const dtsHost_1 = require("./dtsHost");
|
|
8
7
|
let currentCwd = '';
|
|
9
|
-
function createSys(
|
|
8
|
+
function createSys(ts, env, dtsHost) {
|
|
10
9
|
let version = 0;
|
|
11
10
|
const rootPath = env.uriToFileName(env.rootUri.toString());
|
|
12
11
|
const sys = ts.sys;
|
|
@@ -150,16 +149,16 @@ function createSys(ctx, ts, env, dtsHost) {
|
|
|
150
149
|
promises.add(promise);
|
|
151
150
|
result.then(result => {
|
|
152
151
|
promises.delete(promise);
|
|
153
|
-
file.exists = result?.type === 1
|
|
152
|
+
file.exists = result?.type === 1;
|
|
154
153
|
if (file.exists) {
|
|
155
154
|
const time = Date.now();
|
|
156
|
-
file.modifiedTime = time !== file.modifiedTime ? time :
|
|
155
|
+
file.modifiedTime = time !== file.modifiedTime ? time : file.modifiedTime + 1;
|
|
157
156
|
version++;
|
|
158
157
|
}
|
|
159
158
|
});
|
|
160
159
|
}
|
|
161
160
|
else {
|
|
162
|
-
file.exists = result?.type === 1
|
|
161
|
+
file.exists = result?.type === 1;
|
|
163
162
|
}
|
|
164
163
|
}
|
|
165
164
|
return file.exists;
|
|
@@ -173,40 +172,15 @@ function createSys(ctx, ts, env, dtsHost) {
|
|
|
173
172
|
}
|
|
174
173
|
function readDirectory(dirName, extensions, excludes, includes, depth) {
|
|
175
174
|
dirName = resolvePath(dirName);
|
|
176
|
-
|
|
175
|
+
const matches = (0, utilities_1.matchFiles)(dirName, extensions, excludes, includes, sys?.useCaseSensitiveFileNames ?? false, rootPath, depth, (dirPath) => {
|
|
177
176
|
dirPath = resolvePath(dirPath);
|
|
178
177
|
readDirectoryWorker(dirPath);
|
|
179
178
|
const dir = getDir(dirPath);
|
|
180
|
-
const virtualFiles = [];
|
|
181
|
-
if (ctx) {
|
|
182
|
-
for (const { root } of ctx.virtualFiles.allSources()) {
|
|
183
|
-
(0, language_core_1.forEachEmbeddedFile)(root, file => {
|
|
184
|
-
if (file.kind === language_core_1.FileKind.TypeScriptHostFile) {
|
|
185
|
-
const fileDirName = path_1.posix.dirname(file.fileName);
|
|
186
|
-
if (fileDirName.toLowerCase() === dirPath.toLowerCase()) {
|
|
187
|
-
virtualFiles.push(path_1.posix.basename(file.fileName));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
179
|
return {
|
|
194
|
-
files: [
|
|
195
|
-
...[...Object.entries(dir.files)].filter(([_, file]) => file.exists).map(([name]) => name),
|
|
196
|
-
...virtualFiles,
|
|
197
|
-
],
|
|
180
|
+
files: [...Object.entries(dir.files)].filter(([_, file]) => file.exists).map(([name]) => name),
|
|
198
181
|
directories: [...Object.entries(dir.dirs)].filter(([_, dir]) => dir.exists).map(([name]) => name),
|
|
199
182
|
};
|
|
200
183
|
}, sys?.realpath ? (path => sys.realpath(path)) : (path => path));
|
|
201
|
-
if (ctx) {
|
|
202
|
-
matches = matches.map(match => {
|
|
203
|
-
const [_, source] = ctx.virtualFiles.getVirtualFile(match);
|
|
204
|
-
if (source) {
|
|
205
|
-
return source.fileName;
|
|
206
|
-
}
|
|
207
|
-
return match;
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
184
|
return [...new Set(matches)];
|
|
211
185
|
}
|
|
212
186
|
function readFileWorker(fileName, encoding, dir) {
|
|
@@ -254,30 +228,57 @@ function createSys(ctx, ts, env, dtsHost) {
|
|
|
254
228
|
return;
|
|
255
229
|
}
|
|
256
230
|
dir.requested = true;
|
|
257
|
-
const uri = env.fileNameToUri(dirName);
|
|
258
231
|
const result = dirName.startsWith('/node_modules/') && dtsHost
|
|
259
232
|
? dtsHost.readDirectory(dirName)
|
|
260
|
-
: env.fs?.readDirectory(
|
|
233
|
+
: env.fs?.readDirectory(env.fileNameToUri(dirName || '.'));
|
|
261
234
|
if (typeof result === 'object' && 'then' in result) {
|
|
262
235
|
const promise = result;
|
|
263
236
|
promises.add(promise);
|
|
264
237
|
result.then((result) => {
|
|
265
238
|
promises.delete(promise);
|
|
266
|
-
if (onReadDirectoryResult(dir, result)) {
|
|
239
|
+
if (onReadDirectoryResult(dirName, dir, result)) {
|
|
267
240
|
version++;
|
|
268
241
|
}
|
|
269
242
|
});
|
|
270
243
|
}
|
|
271
244
|
else {
|
|
272
|
-
onReadDirectoryResult(dir, result ?? []);
|
|
245
|
+
onReadDirectoryResult(dirName, dir, result ?? []);
|
|
273
246
|
}
|
|
274
247
|
}
|
|
275
|
-
function onReadDirectoryResult(dir, result) {
|
|
248
|
+
function onReadDirectoryResult(dirName, dir, result) {
|
|
276
249
|
// See https://github.com/microsoft/TypeScript/blob/e1a9290051a3b0cbdfbadc3adbcc155a4641522a/src/compiler/sys.ts#L1853-L1857
|
|
277
250
|
result = result.filter(([name]) => name !== '.' && name !== '..');
|
|
278
251
|
let updated = false;
|
|
279
|
-
for (const [name,
|
|
280
|
-
|
|
252
|
+
for (const [name, _fileType] of result) {
|
|
253
|
+
let fileType = _fileType;
|
|
254
|
+
if (fileType === 64) {
|
|
255
|
+
const stat = env.fs?.stat(env.fileNameToUri(dirName + '/' + name));
|
|
256
|
+
if (typeof stat === 'object' && 'then' in stat) {
|
|
257
|
+
const promise = stat;
|
|
258
|
+
promises.add(promise);
|
|
259
|
+
stat.then((stat) => {
|
|
260
|
+
promises.delete(promise);
|
|
261
|
+
if (stat?.type === 1) {
|
|
262
|
+
dir.files[name] ??= {};
|
|
263
|
+
if (!dir.files[name].exists) {
|
|
264
|
+
dir.files[name].exists = true;
|
|
265
|
+
version++;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else if (stat?.type === 2) {
|
|
269
|
+
const childDir = getDirFromDir(dir, name);
|
|
270
|
+
if (!childDir.exists) {
|
|
271
|
+
childDir.exists = true;
|
|
272
|
+
version++;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
else if (stat) {
|
|
278
|
+
fileType = stat.type;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (fileType === 1) {
|
|
281
282
|
dir.files[name] ??= {};
|
|
282
283
|
if (!dir.files[name].exists) {
|
|
283
284
|
dir.files[name].exists = true;
|
|
@@ -298,9 +299,9 @@ function createSys(ctx, ts, env, dtsHost) {
|
|
|
298
299
|
const dirNames = [];
|
|
299
300
|
let currentDirPath = dirName;
|
|
300
301
|
let currentDirName = path_1.posix.basename(currentDirPath);
|
|
301
|
-
let
|
|
302
|
-
while (
|
|
303
|
-
|
|
302
|
+
let lastDirPath;
|
|
303
|
+
while (lastDirPath !== currentDirPath) {
|
|
304
|
+
lastDirPath = currentDirPath;
|
|
304
305
|
dirNames.push(currentDirName);
|
|
305
306
|
currentDirPath = path_1.posix.dirname(currentDirPath);
|
|
306
307
|
currentDirName = path_1.posix.basename(currentDirPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volar/typescript",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.8",
|
|
4
4
|
"main": "out/index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"directory": "packages/typescript"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@volar/language-core": "1.7.
|
|
16
|
+
"@volar/language-core": "1.7.8"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@volar/language-service": "1.7.
|
|
19
|
+
"@volar/language-service": "1.7.8"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "e7c1b16e5c78702de6986eafa17ae96000ffe0cb"
|
|
22
22
|
}
|