@volar/typescript 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -129,6 +129,9 @@ function decorateLanguageServiceHost(virtualFiles, languageServiceHost, ts) {
129
129
  patchedText += script.code.snapshot.getText(0, script.code.snapshot.getLength());
130
130
  }
131
131
  snapshotSnapshot = ts.ScriptSnapshot.fromString(patchedText);
132
+ if (sourceFile.generated.languagePlugin.typescript?.getExtraScripts) {
133
+ console.warn('getExtraScripts() is not available in this use case.');
134
+ }
132
135
  }
133
136
  }
134
137
  else if (virtualFiles.get(fileName)) {
@@ -64,12 +64,16 @@ function proxyCreateProgram(ts, original, extensions, getLanguagePlugins) {
64
64
  assert(!!sourceFile, '!!sourceFile');
65
65
  let patchedText = originalSourceFile.text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
66
66
  let scriptKind = ts.ScriptKind.TS;
67
- if (sourceFile.generated) {
68
- const script = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
67
+ if (sourceFile.generated?.languagePlugin.typescript) {
68
+ const { getScript, getExtraScripts } = sourceFile.generated.languagePlugin.typescript;
69
+ const script = getScript(sourceFile.generated.code);
69
70
  if (script) {
70
71
  scriptKind = script.scriptKind;
71
72
  patchedText += script.code.snapshot.getText(0, script.code.snapshot.getLength());
72
73
  }
74
+ if (getExtraScripts) {
75
+ console.warn('getExtraScripts() is not available in this use case.');
76
+ }
73
77
  }
74
78
  sourceFile2 = ts.createSourceFile(fileName, patchedText, 99, true, scriptKind);
75
79
  // @ts-expect-error
@@ -92,6 +96,7 @@ function proxyCreateProgram(ts, original, extensions, getLanguagePlugins) {
92
96
  };
93
97
  const program = Reflect.apply(target, thisArg, [options]);
94
98
  (0, decorateProgram_1.decorateProgram)(files, program);
99
+ program.__volar__ = { files };
95
100
  return program;
96
101
  function resolveModuleName(name, containingFile, options, redirectedReference) {
97
102
  const resolved = ts.resolveModuleName(name, containingFile, options, moduleResolutionHost, originalHost.getModuleResolutionCache?.(), redirectedReference);
@@ -1,7 +1,3 @@
1
1
  import type { FileRegistry } from '@volar/language-core';
2
2
  export declare function notEmpty<T>(value: T | null | undefined): value is T;
3
- export declare function getVirtualFileAndMap(files: FileRegistry, fileName: string): readonly [{
4
- code: import("@volar/language-core").VirtualCode<string>;
5
- extension: string;
6
- scriptKind: import("typescript").ScriptKind;
7
- }, import("@volar/language-core").SourceFile, import("@volar/language-core").SourceMap<import("@volar/language-core").CodeInformation>] | readonly [undefined, undefined, undefined];
3
+ export declare function getVirtualFileAndMap(files: FileRegistry, fileName: string): readonly [import("@volar/language-core").ServiceScript, import("@volar/language-core").SourceFile, import("@volar/language-core").SourceMap<import("@volar/language-core").CodeInformation>] | readonly [undefined, undefined, undefined];
@@ -34,7 +34,7 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
34
34
  files.delete(fileId);
35
35
  }
36
36
  });
37
- let languageServiceHost = createLanguageServiceHost();
37
+ let { languageServiceHost, getExtraScript } = createLanguageServiceHost();
38
38
  for (const language of languagePlugins) {
39
39
  if (language.typescript?.resolveLanguageServiceHost) {
40
40
  languageServiceHost = language.typescript.resolveLanguageServiceHost(languageServiceHost);
@@ -93,12 +93,14 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
93
93
  sys,
94
94
  projectHost,
95
95
  languageServiceHost,
96
+ getExtraScript,
96
97
  },
97
98
  };
98
99
  function createLanguageServiceHost() {
99
100
  let lastProjectVersion;
100
101
  let tsProjectVersion = 0;
101
102
  let tsFileRegistry = new language_core_1.FileMap(sys.useCaseSensitiveFileNames);
103
+ let extraScriptRegistry = new language_core_1.FileMap(sys.useCaseSensitiveFileNames);
102
104
  let lastTsVirtualFileSnapshots = new Set();
103
105
  let lastOtherVirtualFileSnapshots = new Set();
104
106
  const languageServiceHost = {
@@ -156,14 +158,18 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
156
158
  return getScriptVersion(fileName) !== '';
157
159
  },
158
160
  getProjectVersion() {
159
- syncProject();
161
+ sync();
160
162
  return tsProjectVersion + ('version' in sys ? `:${sys.version}` : '');
161
163
  },
162
164
  getScriptFileNames() {
163
- syncProject();
165
+ sync();
164
166
  return [...tsFileRegistry.keys()];
165
167
  },
166
168
  getScriptKind(fileName) {
169
+ sync();
170
+ if (extraScriptRegistry.has(fileName)) {
171
+ return extraScriptRegistry.get(fileName).scriptKind;
172
+ }
167
173
  const sourceFile = files.get(fileNameToFileId(fileName));
168
174
  if (sourceFile?.generated) {
169
175
  const tsCode = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
@@ -193,14 +199,22 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
193
199
  getScriptVersion,
194
200
  getScriptSnapshot,
195
201
  };
196
- return languageServiceHost;
197
- function syncProject() {
202
+ return {
203
+ languageServiceHost,
204
+ getExtraScript,
205
+ };
206
+ function getExtraScript(fileName) {
207
+ sync();
208
+ return extraScriptRegistry.get(fileName);
209
+ }
210
+ function sync() {
198
211
  const newProjectVersion = projectHost.getProjectVersion?.();
199
212
  const shouldUpdate = newProjectVersion === undefined || newProjectVersion !== lastProjectVersion;
200
213
  if (!shouldUpdate) {
201
214
  return;
202
215
  }
203
216
  lastProjectVersion = newProjectVersion;
217
+ extraScriptRegistry.clear();
204
218
  const newTsVirtualFileSnapshots = new Set();
205
219
  const newOtherVirtualFileSnapshots = new Set();
206
220
  const tsFileNamesSet = new Set();
@@ -210,10 +224,15 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
210
224
  const script = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
211
225
  if (script) {
212
226
  newTsVirtualFileSnapshots.add(script.code.snapshot);
213
- tsFileNamesSet.add(fileName); // virtual .ts
227
+ tsFileNamesSet.add(fileName);
214
228
  }
215
- for (const file of (0, language_core_2.forEachEmbeddedCode)(sourceFile.generated.code)) {
216
- newOtherVirtualFileSnapshots.add(file.snapshot);
229
+ for (const extraScript of sourceFile.generated.languagePlugin.typescript?.getExtraScripts?.(fileName, sourceFile.generated.code) ?? []) {
230
+ newTsVirtualFileSnapshots.add(extraScript.code.snapshot);
231
+ tsFileNamesSet.add(extraScript.fileName);
232
+ extraScriptRegistry.set(extraScript.fileName, extraScript);
233
+ }
234
+ for (const code of (0, language_core_2.forEachEmbeddedCode)(sourceFile.generated.code)) {
235
+ newOtherVirtualFileSnapshots.add(code.snapshot);
217
236
  }
218
237
  }
219
238
  else {
@@ -235,6 +254,10 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
235
254
  }
236
255
  }
237
256
  function getScriptSnapshot(fileName) {
257
+ sync();
258
+ if (extraScriptRegistry.has(fileName)) {
259
+ return extraScriptRegistry.get(fileName).code.snapshot;
260
+ }
238
261
  const sourceFile = files.get(fileNameToFileId(fileName));
239
262
  if (sourceFile?.generated) {
240
263
  const script = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
@@ -247,10 +270,18 @@ function createLanguage(ts, sys, languagePlugins, configFileName, projectHost, {
247
270
  }
248
271
  }
249
272
  function getScriptVersion(fileName) {
273
+ sync();
250
274
  if (!scriptVersions.has(fileName)) {
251
275
  scriptVersions.set(fileName, { lastVersion: 0, map: new WeakMap() });
252
276
  }
253
277
  const version = scriptVersions.get(fileName);
278
+ if (extraScriptRegistry.has(fileName)) {
279
+ const snapshot = extraScriptRegistry.get(fileName).code.snapshot;
280
+ if (!version.map.has(snapshot)) {
281
+ version.map.set(snapshot, version.lastVersion++);
282
+ }
283
+ return version.map.get(snapshot).toString();
284
+ }
254
285
  const sourceFile = files.get(fileNameToFileId(fileName));
255
286
  if (sourceFile?.generated) {
256
287
  const script = sourceFile.generated.languagePlugin.typescript?.getScript(sourceFile.generated.code);
@@ -18,7 +18,7 @@ function runTsc(tscPath, extensions, _getLanguagePlugins) {
18
18
  tsc = replace(tsc, /allSupportedExtensions = .*(?=;)/, s => s + `.concat([[${extsText}]])`);
19
19
  // proxy createProgram
20
20
  tsc = replace(tsc, /function createProgram\(.+\) {/, s => `var createProgram = require(${JSON.stringify(proxyApiPath)}).proxyCreateProgram(`
21
- + `new Proxy({}, { get(_target, p, _receiver) {return eval(p); } } ), `
21
+ + `new Proxy({}, { get(_target, p, _receiver) { return eval(p); } } ), `
22
22
  + `_createProgram, `
23
23
  + `[${extsText}], `
24
24
  + `require(${JSON.stringify(__filename)}).getLanguagePlugins`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/typescript",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,13 +12,13 @@
12
12
  "directory": "packages/typescript"
13
13
  },
14
14
  "dependencies": {
15
- "@volar/language-core": "2.0.0",
15
+ "@volar/language-core": "2.0.1",
16
16
  "path-browserify": "^1.0.1"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "latest",
20
20
  "@types/path-browserify": "latest",
21
- "@volar/language-service": "2.0.0"
21
+ "@volar/language-service": "2.0.1"
22
22
  },
23
- "gitHead": "95217136d2727bb7304443d91cfde3dbe711369c"
23
+ "gitHead": "b1fbf6eed522624ccccfb17a8999edfbc1d8d9bb"
24
24
  }
@@ -1,3 +0,0 @@
1
- import type * as ts from 'typescript';
2
- import { LanguagePlugin } from '@volar/language-core';
3
- export declare function createAsyncTSServerPlugin(extensions: string[], scriptKind: ts.ScriptKind, loadLanguagePlugins: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => Promise<LanguagePlugin[]>): ts.server.PluginModuleFactory;
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createAsyncTSServerPlugin = void 0;
4
- const decorateLanguageService_1 = require("../node/decorateLanguageService");
5
- const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
6
- const language_core_1 = require("@volar/language-core");
7
- const createTSServerPlugin_1 = require("./createTSServerPlugin");
8
- const externalFiles = new WeakMap();
9
- const decoratedLanguageServices = new WeakSet();
10
- const decoratedLanguageServiceHosts = new WeakSet();
11
- function createAsyncTSServerPlugin(extensions, scriptKind, loadLanguagePlugins) {
12
- return modules => {
13
- const { typescript: ts } = modules;
14
- const pluginModule = {
15
- create(info) {
16
- if (!decoratedLanguageServices.has(info.languageService)
17
- && !decoratedLanguageServiceHosts.has(info.languageServiceHost)) {
18
- decoratedLanguageServices.add(info.languageService);
19
- decoratedLanguageServiceHosts.add(info.languageServiceHost);
20
- const emptySnapshot = ts.ScriptSnapshot.fromString('');
21
- const getScriptSnapshot = info.languageServiceHost.getScriptSnapshot.bind(info.languageServiceHost);
22
- const getScriptVersion = info.languageServiceHost.getScriptVersion.bind(info.languageServiceHost);
23
- const getScriptKind = info.languageServiceHost.getScriptKind?.bind(info.languageServiceHost);
24
- const getProjectVersion = info.languageServiceHost.getProjectVersion?.bind(info.languageServiceHost);
25
- let initialized = false;
26
- info.languageServiceHost.getScriptSnapshot = fileName => {
27
- if (!initialized && extensions.some(ext => fileName.endsWith(ext))) {
28
- return emptySnapshot;
29
- }
30
- return getScriptSnapshot(fileName);
31
- };
32
- info.languageServiceHost.getScriptVersion = fileName => {
33
- if (!initialized && extensions.some(ext => fileName.endsWith(ext))) {
34
- return 'initializing...';
35
- }
36
- return getScriptVersion(fileName);
37
- };
38
- if (getScriptKind) {
39
- info.languageServiceHost.getScriptKind = fileName => {
40
- if (!initialized && extensions.some(ext => fileName.endsWith(ext))) {
41
- return scriptKind; // TODO: bypass upstream bug
42
- }
43
- return getScriptKind(fileName);
44
- };
45
- }
46
- if (getProjectVersion) {
47
- info.languageServiceHost.getProjectVersion = () => {
48
- if (!initialized) {
49
- return getProjectVersion() + ',initializing...';
50
- }
51
- return getProjectVersion();
52
- };
53
- }
54
- loadLanguagePlugins(ts, info).then(languagePlugins => {
55
- const files = (0, language_core_1.createFileRegistry)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
56
- const snapshot = getScriptSnapshot(fileName);
57
- if (snapshot) {
58
- files.set(fileName, (0, language_core_1.resolveCommonLanguageId)(fileName), snapshot);
59
- }
60
- else {
61
- files.delete(fileName);
62
- }
63
- });
64
- (0, decorateLanguageService_1.decorateLanguageService)(files, info.languageService);
65
- (0, decorateLanguageServiceHost_1.decorateLanguageServiceHost)(files, info.languageServiceHost, ts);
66
- info.project.markAsDirty();
67
- initialized = true;
68
- });
69
- }
70
- return info.languageService;
71
- },
72
- getExternalFiles(project, updateLevel = 0) {
73
- if (updateLevel >= (1)
74
- || !externalFiles.has(project)) {
75
- const oldFiles = externalFiles.get(project);
76
- const newFiles = (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, extensions);
77
- externalFiles.set(project, newFiles);
78
- if (oldFiles && !(0, createTSServerPlugin_1.arrayItemsEqual)(oldFiles, newFiles)) {
79
- project.refreshDiagnostics();
80
- }
81
- }
82
- return externalFiles.get(project);
83
- },
84
- };
85
- return pluginModule;
86
- };
87
- }
88
- exports.createAsyncTSServerPlugin = createAsyncTSServerPlugin;
89
- //# sourceMappingURL=createAsyncTSServerPlugin.js.map
@@ -1,4 +0,0 @@
1
- import type * as ts from 'typescript';
2
- import { LanguagePlugin } from '@volar/language-core';
3
- export declare function createTSServerPlugin(init: (ts: typeof import('typescript'), info: ts.server.PluginCreateInfo) => LanguagePlugin[]): ts.server.PluginModuleFactory;
4
- export declare function arrayItemsEqual(a: string[], b: string[]): boolean;
@@ -1,70 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.arrayItemsEqual = exports.createTSServerPlugin = void 0;
4
- const decorateLanguageService_1 = require("../node/decorateLanguageService");
5
- const decorateLanguageServiceHost_1 = require("../node/decorateLanguageServiceHost");
6
- const language_core_1 = require("@volar/language-core");
7
- const externalFiles = new WeakMap();
8
- const projectExternalFileExtensions = new WeakMap();
9
- const decoratedLanguageServices = new WeakSet();
10
- const decoratedLanguageServiceHosts = new WeakSet();
11
- function createTSServerPlugin(init) {
12
- return modules => {
13
- const { typescript: ts } = modules;
14
- const pluginModule = {
15
- create(info) {
16
- if (!decoratedLanguageServices.has(info.languageService)
17
- && !decoratedLanguageServiceHosts.has(info.languageServiceHost)) {
18
- decoratedLanguageServices.add(info.languageService);
19
- decoratedLanguageServiceHosts.add(info.languageServiceHost);
20
- const languagePlugins = init(ts, info);
21
- const extensions = languagePlugins
22
- .map(plugin => plugin.typescript?.extraFileExtensions.map(ext => '.' + ext.extension) ?? [])
23
- .flat();
24
- projectExternalFileExtensions.set(info.project, extensions);
25
- const getScriptSnapshot = info.languageServiceHost.getScriptSnapshot.bind(info.languageServiceHost);
26
- const files = (0, language_core_1.createFileRegistry)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
27
- const snapshot = getScriptSnapshot(fileName);
28
- if (snapshot) {
29
- files.set(fileName, (0, language_core_1.resolveCommonLanguageId)(fileName), snapshot);
30
- }
31
- else {
32
- files.delete(fileName);
33
- }
34
- });
35
- (0, decorateLanguageService_1.decorateLanguageService)(files, info.languageService);
36
- (0, decorateLanguageServiceHost_1.decorateLanguageServiceHost)(files, info.languageServiceHost, ts);
37
- }
38
- return info.languageService;
39
- },
40
- getExternalFiles(project, updateLevel = 0) {
41
- if (updateLevel >= (1)
42
- || !externalFiles.has(project)) {
43
- const oldFiles = externalFiles.get(project);
44
- const newFiles = (0, decorateLanguageServiceHost_1.searchExternalFiles)(ts, project, projectExternalFileExtensions.get(project));
45
- externalFiles.set(project, newFiles);
46
- if (oldFiles && !arrayItemsEqual(oldFiles, newFiles)) {
47
- project.refreshDiagnostics();
48
- }
49
- }
50
- return externalFiles.get(project);
51
- },
52
- };
53
- return pluginModule;
54
- };
55
- }
56
- exports.createTSServerPlugin = createTSServerPlugin;
57
- function arrayItemsEqual(a, b) {
58
- if (a.length !== b.length) {
59
- return false;
60
- }
61
- const set = new Set(a);
62
- for (const file of b) {
63
- if (!set.has(file)) {
64
- return false;
65
- }
66
- }
67
- return true;
68
- }
69
- exports.arrayItemsEqual = arrayItemsEqual;
70
- //# sourceMappingURL=createTSServerPlugin.js.map
@@ -1,3 +0,0 @@
1
- import type * as ts from 'typescript';
2
- import type { FileRegistry } from '@volar/language-core';
3
- export declare function resolveModuleName(ts: typeof import('typescript'), files: FileRegistry, fileNameToFileId: (fileName: string) => string, languageServiceHost: ts.LanguageServiceHost, moduleName: string, containingFile: string, options: ts.CompilerOptions, cache?: ts.ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, resolutionMode?: ts.ResolutionMode): ts.ResolvedModuleWithFailedLookupLocations;
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveModuleName = void 0;
4
- function resolveModuleName(ts, files, fileNameToFileId, languageServiceHost, moduleName, containingFile, options, cache, redirectedReference, resolutionMode) {
5
- let extraFileExtension;
6
- let isPatchResult = false;
7
- for (const language of files.languagePlugins) {
8
- extraFileExtension = language.typescript?.extraFileExtensions.find(ext => moduleName.endsWith('.' + ext.extension))?.extension;
9
- if (extraFileExtension) {
10
- break;
11
- }
12
- }
13
- const result = ts.resolveModuleName(moduleName, containingFile, options, {
14
- ...languageServiceHost,
15
- fileExists(fileName) {
16
- if (extraFileExtension && fileName.endsWith('.d.ts')) {
17
- const patchResult = fileExists(fileName.slice(0, -5));
18
- if (patchResult) {
19
- isPatchResult = true;
20
- return true;
21
- }
22
- }
23
- return fileExists(fileName);
24
- },
25
- }, cache, redirectedReference, resolutionMode);
26
- if (isPatchResult && result.resolvedModule) {
27
- result.resolvedModule.resolvedFileName = result.resolvedModule.resolvedFileName.slice(0, -5);
28
- const sourceFile = files.get(fileNameToFileId(result.resolvedModule.resolvedFileName));
29
- if (sourceFile?.generated) {
30
- const tsCode = sourceFile.generated.languagePlugin.typescript?.getLanguageServiceCode(sourceFile.generated.code);
31
- if (tsCode) {
32
- result.resolvedModule.extension = tsCode.extension;
33
- }
34
- }
35
- }
36
- return result;
37
- // fix https://github.com/vuejs/language-tools/issues/3332
38
- function fileExists(fileName) {
39
- if (languageServiceHost.fileExists(fileName)) {
40
- const fileSize = ts.sys.getFileSize?.(fileName) ?? languageServiceHost.readFile(fileName)?.length ?? 0;
41
- return fileSize < 4 * 1024 * 1024;
42
- }
43
- return false;
44
- }
45
- }
46
- exports.resolveModuleName = resolveModuleName;
47
- //# sourceMappingURL=resolveModuleName.js.map