@volar/typescript 1.7.7 → 1.7.9
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 +19 -50
- package/out/serverPlugin.d.ts +3 -0
- package/out/serverPlugin.js +113 -0
- package/out/sys.js +38 -10
- 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
|
}
|
|
@@ -6,6 +6,7 @@ const utilities_1 = require("./typescript/utilities");
|
|
|
6
6
|
function createLanguageServiceHost(ctx, ts, sys) {
|
|
7
7
|
let lastProjectVersion;
|
|
8
8
|
let tsProjectVersion = 0;
|
|
9
|
+
let tsFileNames = [];
|
|
9
10
|
const _tsHost = {
|
|
10
11
|
...sys,
|
|
11
12
|
getCurrentDirectory: () => ctx.host.getCurrentDirectory(),
|
|
@@ -34,7 +35,7 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
34
35
|
},
|
|
35
36
|
readDirectory,
|
|
36
37
|
getDirectories,
|
|
37
|
-
directoryExists,
|
|
38
|
+
directoryExists: undefined,
|
|
38
39
|
fileExists,
|
|
39
40
|
getProjectVersion: () => {
|
|
40
41
|
return tsProjectVersion + ':' + sys.version;
|
|
@@ -42,7 +43,7 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
42
43
|
getTypeRootsVersion: () => {
|
|
43
44
|
return sys.version ?? -1; // TODO: only update for /node_modules changes?
|
|
44
45
|
},
|
|
45
|
-
getScriptFileNames,
|
|
46
|
+
getScriptFileNames: () => tsFileNames,
|
|
46
47
|
getScriptVersion,
|
|
47
48
|
getScriptSnapshot,
|
|
48
49
|
getScriptKind(fileName) {
|
|
@@ -102,11 +103,25 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
102
103
|
}
|
|
103
104
|
oldTsVirtualFileSnapshots = newTsVirtualFileSnapshots;
|
|
104
105
|
oldOtherVirtualFileSnapshots = newOtherVirtualFileSnapshots;
|
|
106
|
+
const tsFileNamesSet = new Set();
|
|
107
|
+
for (const { root } of ctx.virtualFiles.allSources()) {
|
|
108
|
+
forEachEmbeddedFile(root, embedded => {
|
|
109
|
+
if (embedded.kind === 1) {
|
|
110
|
+
tsFileNamesSet.add(embedded.fileName); // virtual .ts
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
for (const fileName of ctx.host.getScriptFileNames()) {
|
|
115
|
+
if (!ctx.virtualFiles.hasSource(fileName)) {
|
|
116
|
+
tsFileNamesSet.add(fileName); // .ts
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
tsFileNames = [...tsFileNamesSet];
|
|
105
120
|
}
|
|
106
121
|
function readDirectory(dirName, extensions, excludes, includes, depth) {
|
|
107
122
|
let matches = (0, utilities_1.matchFiles)(dirName, extensions, excludes, includes, sys?.useCaseSensitiveFileNames ?? false, ctx.host.getCurrentDirectory(), depth, (dirPath) => {
|
|
108
123
|
const files = [];
|
|
109
|
-
for (const fileName of
|
|
124
|
+
for (const fileName of tsFileNames) {
|
|
110
125
|
if (fileName.toLowerCase().startsWith(dirPath.toLowerCase())) {
|
|
111
126
|
const baseName = fileName.substring(dirPath.length);
|
|
112
127
|
if (baseName.indexOf('/') === -1) {
|
|
@@ -141,7 +156,7 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
141
156
|
}
|
|
142
157
|
function getVirtualFileDirectories(dirName) {
|
|
143
158
|
const names = new Set();
|
|
144
|
-
for (const fileName of
|
|
159
|
+
for (const fileName of tsFileNames) {
|
|
145
160
|
if (fileName.toLowerCase().startsWith(dirName.toLowerCase())) {
|
|
146
161
|
const path = fileName.substring(dirName.length);
|
|
147
162
|
if (path.indexOf('/') >= 0) {
|
|
@@ -149,27 +164,8 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
149
164
|
}
|
|
150
165
|
}
|
|
151
166
|
}
|
|
152
|
-
for (const name of sys.getDirectories(dirName)) {
|
|
153
|
-
names.add(name);
|
|
154
|
-
}
|
|
155
167
|
return [...names];
|
|
156
168
|
}
|
|
157
|
-
function getScriptFileNames() {
|
|
158
|
-
const tsFileNames = new Set();
|
|
159
|
-
for (const { root } of ctx.virtualFiles.allSources()) {
|
|
160
|
-
forEachEmbeddedFile(root, embedded => {
|
|
161
|
-
if (embedded.kind === 1) {
|
|
162
|
-
tsFileNames.add(embedded.fileName); // virtual .ts
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
for (const fileName of ctx.host.getScriptFileNames()) {
|
|
167
|
-
if (!ctx.virtualFiles.hasSource(fileName)) {
|
|
168
|
-
tsFileNames.add(fileName); // .ts
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return [...tsFileNames];
|
|
172
|
-
}
|
|
173
169
|
function getScriptSnapshot(fileName) {
|
|
174
170
|
// virtual files
|
|
175
171
|
const [virtualFile] = ctx.virtualFiles.getVirtualFile(fileName);
|
|
@@ -214,34 +210,7 @@ function createLanguageServiceHost(ctx, ts, sys) {
|
|
|
214
210
|
// fs files
|
|
215
211
|
return sys.getModifiedTime?.(fileName)?.valueOf().toString() ?? '';
|
|
216
212
|
}
|
|
217
|
-
function directoryExists(dirName) {
|
|
218
|
-
if (getScriptFileNames().some(fileName => fileName.toLowerCase().startsWith(dirName.toLowerCase()))) {
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
return sys.directoryExists(dirName);
|
|
222
|
-
}
|
|
223
213
|
function fileExists(fileName) {
|
|
224
|
-
// fill external virtual files
|
|
225
|
-
const ext = fileName.substring(fileName.lastIndexOf('.'));
|
|
226
|
-
if (ext === '.js'
|
|
227
|
-
|| ext === '.ts'
|
|
228
|
-
|| ext === '.jsx'
|
|
229
|
-
|| ext === '.tsx') {
|
|
230
|
-
/**
|
|
231
|
-
* If try to access a external .vue file that outside of the project,
|
|
232
|
-
* the file will not process by language service host,
|
|
233
|
-
* so virtual file will not be created.
|
|
234
|
-
*
|
|
235
|
-
* We try to create virtual file here.
|
|
236
|
-
*/
|
|
237
|
-
const sourceFileName = fileName.substring(0, fileName.lastIndexOf('.'));
|
|
238
|
-
if (!ctx.virtualFiles.hasSource(sourceFileName)) {
|
|
239
|
-
const scriptSnapshot = getScriptSnapshot(sourceFileName);
|
|
240
|
-
if (scriptSnapshot) {
|
|
241
|
-
ctx.virtualFiles.updateSource(sourceFileName, scriptSnapshot, ctx.host.getLanguageId?.(sourceFileName));
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
214
|
// virtual files
|
|
246
215
|
if (ctx.virtualFiles.hasVirtualFile(fileName)) {
|
|
247
216
|
return true;
|
|
@@ -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,113 @@
|
|
|
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
|
+
let extraProjectVersion = 0;
|
|
7
|
+
const scripts = new Map();
|
|
8
|
+
const resolveModuleNameLiterals = languageServiceHost.resolveModuleNameLiterals?.bind(languageServiceHost);
|
|
9
|
+
const resolveModuleNames = languageServiceHost.resolveModuleNames?.bind(languageServiceHost);
|
|
10
|
+
const getProjectVersion = languageServiceHost.getProjectVersion?.bind(languageServiceHost);
|
|
11
|
+
const getScriptFileNames = languageServiceHost.getScriptFileNames.bind(languageServiceHost);
|
|
12
|
+
const getScriptSnapshot = languageServiceHost.getScriptSnapshot.bind(languageServiceHost);
|
|
13
|
+
if (resolveModuleNameLiterals) {
|
|
14
|
+
languageServiceHost.resolveModuleNameLiterals = (moduleNames, containingFile, redirectedReference, options, ...rest) => {
|
|
15
|
+
const resolvedModules = resolveModuleNameLiterals(moduleNames, containingFile, redirectedReference, options, ...rest);
|
|
16
|
+
return moduleNames.map((name, i) => {
|
|
17
|
+
if (exts.some(ext => name.text.endsWith(ext))) {
|
|
18
|
+
return resolveModuleName(name.text, containingFile, options, redirectedReference);
|
|
19
|
+
}
|
|
20
|
+
return resolvedModules[i];
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
else if (resolveModuleNames) {
|
|
25
|
+
languageServiceHost.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, options, containingSourceFile) => {
|
|
26
|
+
const resolvedModules = resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, options, containingSourceFile);
|
|
27
|
+
return moduleNames.map((name, i) => {
|
|
28
|
+
if (exts.some(ext => name.endsWith(ext))) {
|
|
29
|
+
return resolveModuleName(name, containingFile, options, redirectedReference).resolvedModule;
|
|
30
|
+
}
|
|
31
|
+
return resolvedModules[i];
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (getProjectVersion) {
|
|
36
|
+
languageServiceHost.getProjectVersion = () => {
|
|
37
|
+
return getProjectVersion() + ':' + extraProjectVersion;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
languageServiceHost.getScriptFileNames = () => {
|
|
41
|
+
if (languageServiceHost.getCompilationSettings().composite) {
|
|
42
|
+
return [
|
|
43
|
+
...getScriptFileNames(),
|
|
44
|
+
...virtualFiles.allSources().map(source => source.fileName),
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return getScriptFileNames();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
languageServiceHost.getScriptSnapshot = (fileName) => {
|
|
52
|
+
if (scripts.has(fileName)) {
|
|
53
|
+
updateScript(fileName);
|
|
54
|
+
}
|
|
55
|
+
return scripts.get(fileName)?.snapshot ?? getScriptSnapshot(fileName);
|
|
56
|
+
};
|
|
57
|
+
function resolveModuleName(name, containingFile, options, redirectedReference) {
|
|
58
|
+
const resolved = ts.resolveModuleName(name, containingFile, options, {
|
|
59
|
+
readFile(fileName) {
|
|
60
|
+
return languageServiceHost.readFile(fileName);
|
|
61
|
+
},
|
|
62
|
+
fileExists(fileName) {
|
|
63
|
+
if (exts.some(ext => fileName.endsWith(ext + '.d.ts'))) {
|
|
64
|
+
return languageServiceHost.fileExists(fileName.slice(0, -'.d.ts'.length));
|
|
65
|
+
}
|
|
66
|
+
return languageServiceHost.fileExists(fileName);
|
|
67
|
+
},
|
|
68
|
+
}, undefined, redirectedReference);
|
|
69
|
+
if (resolved.resolvedModule) {
|
|
70
|
+
resolved.resolvedModule.resolvedFileName = resolved.resolvedModule.resolvedFileName.slice(0, -'.d.ts'.length);
|
|
71
|
+
const script = updateScript(resolved.resolvedModule.resolvedFileName);
|
|
72
|
+
if (script) {
|
|
73
|
+
resolved.resolvedModule.extension = script.extension;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return resolved;
|
|
77
|
+
}
|
|
78
|
+
function updateScript(fileName) {
|
|
79
|
+
const version = languageServiceHost.getScriptVersion(fileName);
|
|
80
|
+
if (version !== scripts.get(fileName)?.version) {
|
|
81
|
+
const text = languageServiceHost.readFile(fileName);
|
|
82
|
+
let snapshot;
|
|
83
|
+
let extension = '.ts';
|
|
84
|
+
if (text !== undefined) {
|
|
85
|
+
extraProjectVersion++;
|
|
86
|
+
const virtualFile = virtualFiles.updateSource(fileName, ts.ScriptSnapshot.fromString(text), undefined);
|
|
87
|
+
if (virtualFile) {
|
|
88
|
+
let patchedText = text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
|
|
89
|
+
(0, language_core_1.forEachEmbeddedFile)(virtualFile, file => {
|
|
90
|
+
const ext = file.fileName.replace(fileName, '');
|
|
91
|
+
if (file.kind === language_core_1.FileKind.TypeScriptHostFile && (ext === '.d.ts' || ext.match(/^\.(js|ts)x?$/))) {
|
|
92
|
+
extension = ext;
|
|
93
|
+
patchedText += file.snapshot.getText(0, file.snapshot.getLength());
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
snapshot = ts.ScriptSnapshot.fromString(patchedText);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (virtualFiles.hasSource(fileName)) {
|
|
100
|
+
extraProjectVersion++;
|
|
101
|
+
virtualFiles.deleteSource(fileName);
|
|
102
|
+
}
|
|
103
|
+
scripts.set(fileName, {
|
|
104
|
+
version,
|
|
105
|
+
snapshot,
|
|
106
|
+
extension,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return scripts.get(fileName);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.decorateLanguageServiceHost = decorateLanguageServiceHost;
|
|
113
|
+
//# sourceMappingURL=serverPlugin.js.map
|
package/out/sys.js
CHANGED
|
@@ -149,7 +149,7 @@ function createSys(ts, env, dtsHost) {
|
|
|
149
149
|
promises.add(promise);
|
|
150
150
|
result.then(result => {
|
|
151
151
|
promises.delete(promise);
|
|
152
|
-
file.exists = result?.type === 1
|
|
152
|
+
file.exists = result?.type === 1;
|
|
153
153
|
if (file.exists) {
|
|
154
154
|
const time = Date.now();
|
|
155
155
|
file.modifiedTime = time !== file.modifiedTime ? time : file.modifiedTime + 1;
|
|
@@ -158,7 +158,7 @@ function createSys(ts, env, dtsHost) {
|
|
|
158
158
|
});
|
|
159
159
|
}
|
|
160
160
|
else {
|
|
161
|
-
file.exists = result?.type === 1
|
|
161
|
+
file.exists = result?.type === 1;
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
return file.exists;
|
|
@@ -236,21 +236,49 @@ function createSys(ts, env, dtsHost) {
|
|
|
236
236
|
promises.add(promise);
|
|
237
237
|
result.then((result) => {
|
|
238
238
|
promises.delete(promise);
|
|
239
|
-
if (onReadDirectoryResult(dir, result)) {
|
|
239
|
+
if (onReadDirectoryResult(dirName, dir, result)) {
|
|
240
240
|
version++;
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
}
|
|
244
244
|
else {
|
|
245
|
-
onReadDirectoryResult(dir, result ?? []);
|
|
245
|
+
onReadDirectoryResult(dirName, dir, result ?? []);
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
function onReadDirectoryResult(dir, result) {
|
|
248
|
+
function onReadDirectoryResult(dirName, dir, result) {
|
|
249
249
|
// See https://github.com/microsoft/TypeScript/blob/e1a9290051a3b0cbdfbadc3adbcc155a4641522a/src/compiler/sys.ts#L1853-L1857
|
|
250
250
|
result = result.filter(([name]) => name !== '.' && name !== '..');
|
|
251
251
|
let updated = false;
|
|
252
|
-
for (const [name,
|
|
253
|
-
|
|
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) {
|
|
254
282
|
dir.files[name] ??= {};
|
|
255
283
|
if (!dir.files[name].exists) {
|
|
256
284
|
dir.files[name].exists = true;
|
|
@@ -271,9 +299,9 @@ function createSys(ts, env, dtsHost) {
|
|
|
271
299
|
const dirNames = [];
|
|
272
300
|
let currentDirPath = dirName;
|
|
273
301
|
let currentDirName = path_1.posix.basename(currentDirPath);
|
|
274
|
-
let
|
|
275
|
-
while (
|
|
276
|
-
|
|
302
|
+
let lastDirPath;
|
|
303
|
+
while (lastDirPath !== currentDirPath) {
|
|
304
|
+
lastDirPath = currentDirPath;
|
|
277
305
|
dirNames.push(currentDirName);
|
|
278
306
|
currentDirPath = path_1.posix.dirname(currentDirPath);
|
|
279
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.9",
|
|
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.9"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@volar/language-service": "1.7.
|
|
19
|
+
"@volar/language-service": "1.7.9"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "c28b1b3fc725f38d335f4341179678c78828528f"
|
|
22
22
|
}
|