@volar/typescript 1.6.9 → 1.7.1-patch.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/out/documentRegistry.d.ts +2 -0
- package/out/documentRegistry.js +14 -0
- package/out/dtsHost.d.ts +26 -0
- package/out/dtsHost.js +190 -0
- package/out/getProgram.d.ts +1 -1
- package/out/getProgram.js +8 -8
- package/out/index.d.ts +5 -8
- package/out/index.js +19 -285
- package/out/languageService.d.ts +9 -0
- package/out/languageService.js +292 -0
- package/out/languageServiceHost.d.ts +5 -0
- package/out/languageServiceHost.js +210 -0
- package/out/sys.d.ts +7 -0
- package/out/sys.js +327 -0
- package/out/typescript/core.d.ts +83 -0
- package/out/typescript/core.js +320 -0
- package/out/typescript/corePublic.d.ts +91 -0
- package/out/typescript/corePublic.js +51 -0
- package/out/typescript/path.d.ts +112 -0
- package/out/typescript/path.js +417 -0
- package/out/typescript/types.d.ts +129 -0
- package/out/typescript/types.js +3 -0
- package/out/typescript/utilities.d.ts +7 -0
- package/out/typescript/utilities.js +250 -0
- package/package.json +5 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDocumentRegistry = void 0;
|
|
4
|
+
const documentRegistries = [];
|
|
5
|
+
function getDocumentRegistry(ts, useCaseSensitiveFileNames, currentDirectory) {
|
|
6
|
+
let documentRegistry = documentRegistries.find(item => item[0] === useCaseSensitiveFileNames && item[1] === currentDirectory)?.[2];
|
|
7
|
+
if (!documentRegistry) {
|
|
8
|
+
documentRegistry = ts.createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory);
|
|
9
|
+
documentRegistries.push([useCaseSensitiveFileNames, currentDirectory, documentRegistry]);
|
|
10
|
+
}
|
|
11
|
+
return documentRegistry;
|
|
12
|
+
}
|
|
13
|
+
exports.getDocumentRegistry = getDocumentRegistry;
|
|
14
|
+
//# sourceMappingURL=documentRegistry.js.map
|
package/out/dtsHost.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FileStat, FileType } from '@volar/language-service';
|
|
2
|
+
export interface IDtsHost {
|
|
3
|
+
stat(uri: string): Promise<FileStat | undefined>;
|
|
4
|
+
readFile(fileName: string): Promise<string | undefined>;
|
|
5
|
+
readDirectory(dirName: string): Promise<[string, FileType][]>;
|
|
6
|
+
}
|
|
7
|
+
export declare function createJsDelivrDtsHost(versions?: Record<string, string>, onFetch?: (fileName: string, text: string) => void): DtsHost;
|
|
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
|
+
}
|
|
25
|
+
export declare function getPackageNameOfDtsPath(path: string): string | undefined;
|
|
26
|
+
export {};
|
package/out/dtsHost.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPackageNameOfDtsPath = exports.createJsDelivrDtsHost = void 0;
|
|
4
|
+
function createJsDelivrDtsHost(versions = {}, onFetch) {
|
|
5
|
+
return new DtsHost(async (fileName) => {
|
|
6
|
+
const requestFileName = resolveRequestFileName(fileName);
|
|
7
|
+
const url = 'https://cdn.jsdelivr.net/npm/' + requestFileName.slice('/node_modules/'.length);
|
|
8
|
+
const text = await fetchText(url);
|
|
9
|
+
if (text !== undefined) {
|
|
10
|
+
onFetch?.(fileName, text);
|
|
11
|
+
}
|
|
12
|
+
return text;
|
|
13
|
+
}, async (pkg) => {
|
|
14
|
+
let version = versions[pkg];
|
|
15
|
+
if (!version) {
|
|
16
|
+
const data = await fetchJson(`https://data.jsdelivr.com/v1/package/resolve/npm/${pkg}@latest`);
|
|
17
|
+
if (data?.version) {
|
|
18
|
+
version = data.version;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!version) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const flat = await fetchJson(`https://data.jsdelivr.com/v1/package/npm/${pkg}@${version}/flat`);
|
|
25
|
+
if (!flat) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
return flat.files.map(file => file.name);
|
|
29
|
+
});
|
|
30
|
+
function resolveRequestFileName(fileName) {
|
|
31
|
+
for (const [key, version] of Object.entries(versions)) {
|
|
32
|
+
if (fileName.startsWith(`/node_modules/${key}/`)) {
|
|
33
|
+
fileName = fileName.replace(`/node_modules/${key}/`, `/node_modules/${key}@${version}/`);
|
|
34
|
+
return fileName;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return fileName;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.createJsDelivrDtsHost = createJsDelivrDtsHost;
|
|
41
|
+
class DtsHost {
|
|
42
|
+
constructor(fetchText, flat) {
|
|
43
|
+
this.fetchText = fetchText;
|
|
44
|
+
this.flat = flat;
|
|
45
|
+
this.fetchResults = new Map();
|
|
46
|
+
this.flatResults = new Map();
|
|
47
|
+
}
|
|
48
|
+
async stat(fileName) {
|
|
49
|
+
if (!await this.valid(fileName)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const pkgName = getPackageNameOfDtsPath(fileName);
|
|
53
|
+
if (!pkgName) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (!this.flatResults.has(pkgName)) {
|
|
57
|
+
this.flatResults.set(pkgName, this.flat(pkgName));
|
|
58
|
+
}
|
|
59
|
+
const flat = await this.flatResults.get(pkgName);
|
|
60
|
+
const filePath = fileName.slice(`/node_modules/${pkgName}`.length);
|
|
61
|
+
if (flat.includes(filePath)) {
|
|
62
|
+
return {
|
|
63
|
+
type: 1,
|
|
64
|
+
ctime: -1,
|
|
65
|
+
mtime: -1,
|
|
66
|
+
size: -1,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
else if (flat.some(f => f.startsWith(filePath + '/'))) {
|
|
70
|
+
return {
|
|
71
|
+
type: 2,
|
|
72
|
+
ctime: -1,
|
|
73
|
+
mtime: -1,
|
|
74
|
+
size: -1,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async readDirectory(dirName) {
|
|
79
|
+
if (!await this.valid(dirName)) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const pkgName = getPackageNameOfDtsPath(dirName);
|
|
83
|
+
if (!pkgName) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
if (!this.flatResults.has(pkgName)) {
|
|
87
|
+
this.flatResults.set(pkgName, this.flat(pkgName));
|
|
88
|
+
}
|
|
89
|
+
const flat = await this.flatResults.get(pkgName);
|
|
90
|
+
const dirPath = dirName.slice(`/node_modules/${pkgName}`.length);
|
|
91
|
+
const files = flat
|
|
92
|
+
.filter(f => f.substring(0, f.lastIndexOf('/')) === dirPath)
|
|
93
|
+
.map(f => f.slice(dirPath.length + 1));
|
|
94
|
+
const dirs = flat
|
|
95
|
+
.filter(f => f.startsWith(dirPath + '/') && f.substring(dirPath.length + 1).split('/').length >= 2)
|
|
96
|
+
.map(f => f.slice(dirPath.length + 1).split('/')[0]);
|
|
97
|
+
return [
|
|
98
|
+
...files.map(f => [f, 1]),
|
|
99
|
+
...[...new Set(dirs)].map(f => [f, 2]),
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
async readFile(fileName) {
|
|
103
|
+
if (!await this.valid(fileName)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!this.fetchResults.has(fileName)) {
|
|
107
|
+
this.fetchResults.set(fileName, this.fetchFile(fileName));
|
|
108
|
+
}
|
|
109
|
+
return await this.fetchResults.get(fileName);
|
|
110
|
+
}
|
|
111
|
+
async fetchFile(fileName) {
|
|
112
|
+
const pkgName = getPackageNameOfDtsPath(fileName);
|
|
113
|
+
if (!pkgName) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
if ((await this.stat(fileName))?.type !== 1) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
return await this.fetchText(fileName);
|
|
120
|
+
}
|
|
121
|
+
async valid(fileName) {
|
|
122
|
+
const pkgName = getPackageNameOfDtsPath(fileName);
|
|
123
|
+
if (!pkgName) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
if (pkgName.indexOf('.') >= 0 || pkgName.endsWith('/node_modules')) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
// hard code for known invalid package
|
|
130
|
+
if (pkgName.startsWith('@typescript/') || pkgName.startsWith('@types/typescript__')) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
// don't check @types if original package already having types
|
|
134
|
+
if (pkgName.startsWith('@types/')) {
|
|
135
|
+
let originalPkgName = pkgName.slice('@types/'.length);
|
|
136
|
+
if (originalPkgName.indexOf('__') >= 0) {
|
|
137
|
+
originalPkgName = '@' + originalPkgName.replace('__', '/');
|
|
138
|
+
}
|
|
139
|
+
const packageJson = await this.readFile(`/node_modules/${originalPkgName}/package.json`);
|
|
140
|
+
if (packageJson) {
|
|
141
|
+
const packageJsonObj = JSON.parse(packageJson);
|
|
142
|
+
if (packageJsonObj.types || packageJsonObj.typings) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
const indexDts = await this.stat(`/node_modules/${originalPkgName}/index.d.ts`);
|
|
146
|
+
if (indexDts?.type === 1) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async function fetchText(url) {
|
|
155
|
+
try {
|
|
156
|
+
const res = await fetch(url);
|
|
157
|
+
if (res.status === 200) {
|
|
158
|
+
return await res.text();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// ignore
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function fetchJson(url) {
|
|
166
|
+
try {
|
|
167
|
+
const res = await fetch(url);
|
|
168
|
+
if (res.status === 200) {
|
|
169
|
+
return await res.json();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// ignore
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function getPackageNameOfDtsPath(path) {
|
|
177
|
+
if (!path.startsWith('/node_modules/')) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
let pkgName = path.split('/')[2];
|
|
181
|
+
if (pkgName.startsWith('@')) {
|
|
182
|
+
if (path.split('/').length < 4) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
pkgName += '/' + path.split('/')[3];
|
|
186
|
+
}
|
|
187
|
+
return pkgName;
|
|
188
|
+
}
|
|
189
|
+
exports.getPackageNameOfDtsPath = getPackageNameOfDtsPath;
|
|
190
|
+
//# sourceMappingURL=dtsHost.js.map
|
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): any;
|
|
3
|
+
export declare function getProgram(ts: typeof import('typescript/lib/tsserverlibrary'), core: embedded.LanguageContext, ls: ts.LanguageService, lsHost: ts.LanguageServiceHost): any;
|
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, lsHost) {
|
|
5
5
|
const proxy = {
|
|
6
6
|
getRootFileNames,
|
|
7
7
|
emit,
|
|
@@ -34,7 +34,7 @@ function getProgram(ts, core, ls) {
|
|
|
34
34
|
return ls.getProgram();
|
|
35
35
|
}
|
|
36
36
|
function getRootFileNames() {
|
|
37
|
-
return getProgram().getRootFileNames().filter(fileName =>
|
|
37
|
+
return getProgram().getRootFileNames().filter(fileName => lsHost.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) {
|
|
|
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, (lsHost.writeFile ?? ts.sys.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
|
|
67
67
|
return {
|
|
68
68
|
emitSkipped: scriptResult.emitSkipped,
|
|
69
69
|
emittedFiles: scriptResult.emittedFiles,
|
|
@@ -79,10 +79,10 @@ function getProgram(ts, core, ls) {
|
|
|
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 (lsHost.fileExists?.(source.fileName) === false)
|
|
83
83
|
continue;
|
|
84
|
-
for (const [
|
|
85
|
-
if (
|
|
84
|
+
for (const [_, [sourceSnapshot, map]] of core.virtualFiles.getMaps(virtualFile)) {
|
|
85
|
+
if (sourceSnapshot !== source.snapshot)
|
|
86
86
|
continue;
|
|
87
87
|
for (const start of map.toSourceOffsets(diagnostic.start)) {
|
|
88
88
|
const reportStart = typeof start[1].data.diagnostic === 'object' ? typeof start[1].data.diagnostic.shouldReport() : !!start[1].data.diagnostic;
|
|
@@ -100,7 +100,7 @@ function getProgram(ts, core, ls) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
if (
|
|
103
|
+
if (lsHost.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) {
|
|
|
116
116
|
: undefined;
|
|
117
117
|
if (!file) {
|
|
118
118
|
if (docText === undefined) {
|
|
119
|
-
const snapshot =
|
|
119
|
+
const snapshot = lsHost.getScriptSnapshot(fileName);
|
|
120
120
|
if (snapshot) {
|
|
121
121
|
docText = snapshot.getText(0, snapshot.getLength());
|
|
122
122
|
}
|
package/out/index.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
context: embedded.LanguageContext;
|
|
7
|
-
};
|
|
8
|
-
} & ts.LanguageService;
|
|
1
|
+
export * from './documentRegistry';
|
|
2
|
+
export * from './dtsHost';
|
|
3
|
+
export * from './languageService';
|
|
4
|
+
export * from './languageServiceHost';
|
|
5
|
+
export * from './sys';
|
package/out/index.js
CHANGED
|
@@ -1,288 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (!ts) {
|
|
9
|
-
throw new Error('TypeScript module not provided.');
|
|
10
|
-
}
|
|
11
|
-
const ls = ts.createLanguageService(core.typescript.languageServiceHost);
|
|
12
|
-
return new Proxy({
|
|
13
|
-
organizeImports,
|
|
14
|
-
// only support for .ts for now, not support for .vue
|
|
15
|
-
getDefinitionAtPosition,
|
|
16
|
-
getDefinitionAndBoundSpan,
|
|
17
|
-
getTypeDefinitionAtPosition,
|
|
18
|
-
getImplementationAtPosition,
|
|
19
|
-
findRenameLocations,
|
|
20
|
-
getReferencesAtPosition,
|
|
21
|
-
findReferences,
|
|
22
|
-
// TODO: now is handled by vue server
|
|
23
|
-
// prepareCallHierarchy: tsLanguageService.rawLs.prepareCallHierarchy,
|
|
24
|
-
// provideCallHierarchyIncomingCalls: tsLanguageService.rawLs.provideCallHierarchyIncomingCalls,
|
|
25
|
-
// provideCallHierarchyOutgoingCalls: tsLanguageService.rawLs.provideCallHierarchyOutgoingCalls,
|
|
26
|
-
// getEditsForFileRename: tsLanguageService.rawLs.getEditsForFileRename,
|
|
27
|
-
// TODO
|
|
28
|
-
// getCodeFixesAtPosition: tsLanguageService.rawLs.getCodeFixesAtPosition,
|
|
29
|
-
// getCombinedCodeFix: tsLanguageService.rawLs.getCombinedCodeFix,
|
|
30
|
-
// applyCodeActionCommand: tsLanguageService.rawLs.applyCodeActionCommand,
|
|
31
|
-
// getApplicableRefactors: tsLanguageService.rawLs.getApplicableRefactors,
|
|
32
|
-
// getEditsForRefactor: tsLanguageService.rawLs.getEditsForRefactor,
|
|
33
|
-
getProgram: () => (0, getProgram_1.getProgram)(ts, core, ls),
|
|
34
|
-
__internal__: {
|
|
35
|
-
context: core,
|
|
36
|
-
languageService: ls,
|
|
37
|
-
},
|
|
38
|
-
}, {
|
|
39
|
-
get: (target, property) => {
|
|
40
|
-
if (property in target) {
|
|
41
|
-
return target[property];
|
|
42
|
-
}
|
|
43
|
-
return ls[property];
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
// apis
|
|
47
|
-
function organizeImports(args, formatOptions, preferences) {
|
|
48
|
-
let edits = [];
|
|
49
|
-
const file = core.virtualFiles.getSource(args.fileName)?.root;
|
|
50
|
-
if (file) {
|
|
51
|
-
embedded.forEachEmbeddedFile(file, embeddedFile => {
|
|
52
|
-
if (embeddedFile.kind === embedded.FileKind.TypeScriptHostFile && embeddedFile.capabilities.codeAction) {
|
|
53
|
-
edits = edits.concat(ls.organizeImports({
|
|
54
|
-
...args,
|
|
55
|
-
fileName: embeddedFile.fileName,
|
|
56
|
-
}, formatOptions, preferences));
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
return ls.organizeImports(args, formatOptions, preferences);
|
|
62
|
-
}
|
|
63
|
-
return edits.map(transformFileTextChanges).filter(notEmpty);
|
|
64
|
-
}
|
|
65
|
-
function getReferencesAtPosition(fileName, position) {
|
|
66
|
-
return findLocations(fileName, position, 'references');
|
|
67
|
-
}
|
|
68
|
-
function getDefinitionAtPosition(fileName, position) {
|
|
69
|
-
return findLocations(fileName, position, 'definition');
|
|
70
|
-
}
|
|
71
|
-
function getTypeDefinitionAtPosition(fileName, position) {
|
|
72
|
-
return findLocations(fileName, position, 'typeDefinition');
|
|
73
|
-
}
|
|
74
|
-
function getImplementationAtPosition(fileName, position) {
|
|
75
|
-
return findLocations(fileName, position, 'implementation');
|
|
76
|
-
}
|
|
77
|
-
function findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) {
|
|
78
|
-
return findLocations(fileName, position, 'rename', findInStrings, findInComments, providePrefixAndSuffixTextForRename);
|
|
79
|
-
}
|
|
80
|
-
function findLocations(fileName, position, mode, findInStrings = false, findInComments = false, providePrefixAndSuffixTextForRename) {
|
|
81
|
-
const loopChecker = new Set();
|
|
82
|
-
let symbols = [];
|
|
83
|
-
withMirrors(fileName, position);
|
|
84
|
-
return symbols.map(s => transformDocumentSpanLike(s)).filter(notEmpty);
|
|
85
|
-
function withMirrors(fileName, position) {
|
|
86
|
-
if (loopChecker.has(fileName + ':' + position))
|
|
87
|
-
return;
|
|
88
|
-
loopChecker.add(fileName + ':' + position);
|
|
89
|
-
const _symbols = mode === 'definition' ? ls.getDefinitionAtPosition(fileName, position)
|
|
90
|
-
: mode === 'typeDefinition' ? ls.getTypeDefinitionAtPosition(fileName, position)
|
|
91
|
-
: mode === 'references' ? ls.getReferencesAtPosition(fileName, position)
|
|
92
|
-
: mode === 'implementation' ? ls.getImplementationAtPosition(fileName, position)
|
|
93
|
-
: mode === 'rename' ? ls.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename)
|
|
94
|
-
: undefined;
|
|
95
|
-
if (!_symbols)
|
|
96
|
-
return;
|
|
97
|
-
symbols = symbols.concat(_symbols);
|
|
98
|
-
for (const ref of _symbols) {
|
|
99
|
-
loopChecker.add(ref.fileName + ':' + ref.textSpan.start);
|
|
100
|
-
const [virtualFile] = core.virtualFiles.getVirtualFile(ref.fileName);
|
|
101
|
-
if (!virtualFile)
|
|
102
|
-
continue;
|
|
103
|
-
const mirrorMap = core.virtualFiles.getMirrorMap(virtualFile);
|
|
104
|
-
if (!mirrorMap)
|
|
105
|
-
continue;
|
|
106
|
-
for (const [mirrorOffset, data] of mirrorMap.findMirrorOffsets(ref.textSpan.start)) {
|
|
107
|
-
if ((mode === 'definition' || mode === 'typeDefinition' || mode === 'implementation') && !data.definition)
|
|
108
|
-
continue;
|
|
109
|
-
if ((mode === 'references') && !data.references)
|
|
110
|
-
continue;
|
|
111
|
-
if ((mode === 'rename') && !data.rename)
|
|
112
|
-
continue;
|
|
113
|
-
if (loopChecker.has(ref.fileName + ':' + mirrorOffset))
|
|
114
|
-
continue;
|
|
115
|
-
withMirrors(ref.fileName, mirrorOffset);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function getDefinitionAndBoundSpan(fileName, position) {
|
|
121
|
-
const loopChecker = new Set();
|
|
122
|
-
let textSpan;
|
|
123
|
-
let symbols = [];
|
|
124
|
-
withMirrors(fileName, position);
|
|
125
|
-
if (!textSpan)
|
|
126
|
-
return;
|
|
127
|
-
return {
|
|
128
|
-
textSpan: textSpan,
|
|
129
|
-
definitions: symbols?.map(s => transformDocumentSpanLike(s)).filter(notEmpty),
|
|
130
|
-
};
|
|
131
|
-
function withMirrors(fileName, position) {
|
|
132
|
-
if (loopChecker.has(fileName + ':' + position))
|
|
133
|
-
return;
|
|
134
|
-
loopChecker.add(fileName + ':' + position);
|
|
135
|
-
const _symbols = ls.getDefinitionAndBoundSpan(fileName, position);
|
|
136
|
-
if (!_symbols)
|
|
137
|
-
return;
|
|
138
|
-
if (!textSpan) {
|
|
139
|
-
textSpan = _symbols.textSpan;
|
|
140
|
-
}
|
|
141
|
-
if (!_symbols.definitions)
|
|
142
|
-
return;
|
|
143
|
-
symbols = symbols.concat(_symbols.definitions);
|
|
144
|
-
for (const ref of _symbols.definitions) {
|
|
145
|
-
loopChecker.add(ref.fileName + ':' + ref.textSpan.start);
|
|
146
|
-
const [virtualFile] = core.virtualFiles.getVirtualFile(ref.fileName);
|
|
147
|
-
if (!virtualFile)
|
|
148
|
-
continue;
|
|
149
|
-
const mirrorMap = core.virtualFiles.getMirrorMap(virtualFile);
|
|
150
|
-
if (!mirrorMap)
|
|
151
|
-
continue;
|
|
152
|
-
for (const [mirrorOffset, data] of mirrorMap.findMirrorOffsets(ref.textSpan.start)) {
|
|
153
|
-
if (!data.definition)
|
|
154
|
-
continue;
|
|
155
|
-
if (loopChecker.has(ref.fileName + ':' + mirrorOffset))
|
|
156
|
-
continue;
|
|
157
|
-
withMirrors(ref.fileName, mirrorOffset);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
function findReferences(fileName, position) {
|
|
163
|
-
const loopChecker = new Set();
|
|
164
|
-
let symbols = [];
|
|
165
|
-
withMirrors(fileName, position);
|
|
166
|
-
return symbols.map(s => transformReferencedSymbol(s)).filter(notEmpty);
|
|
167
|
-
function withMirrors(fileName, position) {
|
|
168
|
-
if (loopChecker.has(fileName + ':' + position))
|
|
169
|
-
return;
|
|
170
|
-
loopChecker.add(fileName + ':' + position);
|
|
171
|
-
const _symbols = ls.findReferences(fileName, position);
|
|
172
|
-
if (!_symbols)
|
|
173
|
-
return;
|
|
174
|
-
symbols = symbols.concat(_symbols);
|
|
175
|
-
for (const symbol of _symbols) {
|
|
176
|
-
for (const ref of symbol.references) {
|
|
177
|
-
loopChecker.add(ref.fileName + ':' + ref.textSpan.start);
|
|
178
|
-
const [virtualFile] = core.virtualFiles.getVirtualFile(ref.fileName);
|
|
179
|
-
if (!virtualFile)
|
|
180
|
-
continue;
|
|
181
|
-
const mirrorMap = core.virtualFiles.getMirrorMap(virtualFile);
|
|
182
|
-
if (!mirrorMap)
|
|
183
|
-
continue;
|
|
184
|
-
for (const [mirrorOffset, data] of mirrorMap.findMirrorOffsets(ref.textSpan.start)) {
|
|
185
|
-
if (!data.references)
|
|
186
|
-
continue;
|
|
187
|
-
if (loopChecker.has(ref.fileName + ':' + mirrorOffset))
|
|
188
|
-
continue;
|
|
189
|
-
withMirrors(ref.fileName, mirrorOffset);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// transforms
|
|
196
|
-
function transformFileTextChanges(changes) {
|
|
197
|
-
const [_, source] = core.virtualFiles.getVirtualFile(changes.fileName);
|
|
198
|
-
if (source) {
|
|
199
|
-
return {
|
|
200
|
-
...changes,
|
|
201
|
-
fileName: source.fileName,
|
|
202
|
-
textChanges: changes.textChanges.map(c => {
|
|
203
|
-
const span = transformSpan(changes.fileName, c.span);
|
|
204
|
-
if (span) {
|
|
205
|
-
return {
|
|
206
|
-
...c,
|
|
207
|
-
span: span.textSpan,
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
}).filter(notEmpty),
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
return changes;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
function transformReferencedSymbol(symbol) {
|
|
218
|
-
const definition = transformDocumentSpanLike(symbol.definition);
|
|
219
|
-
const references = symbol.references.map(r => transformDocumentSpanLike(r)).filter(notEmpty);
|
|
220
|
-
if (definition) {
|
|
221
|
-
return {
|
|
222
|
-
definition,
|
|
223
|
-
references,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
else if (references.length) { // TODO: remove patching
|
|
227
|
-
return {
|
|
228
|
-
definition: {
|
|
229
|
-
...symbol.definition,
|
|
230
|
-
fileName: references[0].fileName,
|
|
231
|
-
textSpan: references[0].textSpan,
|
|
232
|
-
},
|
|
233
|
-
references,
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function transformDocumentSpanLike(documentSpan) {
|
|
238
|
-
const textSpan = transformSpan(documentSpan.fileName, documentSpan.textSpan);
|
|
239
|
-
if (!textSpan)
|
|
240
|
-
return;
|
|
241
|
-
const contextSpan = transformSpan(documentSpan.fileName, documentSpan.contextSpan);
|
|
242
|
-
const originalTextSpan = transformSpan(documentSpan.originalFileName, documentSpan.originalTextSpan);
|
|
243
|
-
const originalContextSpan = transformSpan(documentSpan.originalFileName, documentSpan.originalContextSpan);
|
|
244
|
-
return {
|
|
245
|
-
...documentSpan,
|
|
246
|
-
fileName: textSpan.fileName,
|
|
247
|
-
textSpan: textSpan.textSpan,
|
|
248
|
-
contextSpan: contextSpan?.textSpan,
|
|
249
|
-
originalFileName: originalTextSpan?.fileName,
|
|
250
|
-
originalTextSpan: originalTextSpan?.textSpan,
|
|
251
|
-
originalContextSpan: originalContextSpan?.textSpan,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function transformSpan(fileName, textSpan) {
|
|
255
|
-
if (!fileName)
|
|
256
|
-
return;
|
|
257
|
-
if (!textSpan)
|
|
258
|
-
return;
|
|
259
|
-
const [virtualFile, source] = core.virtualFiles.getVirtualFile(fileName);
|
|
260
|
-
if (virtualFile && source) {
|
|
261
|
-
for (const [sourceFileName, map] of core.virtualFiles.getMaps(virtualFile)) {
|
|
262
|
-
if (source.fileName !== sourceFileName)
|
|
263
|
-
continue;
|
|
264
|
-
const sourceLoc = map.toSourceOffset(textSpan.start);
|
|
265
|
-
if (sourceLoc) {
|
|
266
|
-
return {
|
|
267
|
-
fileName: source.fileName,
|
|
268
|
-
textSpan: {
|
|
269
|
-
start: sourceLoc[0],
|
|
270
|
-
length: textSpan.length,
|
|
271
|
-
},
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
return {
|
|
278
|
-
fileName,
|
|
279
|
-
textSpan,
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
exports.createLanguageService = createLanguageService;
|
|
285
|
-
function notEmpty(value) {
|
|
286
|
-
return value !== null && value !== undefined;
|
|
287
|
-
}
|
|
17
|
+
__exportStar(require("./documentRegistry"), exports);
|
|
18
|
+
__exportStar(require("./dtsHost"), exports);
|
|
19
|
+
__exportStar(require("./languageService"), exports);
|
|
20
|
+
__exportStar(require("./languageServiceHost"), exports);
|
|
21
|
+
__exportStar(require("./sys"), exports);
|
|
288
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LanguageContext } from '@volar/language-core';
|
|
2
|
+
import type * as ts from 'typescript/lib/tsserverlibrary';
|
|
3
|
+
export declare function createLanguageService(core: LanguageContext, ts: typeof import('typescript/lib/tsserverlibrary'), sys: ts.System): {
|
|
4
|
+
__internal__: {
|
|
5
|
+
languageServiceHost: ts.LanguageServiceHost;
|
|
6
|
+
languageService: ts.LanguageService;
|
|
7
|
+
context: LanguageContext;
|
|
8
|
+
};
|
|
9
|
+
} & ts.LanguageService;
|