@volar/typescript 2.2.0-alpha.6 → 2.2.0-alpha.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.
@@ -70,8 +70,11 @@ function decorateLanguageServiceHost(ts, language, languageServiceHost) {
70
70
  }
71
71
  function updateVirtualScript(fileName) {
72
72
  const version = languageServiceHost.getScriptVersion(fileName);
73
+ if (version === undefined) {
74
+ return;
75
+ }
73
76
  let script = scripts.get(fileName);
74
- if (script?.[0] !== version) {
77
+ if (!script || script[0] !== version) {
75
78
  script = [version];
76
79
  const sourceScript = language.scripts.get(fileName);
77
80
  if (sourceScript?.generated) {
@@ -4,81 +4,136 @@ exports.proxyCreateProgram = void 0;
4
4
  const language_core_1 = require("@volar/language-core");
5
5
  const resolveModuleName_1 = require("../resolveModuleName");
6
6
  const decorateProgram_1 = require("./decorateProgram");
7
+ const arrayEqual = (a, b) => {
8
+ if (a.length !== b.length) {
9
+ return false;
10
+ }
11
+ for (let i = 0; i < a.length; i++) {
12
+ if (a[i] !== b[i]) {
13
+ return false;
14
+ }
15
+ }
16
+ return true;
17
+ };
18
+ const objectEqual = (a, b) => {
19
+ const keysA = Object.keys(a);
20
+ const keysB = Object.keys(b);
21
+ if (keysA.length !== keysB.length) {
22
+ return false;
23
+ }
24
+ for (const key of keysA) {
25
+ if (a[key] !== b[key]) {
26
+ return false;
27
+ }
28
+ }
29
+ return true;
30
+ };
7
31
  function proxyCreateProgram(ts, original, getLanguagePlugins, getLanguageId) {
32
+ const sourceFileSnapshots = new Map();
33
+ const parsedSourceFiles = new WeakMap();
34
+ let lastOptions;
35
+ let languagePlugins;
36
+ let language;
37
+ let moduleResolutionCache;
8
38
  return new Proxy(original, {
9
39
  apply: (target, thisArg, args) => {
10
40
  const options = args[0];
11
41
  assert(!!options.host, '!!options.host');
12
- const languagePlugins = getLanguagePlugins(ts, options);
42
+ if (!lastOptions
43
+ || !languagePlugins
44
+ || !language
45
+ || !arrayEqual(options.rootNames, lastOptions.rootNames)
46
+ || !objectEqual(options.options, lastOptions.options)) {
47
+ moduleResolutionCache = ts.createModuleResolutionCache(options.host.getCurrentDirectory(), options.host.getCanonicalFileName, options.options);
48
+ lastOptions = options;
49
+ languagePlugins = getLanguagePlugins(ts, options);
50
+ language = (0, language_core_1.createLanguage)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
51
+ if (!sourceFileSnapshots.has(fileName)) {
52
+ const sourceFileText = originalHost.readFile(fileName);
53
+ if (sourceFileText !== undefined) {
54
+ sourceFileSnapshots.set(fileName, [undefined, {
55
+ getChangeRange() {
56
+ return undefined;
57
+ },
58
+ getLength() {
59
+ return sourceFileText.length;
60
+ },
61
+ getText(start, end) {
62
+ return sourceFileText.substring(start, end);
63
+ },
64
+ }]);
65
+ }
66
+ else {
67
+ sourceFileSnapshots.set(fileName, [undefined, undefined]);
68
+ }
69
+ }
70
+ const snapshot = sourceFileSnapshots.get(fileName)?.[1];
71
+ if (snapshot) {
72
+ language.scripts.set(fileName, getLanguageId(fileName), snapshot);
73
+ }
74
+ else {
75
+ language.scripts.delete(fileName);
76
+ }
77
+ });
78
+ }
79
+ const originalHost = options.host;
13
80
  const extensions = languagePlugins
14
81
  .map(plugin => plugin.typescript?.extraFileExtensions.map(({ extension }) => `.${extension}`) ?? [])
15
82
  .flat();
16
- const sourceFileToSnapshotMap = new WeakMap();
17
- const language = (0, language_core_1.createLanguage)(languagePlugins, ts.sys.useCaseSensitiveFileNames, fileName => {
18
- let snapshot;
19
- const sourceFile = originalHost.getSourceFile(fileName, 99);
20
- if (sourceFile) {
21
- snapshot = sourceFileToSnapshotMap.get(sourceFile);
22
- if (!snapshot) {
23
- snapshot = {
24
- getChangeRange() {
25
- return undefined;
26
- },
27
- getLength() {
28
- return sourceFile.text.length;
29
- },
30
- getText(start, end) {
31
- return sourceFile.text.substring(start, end);
32
- },
33
- };
34
- sourceFileToSnapshotMap.set(sourceFile, snapshot);
35
- }
36
- }
37
- if (snapshot) {
38
- language.scripts.set(fileName, getLanguageId(fileName), snapshot);
39
- }
40
- else {
41
- language.scripts.delete(fileName);
42
- }
43
- });
44
- const parsedSourceFiles = new WeakMap();
45
- const originalHost = options.host;
46
83
  options.host = { ...originalHost };
47
84
  options.host.getSourceFile = (fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile) => {
48
85
  const originalSourceFile = originalHost.getSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
49
- if (originalSourceFile && extensions.some(ext => fileName.endsWith(ext))) {
50
- let sourceFile2 = parsedSourceFiles.get(originalSourceFile);
51
- if (!sourceFile2) {
52
- const sourceScript = language.scripts.get(fileName);
53
- assert(!!sourceScript, '!!sourceScript');
54
- let patchedText = originalSourceFile.text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
55
- let scriptKind = ts.ScriptKind.TS;
56
- if (sourceScript.generated?.languagePlugin.typescript) {
57
- const { getServiceScript, getExtraServiceScripts } = sourceScript.generated.languagePlugin.typescript;
58
- const serviceScript = getServiceScript(sourceScript.generated.root);
59
- if (serviceScript) {
60
- scriptKind = serviceScript.scriptKind;
61
- patchedText += serviceScript.code.snapshot.getText(0, serviceScript.code.snapshot.getLength());
62
- }
63
- if (getExtraServiceScripts) {
64
- console.warn('getExtraServiceScripts() is not available in this use case.');
65
- }
86
+ if (!sourceFileSnapshots.has(fileName)
87
+ || sourceFileSnapshots.get(fileName)?.[0] !== originalSourceFile) {
88
+ if (originalSourceFile) {
89
+ sourceFileSnapshots.set(fileName, [originalSourceFile, {
90
+ getChangeRange() {
91
+ return undefined;
92
+ },
93
+ getLength() {
94
+ return originalSourceFile.text.length;
95
+ },
96
+ getText(start, end) {
97
+ return originalSourceFile.text.substring(start, end);
98
+ },
99
+ }]);
100
+ }
101
+ else {
102
+ sourceFileSnapshots.set(fileName, [undefined, undefined]);
103
+ }
104
+ }
105
+ if (!originalSourceFile) {
106
+ return;
107
+ }
108
+ if (!parsedSourceFiles.has(originalSourceFile)) {
109
+ const sourceScript = language.scripts.get(fileName);
110
+ assert(!!sourceScript, '!!sourceScript');
111
+ parsedSourceFiles.set(originalSourceFile, originalSourceFile);
112
+ if (sourceScript.generated?.languagePlugin.typescript) {
113
+ const { getServiceScript, getExtraServiceScripts } = sourceScript.generated.languagePlugin.typescript;
114
+ const serviceScript = getServiceScript(sourceScript.generated.root);
115
+ if (serviceScript) {
116
+ let patchedText = originalSourceFile.text.split('\n').map(line => ' '.repeat(line.length)).join('\n');
117
+ let scriptKind = ts.ScriptKind.TS;
118
+ scriptKind = serviceScript.scriptKind;
119
+ patchedText += serviceScript.code.snapshot.getText(0, serviceScript.code.snapshot.getLength());
120
+ const parsedSourceFile = ts.createSourceFile(fileName, patchedText, languageVersionOrOptions, undefined, scriptKind);
121
+ // @ts-expect-error
122
+ parsedSourceFile.version = originalSourceFile.version;
123
+ parsedSourceFiles.set(originalSourceFile, parsedSourceFile);
124
+ }
125
+ if (getExtraServiceScripts) {
126
+ console.warn('getExtraServiceScripts() is not available in this use case.');
66
127
  }
67
- sourceFile2 = ts.createSourceFile(fileName, patchedText, 99, true, scriptKind);
68
- // @ts-expect-error
69
- sourceFile2.version = originalSourceFile.version;
70
- parsedSourceFiles.set(originalSourceFile, sourceFile2);
71
128
  }
72
- return sourceFile2;
73
129
  }
74
- return originalSourceFile;
130
+ return parsedSourceFiles.get(originalSourceFile);
75
131
  };
76
132
  if (extensions.length) {
77
133
  options.options.allowArbitraryExtensions = true;
78
134
  const resolveModuleName = (0, resolveModuleName_1.createResolveModuleName)(ts, originalHost, language.plugins, fileName => language.scripts.get(fileName));
79
135
  const resolveModuleNameLiterals = originalHost.resolveModuleNameLiterals;
80
136
  const resolveModuleNames = originalHost.resolveModuleNames;
81
- const moduleResolutionCache = ts.createModuleResolutionCache(originalHost.getCurrentDirectory(), originalHost.getCanonicalFileName, options.options);
82
137
  options.host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, compilerOptions, ...rest) => {
83
138
  if (resolveModuleNameLiterals && moduleLiterals.every(name => !extensions.some(ext => name.text.endsWith(ext)))) {
84
139
  return resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, compilerOptions, ...rest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/typescript",
3
- "version": "2.2.0-alpha.6",
3
+ "version": "2.2.0-alpha.8",
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.2.0-alpha.6",
15
+ "@volar/language-core": "2.2.0-alpha.8",
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.2.0-alpha.6"
21
+ "@volar/language-service": "2.2.0-alpha.8"
22
22
  },
23
- "gitHead": "c9eb6bc56a5bf0c7c1fddfc66d35717daf0a630e"
23
+ "gitHead": "a48e2549a5bf216ab655e4ef7e6d8c545d10d558"
24
24
  }