@vue/language-core 2.2.0 → 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/common.d.ts +12 -0
- package/lib/codegen/common.js +79 -0
- package/lib/codegen/globalTypes.d.ts +3 -1
- package/lib/codegen/globalTypes.js +30 -14
- package/lib/codegen/localTypes.d.ts +1 -1
- package/lib/codegen/localTypes.js +4 -4
- 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 +7 -7
- package/lib/codegen/script/componentSelf.d.ts +1 -1
- package/lib/codegen/script/componentSelf.js +2 -2
- package/lib/codegen/script/context.d.ts +1 -1
- package/lib/codegen/script/index.d.ts +1 -8
- package/lib/codegen/script/index.js +15 -39
- package/lib/codegen/script/scriptSetup.d.ts +1 -1
- package/lib/codegen/script/scriptSetup.js +46 -58
- package/lib/codegen/script/src.js +2 -2
- package/lib/codegen/script/styleModulesType.d.ts +1 -1
- package/lib/codegen/script/styleModulesType.js +2 -2
- package/lib/codegen/script/template.d.ts +1 -1
- package/lib/codegen/script/template.js +11 -32
- package/lib/codegen/template/camelized.d.ts +2 -0
- package/lib/codegen/template/camelized.js +31 -0
- package/lib/codegen/template/context.d.ts +17 -13
- package/lib/codegen/template/context.js +35 -89
- package/lib/codegen/template/element.js +32 -252
- package/lib/codegen/template/elementChildren.d.ts +1 -1
- package/lib/codegen/template/elementChildren.js +3 -4
- package/lib/codegen/template/elementDirectives.js +18 -11
- package/lib/codegen/template/elementProps.d.ts +2 -1
- package/lib/codegen/template/elementProps.js +22 -26
- package/lib/codegen/template/index.d.ts +1 -0
- package/lib/codegen/template/index.js +39 -33
- package/lib/codegen/template/interpolation.js +13 -9
- package/lib/codegen/template/slotOutlet.js +39 -17
- package/lib/codegen/template/styleScopedClasses.d.ts +3 -0
- package/lib/codegen/template/styleScopedClasses.js +141 -0
- package/lib/codegen/template/templateChild.js +9 -2
- package/lib/codegen/template/vSlot.d.ts +5 -0
- package/lib/codegen/template/vSlot.js +80 -0
- package/lib/codegen/utils/index.d.ts +11 -1
- package/lib/codegen/utils/index.js +15 -4
- package/lib/codegen/utils/src.d.ts +2 -0
- package/lib/codegen/utils/src.js +19 -0
- package/lib/parsers/scriptSetupRanges.d.ts +5 -3
- package/lib/parsers/scriptSetupRanges.js +8 -11
- package/lib/parsers/vueCompilerOptions.d.ts +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-inline-ts.js +53 -12
- package/lib/plugins/vue-tsx.d.ts +35 -28
- package/lib/plugins/vue-tsx.js +75 -55
- package/lib/plugins/vue-vine.d.ts +3 -0
- package/lib/plugins/vue-vine.js +35 -0
- package/lib/types.d.ts +6 -2
- package/lib/utils/findDestructuredProps.d.ts +1 -0
- package/lib/utils/findDestructuredProps.js +3 -0
- package/lib/utils/parseCssImports.d.ts +4 -0
- package/lib/utils/parseCssImports.js +19 -0
- package/lib/utils/parseSfc.js +4 -3
- 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 +117 -88
- package/lib/virtualFile/computedEmbeddedCodes.d.ts +1 -1
- package/lib/virtualFile/computedEmbeddedCodes.js +11 -11
- package/lib/virtualFile/computedSfc.d.ts +1 -2
- package/lib/virtualFile/computedSfc.js +79 -82
- 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 +4 -4
package/lib/utils/ts.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
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");
|
|
@@ -11,17 +13,17 @@ 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,67 +112,100 @@ 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 = options.target ?? 3.3;
|
|
173
|
-
const lib = options.lib ?? 'vue';
|
|
208
|
+
function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTemplates = false) {
|
|
174
209
|
return {
|
|
175
210
|
target,
|
|
176
211
|
lib,
|
|
@@ -178,7 +213,10 @@ function getDefaultOptions(options) {
|
|
|
178
213
|
vitePressExtensions: [],
|
|
179
214
|
petiteVueExtensions: [],
|
|
180
215
|
jsxSlots: false,
|
|
181
|
-
|
|
216
|
+
checkUnknownProps: strictTemplates,
|
|
217
|
+
checkUnknownEvents: strictTemplates,
|
|
218
|
+
checkUnknownDirectives: strictTemplates,
|
|
219
|
+
checkUnknownComponents: strictTemplates,
|
|
182
220
|
skipTemplateCodegen: false,
|
|
183
221
|
fallthroughAttributes: false,
|
|
184
222
|
dataAttributes: [],
|
|
@@ -204,25 +242,7 @@ function getDefaultOptions(options) {
|
|
|
204
242
|
plugins: [],
|
|
205
243
|
experimentalDefinePropProposal: false,
|
|
206
244
|
experimentalResolveStyleCssClasses: 'scoped',
|
|
207
|
-
experimentalModelPropName:
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
;
|
|
211
|
-
function resolveVueCompilerOptions(options, defaults = getDefaultOptions(options)) {
|
|
212
|
-
return {
|
|
213
|
-
...defaults,
|
|
214
|
-
...options,
|
|
215
|
-
macros: {
|
|
216
|
-
...defaults.macros,
|
|
217
|
-
...options.macros,
|
|
218
|
-
},
|
|
219
|
-
composables: {
|
|
220
|
-
...defaults.composables,
|
|
221
|
-
...options.composables,
|
|
222
|
-
},
|
|
223
|
-
// https://github.com/vuejs/vue-next/blob/master/packages/compiler-dom/src/transforms/vModel.ts#L49-L51
|
|
224
|
-
// https://vuejs.org/guide/essentials/forms.html#form-input-bindings
|
|
225
|
-
experimentalModelPropName: Object.fromEntries(Object.entries(options.experimentalModelPropName ?? defaults.experimentalModelPropName ?? {
|
|
245
|
+
experimentalModelPropName: {
|
|
226
246
|
'': {
|
|
227
247
|
input: true
|
|
228
248
|
},
|
|
@@ -231,7 +251,16 @@ function resolveVueCompilerOptions(options, defaults = getDefaultOptions(options
|
|
|
231
251
|
textarea: true,
|
|
232
252
|
select: true
|
|
233
253
|
}
|
|
234
|
-
}
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* @deprecated use `getDefaultCompilerOptions` instead
|
|
259
|
+
*/
|
|
260
|
+
function resolveVueCompilerOptions(options) {
|
|
261
|
+
return {
|
|
262
|
+
...getDefaultCompilerOptions(options.target, options.lib),
|
|
263
|
+
...options,
|
|
235
264
|
};
|
|
236
265
|
}
|
|
237
266
|
function setupGlobalTypes(rootDir, vueOptions, host) {
|
|
@@ -247,8 +276,8 @@ function setupGlobalTypes(rootDir, vueOptions, host) {
|
|
|
247
276
|
}
|
|
248
277
|
dir = parentDir;
|
|
249
278
|
}
|
|
250
|
-
const globalTypesPath = path_browserify_1.posix.join(dir, 'node_modules', '.vue-global-types',
|
|
251
|
-
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);
|
|
252
281
|
host.writeFile(globalTypesPath, globalTypesContents);
|
|
253
282
|
return { absolutePath: globalTypesPath };
|
|
254
283
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { VirtualCode } from '@volar/language-core';
|
|
2
2
|
import type { Sfc, VueLanguagePluginReturn } from '../types';
|
|
3
|
-
export declare function computedEmbeddedCodes(plugins: VueLanguagePluginReturn[], fileName: string, sfc: Sfc):
|
|
3
|
+
export declare function computedEmbeddedCodes(plugins: VueLanguagePluginReturn[], fileName: string, sfc: Sfc): () => VirtualCode[];
|
|
4
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,39 +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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
(0, alien_signals_1.setActiveSub)(prevSub, prevTrackId);
|
|
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)();
|
|
14
13
|
return res;
|
|
15
14
|
};
|
|
16
|
-
const
|
|
17
|
-
return
|
|
15
|
+
const getContent = (0, alien_signals_1.computed)(() => {
|
|
16
|
+
return getSnapshot().getText(0, getSnapshot().getLength());
|
|
18
17
|
});
|
|
19
|
-
const
|
|
20
|
-
const newValue =
|
|
18
|
+
const getComments = (0, alien_signals_1.computed)(oldValue => {
|
|
19
|
+
const newValue = getParseResult()?.descriptor.comments ?? [];
|
|
21
20
|
if (oldValue?.length === newValue.length
|
|
22
|
-
&& oldValue
|
|
21
|
+
&& oldValue?.every((v, i) => v === newValue[i])) {
|
|
23
22
|
return oldValue;
|
|
24
23
|
}
|
|
25
24
|
return newValue;
|
|
26
25
|
});
|
|
27
|
-
const
|
|
26
|
+
const getTemplate = computedNullableSfcBlock('template', 'html', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.template ?? undefined), (_block, base) => {
|
|
28
27
|
const compiledAst = computedTemplateAst(base);
|
|
29
28
|
return mergeObject(base, {
|
|
30
|
-
get ast() { return compiledAst
|
|
31
|
-
get errors() { return compiledAst
|
|
32
|
-
get warnings() { return compiledAst
|
|
29
|
+
get ast() { return compiledAst()?.ast; },
|
|
30
|
+
get errors() { return compiledAst()?.errors; },
|
|
31
|
+
get warnings() { return compiledAst()?.warnings; },
|
|
33
32
|
});
|
|
34
33
|
});
|
|
35
|
-
const
|
|
36
|
-
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);
|
|
37
36
|
const srcOffset = (0, alien_signals_1.computed)(() => {
|
|
38
|
-
const _src = src
|
|
39
|
-
return _src ?
|
|
37
|
+
const _src = src();
|
|
38
|
+
return _src ? getUntrackedSnapshot().getText(0, base.startTagEnd).lastIndexOf(_src) - base.startTagEnd : -1;
|
|
40
39
|
});
|
|
41
40
|
const ast = (0, alien_signals_1.computed)(() => {
|
|
42
41
|
for (const plugin of plugins) {
|
|
@@ -48,19 +47,19 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
48
47
|
return ts.createSourceFile(fileName + '.' + base.lang, '', 99);
|
|
49
48
|
});
|
|
50
49
|
return mergeObject(base, {
|
|
51
|
-
get src() { return src
|
|
52
|
-
get srcOffset() { return srcOffset
|
|
53
|
-
get ast() { return ast
|
|
50
|
+
get src() { return src(); },
|
|
51
|
+
get srcOffset() { return srcOffset(); },
|
|
52
|
+
get ast() { return ast(); },
|
|
54
53
|
});
|
|
55
54
|
});
|
|
56
|
-
const
|
|
55
|
+
const getOriginalScriptSetup = computedNullableSfcBlock('scriptSetup', 'js', (0, alien_signals_1.computed)(() => getParseResult()?.descriptor.scriptSetup ?? undefined), (block, base) => {
|
|
57
56
|
const generic = (0, alien_signals_1.computed)(() => {
|
|
58
|
-
const _block = block
|
|
57
|
+
const _block = block();
|
|
59
58
|
return typeof _block.attrs.generic === 'string' ? _block.attrs.generic : undefined;
|
|
60
59
|
});
|
|
61
60
|
const genericOffset = (0, alien_signals_1.computed)(() => {
|
|
62
|
-
const _generic = generic
|
|
63
|
-
return _generic !== undefined ?
|
|
61
|
+
const _generic = generic();
|
|
62
|
+
return _generic !== undefined ? getUntrackedSnapshot().getText(0, base.startTagEnd).lastIndexOf(_generic) - base.startTagEnd : -1;
|
|
64
63
|
});
|
|
65
64
|
const ast = (0, alien_signals_1.computed)(() => {
|
|
66
65
|
for (const plugin of plugins) {
|
|
@@ -72,15 +71,15 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
72
71
|
return ts.createSourceFile(fileName + '.' + base.lang, '', 99);
|
|
73
72
|
});
|
|
74
73
|
return mergeObject(base, {
|
|
75
|
-
get generic() { return generic
|
|
76
|
-
get genericOffset() { return genericOffset
|
|
77
|
-
get ast() { return ast
|
|
74
|
+
get generic() { return generic(); },
|
|
75
|
+
get genericOffset() { return genericOffset(); },
|
|
76
|
+
get ast() { return ast(); },
|
|
78
77
|
});
|
|
79
78
|
});
|
|
80
|
-
const hasScript = (0, alien_signals_1.computed)(() => !!
|
|
81
|
-
const hasScriptSetup = (0, alien_signals_1.computed)(() => !!
|
|
82
|
-
const
|
|
83
|
-
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()) {
|
|
84
83
|
//#region monkey fix: https://github.com/vuejs/language-tools/pull/2113
|
|
85
84
|
return {
|
|
86
85
|
content: '',
|
|
@@ -96,40 +95,40 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
96
95
|
ast: ts.createSourceFile('', '', 99, false, ts.ScriptKind.TS),
|
|
97
96
|
};
|
|
98
97
|
}
|
|
99
|
-
return
|
|
98
|
+
return getOriginalScriptSetup();
|
|
100
99
|
});
|
|
101
|
-
const styles =
|
|
102
|
-
const base = computedSfcBlock('style_' + i, 'css',
|
|
103
|
-
const
|
|
104
|
-
const { __module } =
|
|
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();
|
|
105
104
|
return __module ? {
|
|
106
105
|
name: __module.name,
|
|
107
106
|
offset: __module.offset ? base.start + __module.offset : undefined
|
|
108
107
|
} : undefined;
|
|
109
108
|
});
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
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)]);
|
|
113
112
|
return () => mergeObject(base, {
|
|
114
|
-
get module() { return
|
|
115
|
-
get scoped() { return
|
|
116
|
-
get cssVars() { return
|
|
117
|
-
get classNames() { return
|
|
113
|
+
get module() { return getModule(); },
|
|
114
|
+
get scoped() { return getScoped(); },
|
|
115
|
+
get cssVars() { return getCssVars(); },
|
|
116
|
+
get classNames() { return getClassNames(); },
|
|
118
117
|
});
|
|
119
118
|
});
|
|
120
|
-
const customBlocks =
|
|
121
|
-
const base = computedSfcBlock('custom_block_' + i, 'txt',
|
|
122
|
-
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);
|
|
123
122
|
return () => mergeObject(base, {
|
|
124
|
-
get type() { return
|
|
123
|
+
get type() { return getType(); },
|
|
125
124
|
});
|
|
126
125
|
});
|
|
127
126
|
return {
|
|
128
|
-
get content() { return
|
|
129
|
-
get comments() { return
|
|
130
|
-
get template() { return
|
|
131
|
-
get script() { return
|
|
132
|
-
get scriptSetup() { return
|
|
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(); },
|
|
133
132
|
get styles() { return styles; },
|
|
134
133
|
get customBlocks() { return customBlocks; },
|
|
135
134
|
};
|
|
@@ -145,14 +144,12 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
145
144
|
}
|
|
146
145
|
// incremental update
|
|
147
146
|
if (cache?.plugin.updateSFCTemplate) {
|
|
148
|
-
const change =
|
|
147
|
+
const change = getUntrackedSnapshot().getChangeRange(cache.snapshot);
|
|
149
148
|
if (change) {
|
|
150
|
-
|
|
151
|
-
const prevTrackId = alien_signals_1.activeTrackId;
|
|
152
|
-
(0, alien_signals_1.setActiveSub)(undefined, 0);
|
|
149
|
+
(0, alien_signals_1.pauseTracking)();
|
|
153
150
|
const templateOffset = base.startTagEnd;
|
|
154
|
-
(0, alien_signals_1.
|
|
155
|
-
const newText =
|
|
151
|
+
(0, alien_signals_1.resumeTracking)();
|
|
152
|
+
const newText = getUntrackedSnapshot().getText(change.span.start, change.span.start + change.newLength);
|
|
156
153
|
const newResult = cache.plugin.updateSFCTemplate(cache.result, {
|
|
157
154
|
start: change.span.start - templateOffset,
|
|
158
155
|
end: change.span.start + change.span.length - templateOffset,
|
|
@@ -160,7 +157,7 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
160
157
|
});
|
|
161
158
|
if (newResult) {
|
|
162
159
|
cache.template = base.content;
|
|
163
|
-
cache.snapshot =
|
|
160
|
+
cache.snapshot = getUntrackedSnapshot();
|
|
164
161
|
cache.result = newResult;
|
|
165
162
|
return {
|
|
166
163
|
errors: [],
|
|
@@ -195,7 +192,7 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
195
192
|
if (result && !errors.length && !warnings.length) {
|
|
196
193
|
cache = {
|
|
197
194
|
template: base.content,
|
|
198
|
-
snapshot:
|
|
195
|
+
snapshot: getUntrackedSnapshot(),
|
|
199
196
|
result: result,
|
|
200
197
|
plugin,
|
|
201
198
|
};
|
|
@@ -217,33 +214,33 @@ function computedSfc(ts, plugins, fileName, snapshot, parsed) {
|
|
|
217
214
|
};
|
|
218
215
|
});
|
|
219
216
|
}
|
|
220
|
-
function computedNullableSfcBlock(name, defaultLang,
|
|
221
|
-
const hasBlock = (0, alien_signals_1.computed)(() => !!
|
|
217
|
+
function computedNullableSfcBlock(name, defaultLang, getBlock, resolve) {
|
|
218
|
+
const hasBlock = (0, alien_signals_1.computed)(() => !!getBlock());
|
|
222
219
|
return (0, alien_signals_1.computed)(() => {
|
|
223
|
-
if (!hasBlock
|
|
220
|
+
if (!hasBlock()) {
|
|
224
221
|
return;
|
|
225
222
|
}
|
|
226
|
-
const _block = (0, alien_signals_1.computed)(() =>
|
|
223
|
+
const _block = (0, alien_signals_1.computed)(() => getBlock());
|
|
227
224
|
return resolve(_block, computedSfcBlock(name, defaultLang, _block));
|
|
228
225
|
});
|
|
229
226
|
}
|
|
230
|
-
function computedSfcBlock(name, defaultLang,
|
|
231
|
-
const
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
const
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
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);
|
|
238
235
|
return {
|
|
239
236
|
name,
|
|
240
|
-
get lang() { return
|
|
241
|
-
get attrs() { return
|
|
242
|
-
get content() { return
|
|
243
|
-
get startTagEnd() { return
|
|
244
|
-
get endTagStart() { return
|
|
245
|
-
get start() { return
|
|
246
|
-
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(); },
|
|
247
244
|
};
|
|
248
245
|
}
|
|
249
246
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { SFCParseResult } from '@vue/compiler-sfc';
|
|
2
|
-
import { Signal } from 'alien-signals';
|
|
3
2
|
import type * as ts from 'typescript';
|
|
4
3
|
import type { VueLanguagePluginReturn } from '../types';
|
|
5
|
-
export declare function computedVueSfc(plugins: VueLanguagePluginReturn[], fileName: string, languageId: string,
|
|
4
|
+
export declare function computedVueSfc(plugins: VueLanguagePluginReturn[], fileName: string, languageId: string, getSnapshot: () => ts.IScriptSnapshot): () => SFCParseResult | undefined;
|