@vue/language-core 2.1.10 → 2.2.2
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/index.d.ts +0 -1
- package/index.js +1 -2
- package/lib/codeFeatures.d.ts +1 -0
- package/lib/codeFeatures.js +3 -0
- package/lib/codegen/codeFeatures.d.ts +83 -0
- package/lib/codegen/codeFeatures.js +71 -0
- package/lib/codegen/globalTypes.d.ts +3 -1
- package/lib/codegen/globalTypes.js +39 -14
- package/lib/codegen/localTypes.d.ts +1 -1
- package/lib/codegen/localTypes.js +7 -7
- package/lib/codegen/script/binding.d.ts +4 -0
- package/lib/codegen/script/binding.js +41 -0
- package/lib/codegen/script/component.d.ts +1 -1
- package/lib/codegen/script/component.js +44 -44
- package/lib/codegen/script/componentSelf.d.ts +1 -1
- package/lib/codegen/script/componentSelf.js +14 -14
- package/lib/codegen/script/context.d.ts +1 -1
- package/lib/codegen/script/context.js +2 -2
- package/lib/codegen/script/index.d.ts +6 -11
- package/lib/codegen/script/index.js +21 -63
- package/lib/codegen/script/scriptSetup.d.ts +1 -1
- package/lib/codegen/script/scriptSetup.js +236 -205
- package/lib/codegen/script/src.js +8 -8
- package/lib/codegen/script/styleModulesType.d.ts +1 -1
- package/lib/codegen/script/styleModulesType.js +7 -7
- package/lib/codegen/script/template.d.ts +2 -2
- package/lib/codegen/script/template.js +81 -114
- package/lib/codegen/template/context.d.ts +29 -15
- package/lib/codegen/template/context.js +51 -96
- package/lib/codegen/template/element.d.ts +2 -4
- package/lib/codegen/template/element.js +124 -317
- package/lib/codegen/template/elementChildren.d.ts +1 -1
- package/lib/codegen/template/elementChildren.js +10 -11
- package/lib/codegen/template/elementDirectives.d.ts +1 -0
- package/lib/codegen/template/elementDirectives.js +43 -30
- package/lib/codegen/template/elementEvents.d.ts +2 -2
- package/lib/codegen/template/elementEvents.js +32 -65
- package/lib/codegen/template/elementProps.d.ts +5 -3
- package/lib/codegen/template/elementProps.js +116 -123
- package/lib/codegen/template/index.d.ts +1 -0
- package/lib/codegen/template/index.js +67 -69
- package/lib/codegen/template/interpolation.d.ts +5 -3
- package/lib/codegen/template/interpolation.js +30 -27
- package/lib/codegen/template/objectProperty.js +8 -8
- package/lib/codegen/template/propertyAccess.js +4 -4
- package/lib/codegen/template/slotOutlet.d.ts +1 -1
- package/lib/codegen/template/slotOutlet.js +47 -25
- package/lib/codegen/template/styleScopedClasses.d.ts +4 -1
- package/lib/codegen/template/styleScopedClasses.js +152 -8
- package/lib/codegen/template/templateChild.d.ts +1 -1
- package/lib/codegen/template/templateChild.js +39 -20
- package/lib/codegen/template/vFor.d.ts +1 -1
- package/lib/codegen/template/vFor.js +11 -11
- package/lib/codegen/template/vIf.d.ts +1 -1
- package/lib/codegen/template/vIf.js +6 -6
- package/lib/codegen/template/vSlot.d.ts +5 -0
- package/lib/codegen/template/vSlot.js +80 -0
- package/lib/codegen/utils/camelized.d.ts +2 -0
- package/lib/codegen/utils/camelized.js +31 -0
- package/lib/codegen/utils/index.d.ts +21 -0
- package/lib/codegen/utils/index.js +79 -0
- package/lib/codegen/utils/src.d.ts +2 -0
- package/lib/codegen/utils/src.js +19 -0
- package/lib/codegen/{template → utils}/stringLiteralKey.js +3 -3
- package/lib/codegen/utils/unicode.d.ts +2 -0
- package/lib/codegen/utils/unicode.js +25 -0
- package/lib/languagePlugin.js +1 -1
- package/lib/parsers/scriptRanges.d.ts +7 -2
- package/lib/parsers/scriptSetupRanges.d.ts +69 -83
- package/lib/parsers/scriptSetupRanges.js +194 -171
- package/lib/parsers/vueCompilerOptions.d.ts +2 -0
- package/lib/parsers/vueCompilerOptions.js +23 -0
- package/lib/plugins/file-html.js +4 -3
- package/lib/plugins/file-md.js +1 -1
- package/lib/plugins/file-vue.js +4 -4
- package/lib/plugins/vue-root-tags.js +2 -2
- package/lib/plugins/vue-style-class-names.d.ts +5 -0
- package/lib/plugins/vue-style-class-names.js +32 -0
- package/lib/plugins/vue-style-reference-link.d.ts +1 -0
- package/lib/plugins/vue-style-reference-link.js +3 -0
- package/lib/plugins/vue-style-reference-links.d.ts +3 -0
- package/lib/plugins/vue-style-reference-links.js +26 -0
- package/lib/plugins/vue-template-html.js +6 -2
- package/lib/plugins/vue-template-inline-css.js +1 -1
- package/lib/plugins/vue-template-inline-ts.js +66 -17
- package/lib/plugins/vue-tsx.d.ts +126 -92
- package/lib/plugins/vue-tsx.js +114 -97
- package/lib/plugins/vue-vine.d.ts +3 -0
- package/lib/plugins/vue-vine.js +35 -0
- package/lib/types.d.ts +25 -12
- package/lib/utils/buildMappings.d.ts +1 -1
- package/lib/utils/parseCssImports.d.ts +4 -0
- package/lib/utils/parseCssImports.js +19 -0
- package/lib/utils/parseSfc.d.ts +5 -0
- package/lib/utils/parseSfc.js +11 -5
- package/lib/utils/signals.d.ts +2 -0
- package/lib/utils/signals.js +54 -0
- package/lib/utils/ts.d.ts +14 -2
- package/lib/utils/ts.js +134 -91
- package/lib/virtualFile/computedEmbeddedCodes.d.ts +1 -2
- package/lib/virtualFile/computedEmbeddedCodes.js +11 -11
- package/lib/virtualFile/computedSfc.d.ts +1 -2
- package/lib/virtualFile/computedSfc.js +87 -79
- package/lib/virtualFile/computedVueSfc.d.ts +1 -2
- package/lib/virtualFile/computedVueSfc.js +7 -7
- package/lib/virtualFile/vueFile.d.ts +5 -5
- package/lib/virtualFile/vueFile.js +6 -6
- package/package.json +6 -6
- /package/lib/codegen/{template → utils}/stringLiteralKey.d.ts +0 -0
package/lib/utils/ts.js
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CompilerOptionsResolver = void 0;
|
|
3
4
|
exports.createParsedCommandLineByJson = createParsedCommandLineByJson;
|
|
4
5
|
exports.createParsedCommandLine = createParsedCommandLine;
|
|
6
|
+
exports.getDefaultCompilerOptions = getDefaultCompilerOptions;
|
|
5
7
|
exports.resolveVueCompilerOptions = resolveVueCompilerOptions;
|
|
6
8
|
exports.setupGlobalTypes = setupGlobalTypes;
|
|
7
9
|
const shared_1 = require("@vue/shared");
|
|
8
10
|
const path_browserify_1 = require("path-browserify");
|
|
9
|
-
const languagePlugin_1 = require("../languagePlugin");
|
|
10
11
|
const globalTypes_1 = require("../codegen/globalTypes");
|
|
12
|
+
const languagePlugin_1 = require("../languagePlugin");
|
|
11
13
|
function createParsedCommandLineByJson(ts, parseConfigHost, rootDir, json, configFileName = rootDir + '/jsconfig.json', skipGlobalTypesSetup = false) {
|
|
12
14
|
const proxyHost = proxyParseConfigHostForExtendConfigPaths(parseConfigHost);
|
|
13
15
|
ts.parseJsonConfigFileContent(json, proxyHost.host, rootDir, {}, configFileName);
|
|
14
|
-
|
|
16
|
+
const resolver = new CompilerOptionsResolver();
|
|
15
17
|
for (const extendPath of proxyHost.extendConfigPaths.reverse()) {
|
|
16
18
|
try {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const configFile = ts.readJsonConfigFile(extendPath, proxyHost.host.readFile);
|
|
20
|
+
const obj = ts.convertToObject(configFile, []);
|
|
21
|
+
const rawOptions = obj?.vueCompilerOptions ?? {};
|
|
22
|
+
resolver.addConfig(rawOptions, path_browserify_1.posix.dirname(configFile.fileName));
|
|
21
23
|
}
|
|
22
24
|
catch (err) { }
|
|
23
25
|
}
|
|
24
|
-
const resolvedVueOptions =
|
|
26
|
+
const resolvedVueOptions = resolver.build();
|
|
25
27
|
if (skipGlobalTypesSetup) {
|
|
26
28
|
resolvedVueOptions.__setupedGlobalTypes = true;
|
|
27
29
|
}
|
|
@@ -48,17 +50,17 @@ function createParsedCommandLine(ts, parseConfigHost, tsConfigPath, skipGlobalTy
|
|
|
48
50
|
const proxyHost = proxyParseConfigHostForExtendConfigPaths(parseConfigHost);
|
|
49
51
|
const config = ts.readJsonConfigFile(tsConfigPath, proxyHost.host.readFile);
|
|
50
52
|
ts.parseJsonSourceFileConfigFileContent(config, proxyHost.host, path_browserify_1.posix.dirname(tsConfigPath), {}, tsConfigPath);
|
|
51
|
-
|
|
53
|
+
const resolver = new CompilerOptionsResolver();
|
|
52
54
|
for (const extendPath of proxyHost.extendConfigPaths.reverse()) {
|
|
53
55
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
const configFile = ts.readJsonConfigFile(extendPath, proxyHost.host.readFile);
|
|
57
|
+
const obj = ts.convertToObject(configFile, []);
|
|
58
|
+
const rawOptions = obj?.vueCompilerOptions ?? {};
|
|
59
|
+
resolver.addConfig(rawOptions, path_browserify_1.posix.dirname(configFile.fileName));
|
|
58
60
|
}
|
|
59
61
|
catch (err) { }
|
|
60
62
|
}
|
|
61
|
-
const resolvedVueOptions =
|
|
63
|
+
const resolvedVueOptions = resolver.build();
|
|
62
64
|
if (skipGlobalTypesSetup) {
|
|
63
65
|
resolvedVueOptions.__setupedGlobalTypes = true;
|
|
64
66
|
}
|
|
@@ -85,7 +87,7 @@ function createParsedCommandLine(ts, parseConfigHost, tsConfigPath, skipGlobalTy
|
|
|
85
87
|
return {
|
|
86
88
|
fileNames: [],
|
|
87
89
|
options: {},
|
|
88
|
-
vueOptions:
|
|
90
|
+
vueOptions: getDefaultCompilerOptions(),
|
|
89
91
|
errors: [],
|
|
90
92
|
};
|
|
91
93
|
}
|
|
@@ -110,83 +112,118 @@ function proxyParseConfigHostForExtendConfigPaths(parseConfigHost) {
|
|
|
110
112
|
extendConfigPaths,
|
|
111
113
|
};
|
|
112
114
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
class CompilerOptionsResolver {
|
|
116
|
+
constructor() {
|
|
117
|
+
this.options = {};
|
|
118
|
+
this.plugins = [];
|
|
119
|
+
}
|
|
120
|
+
addConfig(options, rootDir) {
|
|
121
|
+
for (const key in options) {
|
|
122
|
+
switch (key) {
|
|
123
|
+
case 'target':
|
|
124
|
+
const target = options.target;
|
|
125
|
+
if (typeof target === 'string') {
|
|
126
|
+
this.target = findVueVersion(rootDir);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.target = target;
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
case 'plugins':
|
|
133
|
+
this.plugins = (options.plugins ?? [])
|
|
134
|
+
.map((pluginPath) => {
|
|
135
|
+
try {
|
|
136
|
+
const resolvedPath = resolvePath(pluginPath, rootDir);
|
|
137
|
+
if (resolvedPath) {
|
|
138
|
+
const plugin = require(resolvedPath);
|
|
139
|
+
plugin.__moduleName = pluginPath;
|
|
140
|
+
return plugin;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.warn('[Vue] Load plugin failed:', pluginPath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.warn('[Vue] Resolve plugin path failed:', pluginPath, error);
|
|
148
|
+
}
|
|
149
|
+
return [];
|
|
150
|
+
});
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
// @ts-expect-error
|
|
154
|
+
this.options[key] = options[key];
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
127
157
|
}
|
|
128
|
-
|
|
129
|
-
|
|
158
|
+
if (this.target === undefined) {
|
|
159
|
+
this.fallbackTarget = findVueVersion(rootDir);
|
|
130
160
|
}
|
|
131
161
|
}
|
|
132
|
-
|
|
133
|
-
|
|
162
|
+
build(defaults) {
|
|
163
|
+
const target = this.target ?? this.fallbackTarget;
|
|
164
|
+
defaults ??= getDefaultCompilerOptions(target, this.options.lib, this.options.strictTemplates);
|
|
165
|
+
return {
|
|
166
|
+
...defaults,
|
|
167
|
+
...this.options,
|
|
168
|
+
plugins: this.plugins,
|
|
169
|
+
macros: {
|
|
170
|
+
...defaults.macros,
|
|
171
|
+
...this.options.macros,
|
|
172
|
+
},
|
|
173
|
+
composables: {
|
|
174
|
+
...defaults.composables,
|
|
175
|
+
...this.options.composables,
|
|
176
|
+
},
|
|
177
|
+
// https://github.com/vuejs/vue-next/blob/master/packages/compiler-dom/src/transforms/vModel.ts#L49-L51
|
|
178
|
+
// https://vuejs.org/guide/essentials/forms.html#form-input-bindings
|
|
179
|
+
experimentalModelPropName: Object.fromEntries(Object.entries(this.options.experimentalModelPropName ?? defaults.experimentalModelPropName).map(([k, v]) => [(0, shared_1.camelize)(k), v])),
|
|
180
|
+
};
|
|
134
181
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return plugin;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
console.warn('[Vue] Load plugin failed:', pluginPath);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
console.warn('[Vue] Resolve plugin path failed:', pluginPath, error);
|
|
151
|
-
}
|
|
152
|
-
return [];
|
|
153
|
-
});
|
|
154
|
-
result.plugins = plugins;
|
|
182
|
+
}
|
|
183
|
+
exports.CompilerOptionsResolver = CompilerOptionsResolver;
|
|
184
|
+
function findVueVersion(rootDir) {
|
|
185
|
+
const resolvedPath = resolvePath('vue/package.json', rootDir);
|
|
186
|
+
if (resolvedPath) {
|
|
187
|
+
const vuePackageJson = require(resolvedPath);
|
|
188
|
+
const versionNumbers = vuePackageJson.version.split('.');
|
|
189
|
+
return Number(versionNumbers[0] + '.' + versionNumbers[1]);
|
|
155
190
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
191
|
+
else {
|
|
192
|
+
// console.warn('Load vue/package.json failed from', folder);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function resolvePath(scriptPath, root) {
|
|
196
|
+
try {
|
|
197
|
+
if (require?.resolve) {
|
|
198
|
+
return require.resolve(scriptPath, { paths: [root] });
|
|
165
199
|
}
|
|
166
|
-
|
|
167
|
-
// console.warn(
|
|
200
|
+
else {
|
|
201
|
+
// console.warn('failed to resolve path:', scriptPath, 'require.resolve is not supported in web');
|
|
168
202
|
}
|
|
169
203
|
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
// console.warn(error);
|
|
206
|
+
}
|
|
170
207
|
}
|
|
171
|
-
function
|
|
172
|
-
const target = vueOptions.target ?? 3.3;
|
|
173
|
-
const lib = vueOptions.lib ?? 'vue';
|
|
208
|
+
function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTemplates = false) {
|
|
174
209
|
return {
|
|
175
|
-
...vueOptions,
|
|
176
210
|
target,
|
|
177
|
-
extensions: vueOptions.extensions ?? ['.vue'],
|
|
178
|
-
vitePressExtensions: vueOptions.vitePressExtensions ?? [],
|
|
179
|
-
petiteVueExtensions: vueOptions.petiteVueExtensions ?? [],
|
|
180
211
|
lib,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
212
|
+
extensions: ['.vue'],
|
|
213
|
+
vitePressExtensions: [],
|
|
214
|
+
petiteVueExtensions: [],
|
|
215
|
+
jsxSlots: false,
|
|
216
|
+
checkUnknownProps: strictTemplates,
|
|
217
|
+
checkUnknownEvents: strictTemplates,
|
|
218
|
+
checkUnknownDirectives: strictTemplates,
|
|
219
|
+
checkUnknownComponents: strictTemplates,
|
|
220
|
+
skipTemplateCodegen: false,
|
|
221
|
+
fallthroughAttributes: false,
|
|
222
|
+
dataAttributes: [],
|
|
223
|
+
htmlAttributes: ['aria-*'],
|
|
224
|
+
optionsWrapper: target >= 2.7
|
|
188
225
|
? [`(await import('${lib}')).defineComponent(`, `)`]
|
|
189
|
-
: [`(await import('${lib}')).default.extend(`, `)`]
|
|
226
|
+
: [`(await import('${lib}')).default.extend(`, `)`],
|
|
190
227
|
macros: {
|
|
191
228
|
defineProps: ['defineProps'],
|
|
192
229
|
defineSlots: ['defineSlots'],
|
|
@@ -195,20 +232,17 @@ function resolveVueCompilerOptions(vueOptions) {
|
|
|
195
232
|
defineModel: ['defineModel'],
|
|
196
233
|
defineOptions: ['defineOptions'],
|
|
197
234
|
withDefaults: ['withDefaults'],
|
|
198
|
-
...vueOptions.macros,
|
|
199
235
|
},
|
|
200
|
-
|
|
236
|
+
composables: {
|
|
237
|
+
useAttrs: ['useAttrs'],
|
|
201
238
|
useCssModule: ['useCssModule'],
|
|
239
|
+
useSlots: ['useSlots'],
|
|
202
240
|
useTemplateRef: ['useTemplateRef', 'templateRef'],
|
|
203
|
-
...vueOptions.composibles,
|
|
204
241
|
},
|
|
205
|
-
plugins:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// https://github.com/vuejs/vue-next/blob/master/packages/compiler-dom/src/transforms/vModel.ts#L49-L51
|
|
210
|
-
// https://vuejs.org/guide/essentials/forms.html#form-input-bindings
|
|
211
|
-
experimentalModelPropName: Object.fromEntries(Object.entries(vueOptions.experimentalModelPropName ?? {
|
|
242
|
+
plugins: [],
|
|
243
|
+
experimentalDefinePropProposal: false,
|
|
244
|
+
experimentalResolveStyleCssClasses: 'scoped',
|
|
245
|
+
experimentalModelPropName: {
|
|
212
246
|
'': {
|
|
213
247
|
input: true
|
|
214
248
|
},
|
|
@@ -217,7 +251,16 @@ function resolveVueCompilerOptions(vueOptions) {
|
|
|
217
251
|
textarea: true,
|
|
218
252
|
select: true
|
|
219
253
|
}
|
|
220
|
-
}
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* @deprecated use `getDefaultCompilerOptions` instead
|
|
259
|
+
*/
|
|
260
|
+
function resolveVueCompilerOptions(options) {
|
|
261
|
+
return {
|
|
262
|
+
...getDefaultCompilerOptions(options.target, options.lib),
|
|
263
|
+
...options,
|
|
221
264
|
};
|
|
222
265
|
}
|
|
223
266
|
function setupGlobalTypes(rootDir, vueOptions, host) {
|
|
@@ -233,8 +276,8 @@ function setupGlobalTypes(rootDir, vueOptions, host) {
|
|
|
233
276
|
}
|
|
234
277
|
dir = parentDir;
|
|
235
278
|
}
|
|
236
|
-
const globalTypesPath = path_browserify_1.posix.join(dir, 'node_modules', '.vue-global-types',
|
|
237
|
-
const globalTypesContents = `// @ts-nocheck\nexport {};\n` + (0, globalTypes_1.generateGlobalTypes)(vueOptions
|
|
279
|
+
const globalTypesPath = path_browserify_1.posix.join(dir, 'node_modules', '.vue-global-types', (0, globalTypes_1.getGlobalTypesFileName)(vueOptions));
|
|
280
|
+
const globalTypesContents = `// @ts-nocheck\nexport {};\n` + (0, globalTypes_1.generateGlobalTypes)(vueOptions);
|
|
238
281
|
host.writeFile(globalTypesPath, globalTypesContents);
|
|
239
282
|
return { absolutePath: globalTypesPath };
|
|
240
283
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { VirtualCode } from '@volar/language-core';
|
|
2
|
-
import { ISignal } from 'alien-signals';
|
|
3
2
|
import type { Sfc, VueLanguagePluginReturn } from '../types';
|
|
4
|
-
export declare function computedEmbeddedCodes(plugins: VueLanguagePluginReturn[], fileName: string, sfc: Sfc):
|
|
3
|
+
export declare function computedEmbeddedCodes(plugins: VueLanguagePluginReturn[], fileName: string, sfc: Sfc): () => VirtualCode[];
|
|
5
4
|
export declare function resolveCommonLanguageId(lang: string): string;
|
|
@@ -7,7 +7,7 @@ const muggle_string_1 = require("muggle-string");
|
|
|
7
7
|
const buildMappings_1 = require("../utils/buildMappings");
|
|
8
8
|
const embeddedFile_1 = require("./embeddedFile");
|
|
9
9
|
function computedEmbeddedCodes(plugins, fileName, sfc) {
|
|
10
|
-
const
|
|
10
|
+
const getNameToBlockMap = (0, alien_signals_1.computed)(() => {
|
|
11
11
|
const blocks = {};
|
|
12
12
|
if (sfc.template) {
|
|
13
13
|
blocks[sfc.template.name] = sfc.template;
|
|
@@ -26,11 +26,11 @@ function computedEmbeddedCodes(plugins, fileName, sfc) {
|
|
|
26
26
|
}
|
|
27
27
|
return blocks;
|
|
28
28
|
});
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
29
|
+
const getPluginsResult = plugins.map(plugin => computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc, name => getNameToBlockMap()[name]));
|
|
30
|
+
const getFlatResult = (0, alien_signals_1.computed)(() => getPluginsResult.map(r => r()).flat());
|
|
31
|
+
const getStructuredResult = (0, alien_signals_1.computed)(() => {
|
|
32
32
|
const embeddedCodes = [];
|
|
33
|
-
let remain = [...
|
|
33
|
+
let remain = [...getFlatResult()];
|
|
34
34
|
while (remain.length) {
|
|
35
35
|
const beforeLength = remain.length;
|
|
36
36
|
consumeRemain();
|
|
@@ -85,12 +85,12 @@ function computedEmbeddedCodes(plugins, fileName, sfc) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
|
-
return
|
|
88
|
+
return getStructuredResult;
|
|
89
89
|
}
|
|
90
|
-
function computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc,
|
|
90
|
+
function computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc, getBlockByName) {
|
|
91
91
|
const computeds = new Map();
|
|
92
92
|
const getComputedKey = (code) => code.id + '__' + code.lang;
|
|
93
|
-
const
|
|
93
|
+
const getCodes = (0, alien_signals_1.computed)(() => {
|
|
94
94
|
try {
|
|
95
95
|
if (!plugin.getEmbeddedCodes) {
|
|
96
96
|
return [...computeds.values()];
|
|
@@ -148,8 +148,8 @@ function computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc, nameToBlock
|
|
|
148
148
|
return [...computeds.values()];
|
|
149
149
|
});
|
|
150
150
|
return (0, alien_signals_1.computed)(() => {
|
|
151
|
-
return
|
|
152
|
-
const { code, snapshot } = _file
|
|
151
|
+
return getCodes().map(_file => {
|
|
152
|
+
const { code, snapshot } = _file();
|
|
153
153
|
const mappings = (0, buildMappings_1.buildMappings)(code.content.map(segment => {
|
|
154
154
|
if (typeof segment === 'string') {
|
|
155
155
|
return segment;
|
|
@@ -158,7 +158,7 @@ function computedPluginEmbeddedCodes(plugins, plugin, fileName, sfc, nameToBlock
|
|
|
158
158
|
if (source === undefined) {
|
|
159
159
|
return segment;
|
|
160
160
|
}
|
|
161
|
-
const block =
|
|
161
|
+
const block = getBlockByName(source);
|
|
162
162
|
if (!block) {
|
|
163
163
|
// console.warn('Unable to find block: ' + source);
|
|
164
164
|
return segment;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { SFCParseResult } from '@vue/compiler-sfc';
|
|
2
|
-
import { ISignal, Signal } from 'alien-signals';
|
|
3
2
|
import type * as ts from 'typescript';
|
|
4
3
|
import type { Sfc, VueLanguagePluginReturn } from '../types';
|
|
5
|
-
export declare function computedSfc(ts: typeof import('typescript'), plugins: VueLanguagePluginReturn[], fileName: string,
|
|
4
|
+
export declare function computedSfc(ts: typeof import('typescript'), plugins: VueLanguagePluginReturn[], fileName: string, getSnapshot: () => ts.IScriptSnapshot, getParseResult: () => SFCParseResult | undefined): Sfc;
|
|
@@ -4,30 +4,38 @@ exports.computedSfc = computedSfc;
|
|
|
4
4
|
const alien_signals_1 = require("alien-signals");
|
|
5
5
|
const parseCssClassNames_1 = require("../utils/parseCssClassNames");
|
|
6
6
|
const parseCssVars_1 = require("../utils/parseCssVars");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
alien_signals_1.
|
|
11
|
-
const res =
|
|
12
|
-
alien_signals_1.
|
|
7
|
+
const signals_1 = require("../utils/signals");
|
|
8
|
+
function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
9
|
+
const getUntrackedSnapshot = () => {
|
|
10
|
+
(0, alien_signals_1.pauseTracking)();
|
|
11
|
+
const res = getSnapshot();
|
|
12
|
+
(0, alien_signals_1.resumeTracking)();
|
|
13
13
|
return res;
|
|
14
14
|
};
|
|
15
|
-
const
|
|
16
|
-
return
|
|
15
|
+
const getContent = (0, alien_signals_1.computed)(() => {
|
|
16
|
+
return getSnapshot().getText(0, getSnapshot().getLength());
|
|
17
17
|
});
|
|
18
|
-
const
|
|
18
|
+
const getComments = (0, alien_signals_1.computed)(oldValue => {
|
|
19
|
+
const newValue = getParseResult()?.descriptor.comments ?? [];
|
|
20
|
+
if (oldValue?.length === newValue.length
|
|
21
|
+
&& oldValue?.every((v, i) => v === newValue[i])) {
|
|
22
|
+
return oldValue;
|
|
23
|
+
}
|
|
24
|
+
return newValue;
|
|
25
|
+
});
|
|
26
|
+
const getTemplate = computedNullableSfcBlock('template', 'html', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.template ?? undefined), (_block, base) => {
|
|
19
27
|
const compiledAst = computedTemplateAst(base);
|
|
20
28
|
return mergeObject(base, {
|
|
21
|
-
get ast() { return compiledAst
|
|
22
|
-
get errors() { return compiledAst
|
|
23
|
-
get warnings() { return compiledAst
|
|
29
|
+
get ast() { return compiledAst()?.ast; },
|
|
30
|
+
get errors() { return compiledAst()?.errors; },
|
|
31
|
+
get warnings() { return compiledAst()?.warnings; },
|
|
24
32
|
});
|
|
25
33
|
});
|
|
26
|
-
const
|
|
27
|
-
const src = (0, alien_signals_1.computed)(() => block
|
|
34
|
+
const getScript = computedNullableSfcBlock('script', 'js', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.script ?? undefined), (block, base) => {
|
|
35
|
+
const src = (0, alien_signals_1.computed)(() => block().src);
|
|
28
36
|
const srcOffset = (0, alien_signals_1.computed)(() => {
|
|
29
|
-
const _src = src
|
|
30
|
-
return _src ?
|
|
37
|
+
const _src = src();
|
|
38
|
+
return _src ? getUntrackedSnapshot().getText(0, base.startTagEnd).lastIndexOf(_src) - base.startTagEnd : -1;
|
|
31
39
|
});
|
|
32
40
|
const ast = (0, alien_signals_1.computed)(() => {
|
|
33
41
|
for (const plugin of plugins) {
|
|
@@ -39,19 +47,19 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
39
47
|
return ts.createSourceFile(fileName + '.' + base.lang, '', 99);
|
|
40
48
|
});
|
|
41
49
|
return mergeObject(base, {
|
|
42
|
-
get src() { return src
|
|
43
|
-
get srcOffset() { return srcOffset
|
|
44
|
-
get ast() { return ast
|
|
50
|
+
get src() { return src(); },
|
|
51
|
+
get srcOffset() { return srcOffset(); },
|
|
52
|
+
get ast() { return ast(); },
|
|
45
53
|
});
|
|
46
54
|
});
|
|
47
|
-
const
|
|
55
|
+
const getOriginalScriptSetup = computedNullableSfcBlock('scriptSetup', 'js', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.scriptSetup ?? undefined), (block, base) => {
|
|
48
56
|
const generic = (0, alien_signals_1.computed)(() => {
|
|
49
|
-
const _block = block
|
|
57
|
+
const _block = block();
|
|
50
58
|
return typeof _block.attrs.generic === 'string' ? _block.attrs.generic : undefined;
|
|
51
59
|
});
|
|
52
60
|
const genericOffset = (0, alien_signals_1.computed)(() => {
|
|
53
|
-
const _generic = generic
|
|
54
|
-
return _generic !== undefined ?
|
|
61
|
+
const _generic = generic();
|
|
62
|
+
return _generic !== undefined ? getUntrackedSnapshot().getText(0, base.startTagEnd).lastIndexOf(_generic) - base.startTagEnd : -1;
|
|
55
63
|
});
|
|
56
64
|
const ast = (0, alien_signals_1.computed)(() => {
|
|
57
65
|
for (const plugin of plugins) {
|
|
@@ -63,15 +71,15 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
63
71
|
return ts.createSourceFile(fileName + '.' + base.lang, '', 99);
|
|
64
72
|
});
|
|
65
73
|
return mergeObject(base, {
|
|
66
|
-
get generic() { return generic
|
|
67
|
-
get genericOffset() { return genericOffset
|
|
68
|
-
get ast() { return ast
|
|
74
|
+
get generic() { return generic(); },
|
|
75
|
+
get genericOffset() { return genericOffset(); },
|
|
76
|
+
get ast() { return ast(); },
|
|
69
77
|
});
|
|
70
78
|
});
|
|
71
|
-
const hasScript = (0, alien_signals_1.computed)(() => !!
|
|
72
|
-
const hasScriptSetup = (0, alien_signals_1.computed)(() => !!
|
|
73
|
-
const
|
|
74
|
-
if (!hasScript
|
|
79
|
+
const hasScript = (0, alien_signals_1.computed)(() => !!getParseResult()?.descriptor.script);
|
|
80
|
+
const hasScriptSetup = (0, alien_signals_1.computed)(() => !!getParseResult()?.descriptor.scriptSetup);
|
|
81
|
+
const getScriptSetup = (0, alien_signals_1.computed)(() => {
|
|
82
|
+
if (!hasScript() && !hasScriptSetup()) {
|
|
75
83
|
//#region monkey fix: https://github.com/vuejs/language-tools/pull/2113
|
|
76
84
|
return {
|
|
77
85
|
content: '',
|
|
@@ -87,39 +95,40 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
87
95
|
ast: ts.createSourceFile('', '', 99, false, ts.ScriptKind.TS),
|
|
88
96
|
};
|
|
89
97
|
}
|
|
90
|
-
return
|
|
98
|
+
return getOriginalScriptSetup();
|
|
91
99
|
});
|
|
92
|
-
const styles =
|
|
93
|
-
const base = computedSfcBlock('style_' + i, 'css',
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
return
|
|
97
|
-
name:
|
|
98
|
-
offset:
|
|
100
|
+
const styles = (0, signals_1.computedArray)((0, alien_signals_1.computed)(() => getParseResult()?.descriptor.styles ?? []), (getBlock, i) => {
|
|
101
|
+
const base = computedSfcBlock('style_' + i, 'css', getBlock);
|
|
102
|
+
const getModule = (0, alien_signals_1.computed)(() => {
|
|
103
|
+
const { __module } = getBlock();
|
|
104
|
+
return __module ? {
|
|
105
|
+
name: __module.name,
|
|
106
|
+
offset: __module.offset ? base.start + __module.offset : undefined
|
|
99
107
|
} : undefined;
|
|
100
108
|
});
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const
|
|
109
|
+
const getScoped = (0, alien_signals_1.computed)(() => !!getBlock().scoped);
|
|
110
|
+
const getCssVars = (0, alien_signals_1.computed)(() => [...(0, parseCssVars_1.parseCssVars)(base.content)]);
|
|
111
|
+
const getClassNames = (0, alien_signals_1.computed)(() => [...(0, parseCssClassNames_1.parseCssClassNames)(base.content)]);
|
|
104
112
|
return () => mergeObject(base, {
|
|
105
|
-
get module() { return
|
|
106
|
-
get scoped() { return
|
|
107
|
-
get cssVars() { return
|
|
108
|
-
get classNames() { return
|
|
113
|
+
get module() { return getModule(); },
|
|
114
|
+
get scoped() { return getScoped(); },
|
|
115
|
+
get cssVars() { return getCssVars(); },
|
|
116
|
+
get classNames() { return getClassNames(); },
|
|
109
117
|
});
|
|
110
118
|
});
|
|
111
|
-
const customBlocks =
|
|
112
|
-
const base = computedSfcBlock('custom_block_' + i, 'txt',
|
|
113
|
-
const
|
|
119
|
+
const customBlocks = (0, signals_1.computedArray)((0, alien_signals_1.computed)(() => getParseResult()?.descriptor.customBlocks ?? []), (getBlock, i) => {
|
|
120
|
+
const base = computedSfcBlock('custom_block_' + i, 'txt', getBlock);
|
|
121
|
+
const getType = (0, alien_signals_1.computed)(() => getBlock().type);
|
|
114
122
|
return () => mergeObject(base, {
|
|
115
|
-
get type() { return
|
|
123
|
+
get type() { return getType(); },
|
|
116
124
|
});
|
|
117
125
|
});
|
|
118
126
|
return {
|
|
119
|
-
get content() { return
|
|
120
|
-
get
|
|
121
|
-
get
|
|
122
|
-
get
|
|
127
|
+
get content() { return getContent(); },
|
|
128
|
+
get comments() { return getComments(); },
|
|
129
|
+
get template() { return getTemplate(); },
|
|
130
|
+
get script() { return getScript(); },
|
|
131
|
+
get scriptSetup() { return getScriptSetup(); },
|
|
123
132
|
get styles() { return styles; },
|
|
124
133
|
get customBlocks() { return customBlocks; },
|
|
125
134
|
};
|
|
@@ -135,13 +144,12 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
135
144
|
}
|
|
136
145
|
// incremental update
|
|
137
146
|
if (cache?.plugin.updateSFCTemplate) {
|
|
138
|
-
const change =
|
|
147
|
+
const change = getUntrackedSnapshot().getChangeRange(cache.snapshot);
|
|
139
148
|
if (change) {
|
|
140
|
-
|
|
141
|
-
alien_signals_1.System.activeTrackId = 0;
|
|
149
|
+
(0, alien_signals_1.pauseTracking)();
|
|
142
150
|
const templateOffset = base.startTagEnd;
|
|
143
|
-
alien_signals_1.
|
|
144
|
-
const newText =
|
|
151
|
+
(0, alien_signals_1.resumeTracking)();
|
|
152
|
+
const newText = getUntrackedSnapshot().getText(change.span.start, change.span.start + change.newLength);
|
|
145
153
|
const newResult = cache.plugin.updateSFCTemplate(cache.result, {
|
|
146
154
|
start: change.span.start - templateOffset,
|
|
147
155
|
end: change.span.start + change.span.length - templateOffset,
|
|
@@ -149,7 +157,7 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
149
157
|
});
|
|
150
158
|
if (newResult) {
|
|
151
159
|
cache.template = base.content;
|
|
152
|
-
cache.snapshot =
|
|
160
|
+
cache.snapshot = getUntrackedSnapshot();
|
|
153
161
|
cache.result = newResult;
|
|
154
162
|
return {
|
|
155
163
|
errors: [],
|
|
@@ -184,7 +192,7 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
184
192
|
if (result && !errors.length && !warnings.length) {
|
|
185
193
|
cache = {
|
|
186
194
|
template: base.content,
|
|
187
|
-
snapshot:
|
|
195
|
+
snapshot: getUntrackedSnapshot(),
|
|
188
196
|
result: result,
|
|
189
197
|
plugin,
|
|
190
198
|
};
|
|
@@ -206,33 +214,33 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
206
214
|
};
|
|
207
215
|
});
|
|
208
216
|
}
|
|
209
|
-
function computedNullableSfcBlock(name, defaultLang,
|
|
210
|
-
const hasBlock = (0, alien_signals_1.computed)(() => !!
|
|
217
|
+
function computedNullableSfcBlock(name, defaultLang, getBlock, resolve) {
|
|
218
|
+
const hasBlock = (0, alien_signals_1.computed)(() => !!getBlock());
|
|
211
219
|
return (0, alien_signals_1.computed)(() => {
|
|
212
|
-
if (!hasBlock
|
|
220
|
+
if (!hasBlock()) {
|
|
213
221
|
return;
|
|
214
222
|
}
|
|
215
|
-
const _block = (0, alien_signals_1.computed)(() =>
|
|
223
|
+
const _block = (0, alien_signals_1.computed)(() => getBlock());
|
|
216
224
|
return resolve(_block, computedSfcBlock(name, defaultLang, _block));
|
|
217
225
|
});
|
|
218
226
|
}
|
|
219
|
-
function computedSfcBlock(name, defaultLang,
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
-
const
|
|
224
|
-
const
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
+
function computedSfcBlock(name, defaultLang, getBlock) {
|
|
228
|
+
const getLang = (0, alien_signals_1.computed)(() => getBlock().lang ?? defaultLang);
|
|
229
|
+
const getAttrs = (0, alien_signals_1.computed)(() => getBlock().attrs); // TODO: computed it
|
|
230
|
+
const getContent = (0, alien_signals_1.computed)(() => getBlock().content);
|
|
231
|
+
const getStartTagEnd = (0, alien_signals_1.computed)(() => getBlock().loc.start.offset);
|
|
232
|
+
const getEndTagStart = (0, alien_signals_1.computed)(() => getBlock().loc.end.offset);
|
|
233
|
+
const getStart = (0, alien_signals_1.computed)(() => getUntrackedSnapshot().getText(0, getStartTagEnd()).lastIndexOf('<' + getBlock().type));
|
|
234
|
+
const getEnd = (0, alien_signals_1.computed)(() => getEndTagStart() + getUntrackedSnapshot().getText(getEndTagStart(), getUntrackedSnapshot().getLength()).indexOf('>') + 1);
|
|
227
235
|
return {
|
|
228
236
|
name,
|
|
229
|
-
get lang() { return
|
|
230
|
-
get attrs() { return
|
|
231
|
-
get content() { return
|
|
232
|
-
get startTagEnd() { return
|
|
233
|
-
get endTagStart() { return
|
|
234
|
-
get start() { return
|
|
235
|
-
get end() { return
|
|
237
|
+
get lang() { return getLang(); },
|
|
238
|
+
get attrs() { return getAttrs(); },
|
|
239
|
+
get content() { return getContent(); },
|
|
240
|
+
get startTagEnd() { return getStartTagEnd(); },
|
|
241
|
+
get endTagStart() { return getEndTagStart(); },
|
|
242
|
+
get start() { return getStart(); },
|
|
243
|
+
get end() { return getEnd(); },
|
|
236
244
|
};
|
|
237
245
|
}
|
|
238
246
|
}
|