@vue/language-core 3.1.5 → 3.1.6
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 +2 -1
- package/index.js +3 -2
- package/lib/codegen/codeFeatures.d.ts +5 -9
- package/lib/codegen/codeFeatures.js +5 -5
- package/lib/codegen/globalTypes.js +12 -18
- package/lib/codegen/localTypes.d.ts +1 -1
- package/lib/codegen/localTypes.js +6 -6
- package/lib/codegen/names.d.ts +30 -0
- package/lib/codegen/names.js +34 -0
- package/lib/codegen/script/component.js +45 -54
- package/lib/codegen/script/context.d.ts +2 -5
- package/lib/codegen/script/context.js +1 -7
- package/lib/codegen/script/index.d.ts +10 -12
- package/lib/codegen/script/index.js +74 -73
- package/lib/codegen/script/scriptSetup.d.ts +3 -2
- package/lib/codegen/script/scriptSetup.js +209 -283
- package/lib/codegen/script/src.js +9 -3
- package/lib/codegen/script/template.js +64 -108
- package/lib/codegen/style/common.d.ts +3 -0
- package/lib/codegen/style/common.js +43 -0
- package/lib/codegen/style/index.d.ts +63 -0
- package/lib/codegen/style/index.js +38 -0
- package/lib/codegen/style/modules.d.ts +3 -2
- package/lib/codegen/style/modules.js +12 -11
- package/lib/codegen/style/scopedClasses.d.ts +2 -3
- package/lib/codegen/style/scopedClasses.js +23 -21
- package/lib/codegen/template/context.d.ts +7 -16
- package/lib/codegen/template/context.js +81 -93
- package/lib/codegen/template/element.js +151 -55
- package/lib/codegen/template/elementDirectives.js +32 -12
- package/lib/codegen/template/elementEvents.js +27 -28
- package/lib/codegen/template/elementProps.d.ts +2 -2
- package/lib/codegen/template/elementProps.js +49 -23
- package/lib/codegen/template/index.d.ts +8 -19
- package/lib/codegen/template/index.js +85 -80
- package/lib/codegen/template/interpolation.d.ts +3 -3
- package/lib/codegen/template/interpolation.js +90 -136
- package/lib/codegen/template/objectProperty.js +8 -4
- package/lib/codegen/template/propertyAccess.d.ts +1 -1
- package/lib/codegen/template/propertyAccess.js +5 -7
- package/lib/codegen/template/slotOutlet.js +25 -8
- package/lib/codegen/template/styleScopedClasses.d.ts +3 -6
- package/lib/codegen/template/styleScopedClasses.js +23 -149
- package/lib/codegen/template/templateChild.d.ts +0 -1
- package/lib/codegen/template/templateChild.js +11 -68
- package/lib/codegen/template/vFor.js +10 -13
- package/lib/codegen/template/vIf.js +5 -3
- package/lib/codegen/template/vSlot.js +20 -15
- package/lib/codegen/utils/boundary.d.ts +3 -0
- package/lib/codegen/utils/boundary.js +13 -0
- package/lib/codegen/utils/camelized.js +3 -3
- package/lib/codegen/utils/escaped.js +4 -2
- package/lib/codegen/utils/index.d.ts +3 -4
- package/lib/codegen/utils/index.js +42 -16
- package/lib/codegen/utils/merge.d.ts +2 -2
- package/lib/codegen/utils/merge.js +9 -9
- package/lib/codegen/utils/stringLiteralKey.js +6 -3
- package/lib/codegen/utils/transform.d.ts +8 -0
- package/lib/codegen/utils/transform.js +27 -0
- package/lib/codegen/utils/unicode.js +4 -2
- package/lib/compilerOptions.d.ts +5 -2
- package/lib/compilerOptions.js +67 -44
- package/lib/languagePlugin.d.ts +1 -1
- package/lib/languagePlugin.js +2 -2
- package/lib/plugins/vue-template-inline-css.js +2 -6
- package/lib/plugins/vue-template-inline-ts.js +12 -14
- package/lib/plugins/vue-tsx.d.ts +11 -20
- package/lib/plugins/vue-tsx.js +121 -68
- package/lib/plugins.js +1 -1
- package/lib/types.d.ts +5 -4
- package/lib/utils/parseSfc.js +7 -3
- package/lib/utils/shared.d.ts +1 -1
- package/lib/utils/shared.js +7 -6
- package/lib/utils/signals.d.ts +2 -2
- package/lib/utils/signals.js +8 -6
- package/lib/virtualCode/embeddedCodes.d.ts +12 -0
- package/lib/virtualCode/embeddedCodes.js +249 -0
- package/lib/{virtualFile/vueFile.d.ts → virtualCode/index.d.ts} +9 -9
- package/lib/virtualCode/index.js +81 -0
- package/lib/virtualCode/ir.d.ts +4 -0
- package/lib/{virtualFile/computedSfc.js → virtualCode/ir.js} +59 -94
- package/lib/virtualCode/normalize.d.ts +2 -0
- package/lib/virtualCode/normalize.js +170 -0
- package/package.json +4 -4
- package/lib/codegen/style/classProperty.d.ts +0 -2
- package/lib/codegen/style/classProperty.js +0 -18
- package/lib/codegen/style/imports.d.ts +0 -2
- package/lib/codegen/style/imports.js +0 -27
- package/lib/codegen/template/elementChildren.d.ts +0 -5
- package/lib/codegen/template/elementChildren.js +0 -12
- package/lib/codegen/utils/wrapWith.d.ts +0 -2
- package/lib/codegen/utils/wrapWith.js +0 -15
- package/lib/virtualFile/computedEmbeddedCodes.d.ts +0 -4
- package/lib/virtualFile/computedEmbeddedCodes.js +0 -262
- package/lib/virtualFile/computedSfc.d.ts +0 -6
- package/lib/virtualFile/computedVueSfc.d.ts +0 -4
- package/lib/virtualFile/computedVueSfc.js +0 -41
- package/lib/virtualFile/embeddedFile.d.ts +0 -11
- package/lib/virtualFile/embeddedFile.js +0 -14
- package/lib/virtualFile/vueFile.js +0 -49
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VueEmbeddedCode = void 0;
|
|
4
|
+
exports.useEmbeddedCodes = useEmbeddedCodes;
|
|
5
|
+
const alien_signals_1 = require("alien-signals");
|
|
6
|
+
const muggle_string_1 = require("muggle-string");
|
|
7
|
+
const buildMappings_1 = require("../utils/buildMappings");
|
|
8
|
+
class VueEmbeddedCode {
|
|
9
|
+
constructor(id, lang, content) {
|
|
10
|
+
this.id = id;
|
|
11
|
+
this.lang = lang;
|
|
12
|
+
this.content = content;
|
|
13
|
+
this.linkedCodeMappings = [];
|
|
14
|
+
this.embeddedCodes = [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.VueEmbeddedCode = VueEmbeddedCode;
|
|
18
|
+
function useEmbeddedCodes(plugins, fileName, sfc) {
|
|
19
|
+
const getNameToBlockMap = (0, alien_signals_1.computed)(() => {
|
|
20
|
+
const blocks = {};
|
|
21
|
+
if (sfc.template) {
|
|
22
|
+
blocks[sfc.template.name] = sfc.template;
|
|
23
|
+
}
|
|
24
|
+
if (sfc.script) {
|
|
25
|
+
blocks[sfc.script.name] = sfc.script;
|
|
26
|
+
}
|
|
27
|
+
if (sfc.scriptSetup) {
|
|
28
|
+
blocks[sfc.scriptSetup.name] = sfc.scriptSetup;
|
|
29
|
+
}
|
|
30
|
+
for (const block of sfc.styles) {
|
|
31
|
+
blocks[block.name] = block;
|
|
32
|
+
}
|
|
33
|
+
for (const block of sfc.customBlocks) {
|
|
34
|
+
blocks[block.name] = block;
|
|
35
|
+
}
|
|
36
|
+
return blocks;
|
|
37
|
+
});
|
|
38
|
+
const pluginsResult = plugins.map(useEmbeddedCodesForPlugin);
|
|
39
|
+
return (0, alien_signals_1.computed)(() => {
|
|
40
|
+
const result = [];
|
|
41
|
+
const idToCodeMap = new Map();
|
|
42
|
+
const virtualCodes = pluginsResult
|
|
43
|
+
.map(getPluginResult => getPluginResult())
|
|
44
|
+
.flat()
|
|
45
|
+
.map(({ code, snapshot, mappings }) => {
|
|
46
|
+
const virtualCode = {
|
|
47
|
+
id: code.id,
|
|
48
|
+
languageId: resolveCommonLanguageId(code.lang),
|
|
49
|
+
linkedCodeMappings: code.linkedCodeMappings,
|
|
50
|
+
snapshot,
|
|
51
|
+
mappings,
|
|
52
|
+
embeddedCodes: [],
|
|
53
|
+
};
|
|
54
|
+
idToCodeMap.set(code.id, virtualCode);
|
|
55
|
+
return [code.parentCodeId, virtualCode];
|
|
56
|
+
});
|
|
57
|
+
for (const [parentCodeId, virtualCode] of virtualCodes) {
|
|
58
|
+
if (!parentCodeId) {
|
|
59
|
+
result.push(virtualCode);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const parent = idToCodeMap.get(parentCodeId);
|
|
63
|
+
if (parent) {
|
|
64
|
+
parent.embeddedCodes ??= [];
|
|
65
|
+
parent.embeddedCodes.push(virtualCode);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
result.push(virtualCode);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
});
|
|
73
|
+
function useEmbeddedCodesForPlugin(plugin) {
|
|
74
|
+
const getMap = (0, alien_signals_1.computed)(prevMap => {
|
|
75
|
+
if (!plugin.getEmbeddedCodes) {
|
|
76
|
+
return new Map();
|
|
77
|
+
}
|
|
78
|
+
const newCodeList = plugin.getEmbeddedCodes(fileName, sfc);
|
|
79
|
+
const map = new Map();
|
|
80
|
+
for (const { id, lang } of newCodeList) {
|
|
81
|
+
const key = id + '__' + lang;
|
|
82
|
+
if (prevMap?.has(key)) {
|
|
83
|
+
map.set(key, prevMap.get(key));
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
map.set(key, useEmbeddedCode(id, lang));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return map;
|
|
90
|
+
});
|
|
91
|
+
return (0, alien_signals_1.computed)(() => {
|
|
92
|
+
const result = [];
|
|
93
|
+
for (const generate of getMap().values()) {
|
|
94
|
+
const { code, snapshot } = generate();
|
|
95
|
+
result.push({
|
|
96
|
+
code,
|
|
97
|
+
snapshot,
|
|
98
|
+
mappings: getMappingsForCode(code),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function useEmbeddedCode(id, lang) {
|
|
105
|
+
return (0, alien_signals_1.computed)(() => {
|
|
106
|
+
const content = [];
|
|
107
|
+
const code = new VueEmbeddedCode(id, lang, content);
|
|
108
|
+
for (const plugin of plugins) {
|
|
109
|
+
if (!plugin.resolveEmbeddedCode) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
plugin.resolveEmbeddedCode(fileName, sfc, code);
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
console.error(e);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const newText = (0, muggle_string_1.toString)(code.content);
|
|
120
|
+
const changeRanges = new Map();
|
|
121
|
+
const snapshot = {
|
|
122
|
+
getText: (start, end) => newText.slice(start, end),
|
|
123
|
+
getLength: () => newText.length,
|
|
124
|
+
getChangeRange(oldSnapshot) {
|
|
125
|
+
if (!changeRanges.has(oldSnapshot)) {
|
|
126
|
+
changeRanges.set(oldSnapshot, undefined);
|
|
127
|
+
const oldText = oldSnapshot.getText(0, oldSnapshot.getLength());
|
|
128
|
+
const changeRange = fullDiffTextChangeRange(oldText, newText);
|
|
129
|
+
if (changeRange) {
|
|
130
|
+
changeRanges.set(oldSnapshot, changeRange);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return changeRanges.get(oldSnapshot);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
code,
|
|
138
|
+
snapshot,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function getMappingsForCode(code) {
|
|
143
|
+
const mappings = (0, buildMappings_1.buildMappings)(code.content.map(segment => {
|
|
144
|
+
if (typeof segment === 'string') {
|
|
145
|
+
return segment;
|
|
146
|
+
}
|
|
147
|
+
const source = segment[1];
|
|
148
|
+
if (source === undefined) {
|
|
149
|
+
return segment;
|
|
150
|
+
}
|
|
151
|
+
const block = getNameToBlockMap()[source];
|
|
152
|
+
if (!block) {
|
|
153
|
+
return segment;
|
|
154
|
+
}
|
|
155
|
+
return [
|
|
156
|
+
segment[0],
|
|
157
|
+
undefined,
|
|
158
|
+
segment[2] + block.startTagEnd,
|
|
159
|
+
segment[3],
|
|
160
|
+
];
|
|
161
|
+
}));
|
|
162
|
+
const newMappings = [];
|
|
163
|
+
const tokenMappings = new Map();
|
|
164
|
+
for (let i = 0; i < mappings.length; i++) {
|
|
165
|
+
const mapping = mappings[i];
|
|
166
|
+
if (mapping.data.__combineToken !== undefined) {
|
|
167
|
+
const token = mapping.data.__combineToken;
|
|
168
|
+
if (tokenMappings.has(token)) {
|
|
169
|
+
const offsetMapping = tokenMappings.get(token);
|
|
170
|
+
offsetMapping.sourceOffsets.push(...mapping.sourceOffsets);
|
|
171
|
+
offsetMapping.generatedOffsets.push(...mapping.generatedOffsets);
|
|
172
|
+
offsetMapping.lengths.push(...mapping.lengths);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
tokenMappings.set(token, mapping);
|
|
176
|
+
newMappings.push(mapping);
|
|
177
|
+
}
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (mapping.data.__linkedToken !== undefined) {
|
|
181
|
+
const token = mapping.data.__linkedToken;
|
|
182
|
+
if (tokenMappings.has(token)) {
|
|
183
|
+
const prevMapping = tokenMappings.get(token);
|
|
184
|
+
code.linkedCodeMappings.push({
|
|
185
|
+
sourceOffsets: [prevMapping.generatedOffsets[0]],
|
|
186
|
+
generatedOffsets: [mapping.generatedOffsets[0]],
|
|
187
|
+
lengths: [Number(token.description)],
|
|
188
|
+
data: undefined,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
tokenMappings.set(token, mapping);
|
|
193
|
+
}
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
newMappings.push(mapping);
|
|
197
|
+
}
|
|
198
|
+
return newMappings;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function fullDiffTextChangeRange(oldText, newText) {
|
|
202
|
+
for (let start = 0; start < oldText.length && start < newText.length; start++) {
|
|
203
|
+
if (oldText[start] !== newText[start]) {
|
|
204
|
+
let end = oldText.length;
|
|
205
|
+
for (let i = 0; i < oldText.length - start && i < newText.length - start; i++) {
|
|
206
|
+
if (oldText[oldText.length - i - 1] !== newText[newText.length - i - 1]) {
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
end--;
|
|
210
|
+
}
|
|
211
|
+
let length = end - start;
|
|
212
|
+
let newLength = length + (newText.length - oldText.length);
|
|
213
|
+
if (newLength < 0) {
|
|
214
|
+
length -= newLength;
|
|
215
|
+
newLength = 0;
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
span: { start, length },
|
|
219
|
+
newLength,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function resolveCommonLanguageId(lang) {
|
|
225
|
+
switch (lang) {
|
|
226
|
+
case 'js':
|
|
227
|
+
return 'javascript';
|
|
228
|
+
case 'cjs':
|
|
229
|
+
return 'javascript';
|
|
230
|
+
case 'mjs':
|
|
231
|
+
return 'javascript';
|
|
232
|
+
case 'ts':
|
|
233
|
+
return 'typescript';
|
|
234
|
+
case 'cts':
|
|
235
|
+
return 'typescript';
|
|
236
|
+
case 'mts':
|
|
237
|
+
return 'typescript';
|
|
238
|
+
case 'jsx':
|
|
239
|
+
return 'javascriptreact';
|
|
240
|
+
case 'tsx':
|
|
241
|
+
return 'typescriptreact';
|
|
242
|
+
case 'pug':
|
|
243
|
+
return 'jade';
|
|
244
|
+
case 'md':
|
|
245
|
+
return 'markdown';
|
|
246
|
+
}
|
|
247
|
+
return lang;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=embeddedCodes.js.map
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CodeMapping, VirtualCode } from '@volar/language-core';
|
|
2
|
+
import type { SFCParseResult } from '@vue/compiler-sfc';
|
|
2
3
|
import type * as ts from 'typescript';
|
|
3
|
-
import type { VueCompilerOptions, VueLanguagePluginReturn } from '../types';
|
|
4
|
-
import { computedSfc } from './computedSfc';
|
|
4
|
+
import type { Sfc, VueCompilerOptions, VueLanguagePluginReturn } from '../types';
|
|
5
5
|
export declare class VueVirtualCode implements VirtualCode {
|
|
6
6
|
fileName: string;
|
|
7
7
|
languageId: string;
|
|
8
8
|
initSnapshot: ts.IScriptSnapshot;
|
|
9
9
|
vueCompilerOptions: VueCompilerOptions;
|
|
10
|
-
plugins: VueLanguagePluginReturn[];
|
|
11
|
-
ts: typeof import('typescript');
|
|
12
10
|
readonly id = "main";
|
|
13
|
-
readonly sfc: ReturnType<typeof computedSfc>;
|
|
14
11
|
private _snapshot;
|
|
15
|
-
private
|
|
12
|
+
private _parsedSfcResult;
|
|
13
|
+
private _ir;
|
|
16
14
|
private _embeddedCodes;
|
|
17
15
|
private _mappings;
|
|
18
16
|
get snapshot(): ts.IScriptSnapshot;
|
|
19
|
-
get vueSfc():
|
|
17
|
+
get vueSfc(): SFCParseResult | undefined;
|
|
18
|
+
get sfc(): Sfc;
|
|
20
19
|
get embeddedCodes(): VirtualCode[];
|
|
21
|
-
get mappings():
|
|
20
|
+
get mappings(): CodeMapping[];
|
|
22
21
|
constructor(fileName: string, languageId: string, initSnapshot: ts.IScriptSnapshot, vueCompilerOptions: VueCompilerOptions, plugins: VueLanguagePluginReturn[], ts: typeof import('typescript'));
|
|
23
22
|
update(newSnapshot: ts.IScriptSnapshot): void;
|
|
23
|
+
private parseSfc;
|
|
24
24
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VueVirtualCode = void 0;
|
|
4
|
+
const alien_signals_1 = require("alien-signals");
|
|
5
|
+
const plugins_1 = require("../plugins");
|
|
6
|
+
const embeddedCodes_1 = require("./embeddedCodes");
|
|
7
|
+
const ir_1 = require("./ir");
|
|
8
|
+
class VueVirtualCode {
|
|
9
|
+
get snapshot() {
|
|
10
|
+
return this._snapshot();
|
|
11
|
+
}
|
|
12
|
+
get vueSfc() {
|
|
13
|
+
return this._parsedSfcResult()?.result;
|
|
14
|
+
}
|
|
15
|
+
get sfc() {
|
|
16
|
+
return this._ir;
|
|
17
|
+
}
|
|
18
|
+
get embeddedCodes() {
|
|
19
|
+
return this._embeddedCodes();
|
|
20
|
+
}
|
|
21
|
+
get mappings() {
|
|
22
|
+
return this._mappings();
|
|
23
|
+
}
|
|
24
|
+
constructor(fileName, languageId, initSnapshot, vueCompilerOptions, plugins, ts) {
|
|
25
|
+
this.fileName = fileName;
|
|
26
|
+
this.languageId = languageId;
|
|
27
|
+
this.initSnapshot = initSnapshot;
|
|
28
|
+
this.vueCompilerOptions = vueCompilerOptions;
|
|
29
|
+
this.id = 'main';
|
|
30
|
+
this._snapshot = (0, alien_signals_1.signal)(initSnapshot);
|
|
31
|
+
this._parsedSfcResult = (0, alien_signals_1.computed)(lastResult => this.parseSfc(plugins, lastResult));
|
|
32
|
+
this._ir = (0, ir_1.useIR)(ts, plugins, fileName, this._snapshot, () => this._parsedSfcResult()?.result);
|
|
33
|
+
this._embeddedCodes = (0, embeddedCodes_1.useEmbeddedCodes)(plugins, fileName, this._ir);
|
|
34
|
+
this._mappings = (0, alien_signals_1.computed)(() => {
|
|
35
|
+
return [{
|
|
36
|
+
sourceOffsets: [0],
|
|
37
|
+
generatedOffsets: [0],
|
|
38
|
+
lengths: [this._snapshot().getLength()],
|
|
39
|
+
data: plugins_1.allCodeFeatures,
|
|
40
|
+
}];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
update(newSnapshot) {
|
|
44
|
+
this._snapshot(newSnapshot);
|
|
45
|
+
}
|
|
46
|
+
parseSfc(plugins, lastResult) {
|
|
47
|
+
const snapshot = this.snapshot;
|
|
48
|
+
if (lastResult?.plugin.updateSFC && !lastResult.result.errors.length) {
|
|
49
|
+
const change = snapshot.getChangeRange(lastResult.snapshot);
|
|
50
|
+
if (change) {
|
|
51
|
+
const newSfc = lastResult.plugin.updateSFC(lastResult.result, {
|
|
52
|
+
start: change.span.start,
|
|
53
|
+
end: change.span.start + change.span.length,
|
|
54
|
+
newText: snapshot.getText(change.span.start, change.span.start + change.newLength),
|
|
55
|
+
});
|
|
56
|
+
if (newSfc) {
|
|
57
|
+
// force dirty
|
|
58
|
+
newSfc.descriptor = JSON.parse(JSON.stringify(newSfc.descriptor));
|
|
59
|
+
return {
|
|
60
|
+
snapshot,
|
|
61
|
+
plugin: lastResult.plugin,
|
|
62
|
+
result: newSfc,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const plugin of plugins) {
|
|
68
|
+
const sfc = plugin.parseSFC2?.(this.fileName, this.languageId, snapshot.getText(0, snapshot.getLength()))
|
|
69
|
+
?? plugin.parseSFC?.(this.fileName, snapshot.getText(0, snapshot.getLength()));
|
|
70
|
+
if (sfc) {
|
|
71
|
+
return {
|
|
72
|
+
snapshot,
|
|
73
|
+
plugin,
|
|
74
|
+
result: sfc,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.VueVirtualCode = VueVirtualCode;
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SFCParseResult } from '@vue/compiler-sfc';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
import type { Sfc, VueLanguagePluginReturn } from '../types';
|
|
4
|
+
export declare function useIR(ts: typeof import('typescript'), plugins: VueLanguagePluginReturn[], fileName: string, getSnapshot: () => ts.IScriptSnapshot, getParseSfcResult: () => SFCParseResult | undefined): Sfc;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.computedSfc = computedSfc;
|
|
3
|
+
exports.useIR = useIR;
|
|
5
4
|
const CompilerDOM = require("@vue/compiler-dom");
|
|
6
5
|
const alien_signals_1 = require("alien-signals");
|
|
7
6
|
const signals_1 = require("../utils/signals");
|
|
8
|
-
|
|
9
|
-
function
|
|
7
|
+
const normalize_1 = require("./normalize");
|
|
8
|
+
function useIR(ts, plugins, fileName, getSnapshot, getParseSfcResult) {
|
|
10
9
|
const getUntrackedSnapshot = () => {
|
|
11
10
|
const pausedSub = (0, alien_signals_1.setActiveSub)(undefined);
|
|
12
11
|
const res = getSnapshot();
|
|
@@ -16,30 +15,25 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
16
15
|
const getContent = (0, alien_signals_1.computed)(() => {
|
|
17
16
|
return getSnapshot().getText(0, getSnapshot().getLength());
|
|
18
17
|
});
|
|
19
|
-
const getComments = (0,
|
|
20
|
-
|
|
21
|
-
if (oldValue?.length === newValue.length
|
|
22
|
-
&& oldValue.every((v, i) => v === newValue[i])) {
|
|
23
|
-
return oldValue;
|
|
24
|
-
}
|
|
25
|
-
return newValue;
|
|
18
|
+
const getComments = (0, signals_1.computedArray)(() => {
|
|
19
|
+
return getParseSfcResult()?.descriptor.comments ?? [];
|
|
26
20
|
});
|
|
27
|
-
const getTemplate =
|
|
28
|
-
const
|
|
21
|
+
const getTemplate = useNullableSfcBlock('template', 'html', (0, alien_signals_1.computed)(() => getParseSfcResult()?.descriptor.template ?? undefined), (_block, base) => {
|
|
22
|
+
const getParseTemplateResult = useParseTemplateResult(base);
|
|
29
23
|
return mergeObject(base, {
|
|
30
24
|
get ast() {
|
|
31
|
-
return
|
|
25
|
+
return getParseTemplateResult().result?.ast;
|
|
32
26
|
},
|
|
33
27
|
get errors() {
|
|
34
|
-
return
|
|
28
|
+
return getParseTemplateResult().errors;
|
|
35
29
|
},
|
|
36
30
|
get warnings() {
|
|
37
|
-
return
|
|
31
|
+
return getParseTemplateResult().warnings;
|
|
38
32
|
},
|
|
39
33
|
});
|
|
40
34
|
});
|
|
41
|
-
const getScript =
|
|
42
|
-
const getSrc =
|
|
35
|
+
const getScript = useNullableSfcBlock('script', 'js', (0, alien_signals_1.computed)(() => getParseSfcResult()?.descriptor.script ?? undefined), (block, base) => {
|
|
36
|
+
const getSrc = useAttrValue('__src', base, block);
|
|
43
37
|
const getAst = (0, alien_signals_1.computed)(() => {
|
|
44
38
|
for (const plugin of plugins) {
|
|
45
39
|
const ast = plugin.compileSFCScript?.(base.lang, base.content);
|
|
@@ -58,8 +52,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
58
52
|
},
|
|
59
53
|
});
|
|
60
54
|
});
|
|
61
|
-
const getOriginalScriptSetup =
|
|
62
|
-
const getGeneric =
|
|
55
|
+
const getOriginalScriptSetup = useNullableSfcBlock('scriptSetup', 'js', (0, alien_signals_1.computed)(() => getParseSfcResult()?.descriptor.scriptSetup ?? undefined), (block, base) => {
|
|
56
|
+
const getGeneric = useAttrValue('__generic', base, block);
|
|
63
57
|
const getAst = (0, alien_signals_1.computed)(() => {
|
|
64
58
|
for (const plugin of plugins) {
|
|
65
59
|
const ast = plugin.compileSFCScript?.(base.lang, base.content);
|
|
@@ -78,8 +72,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
78
72
|
},
|
|
79
73
|
});
|
|
80
74
|
});
|
|
81
|
-
const hasScript = (0, alien_signals_1.computed)(() => !!
|
|
82
|
-
const hasScriptSetup = (0, alien_signals_1.computed)(() => !!
|
|
75
|
+
const hasScript = (0, alien_signals_1.computed)(() => !!getParseSfcResult()?.descriptor.script);
|
|
76
|
+
const hasScriptSetup = (0, alien_signals_1.computed)(() => !!getParseSfcResult()?.descriptor.scriptSetup);
|
|
83
77
|
const getScriptSetup = (0, alien_signals_1.computed)(() => {
|
|
84
78
|
if (!hasScript() && !hasScriptSetup()) {
|
|
85
79
|
// #region monkey fix: https://github.com/vuejs/language-tools/pull/2113
|
|
@@ -99,10 +93,10 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
99
93
|
}
|
|
100
94
|
return getOriginalScriptSetup();
|
|
101
95
|
});
|
|
102
|
-
const styles = (0, signals_1.
|
|
103
|
-
const base =
|
|
104
|
-
const getSrc =
|
|
105
|
-
const getModule =
|
|
96
|
+
const styles = (0, signals_1.reactiveArray)(() => getParseSfcResult()?.descriptor.styles ?? [], (getBlock, i) => {
|
|
97
|
+
const base = useSfcBlock('style_' + i, 'css', getBlock);
|
|
98
|
+
const getSrc = useAttrValue('__src', base, getBlock);
|
|
99
|
+
const getModule = useAttrValue('__module', base, getBlock);
|
|
106
100
|
const getScoped = (0, alien_signals_1.computed)(() => !!getBlock().scoped);
|
|
107
101
|
const getIr = (0, alien_signals_1.computed)(() => {
|
|
108
102
|
for (const plugin of plugins) {
|
|
@@ -112,9 +106,9 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
112
106
|
}
|
|
113
107
|
}
|
|
114
108
|
});
|
|
115
|
-
const getImports = (0, signals_1.
|
|
116
|
-
const getBindings = (0, signals_1.
|
|
117
|
-
const getClassNames = (0, signals_1.
|
|
109
|
+
const getImports = (0, signals_1.computedArray)(() => getIr()?.imports ?? [], (oldItem, newItem) => oldItem.text === newItem.text && oldItem.offset === newItem.offset);
|
|
110
|
+
const getBindings = (0, signals_1.computedArray)(() => getIr()?.bindings ?? [], (oldItem, newItem) => oldItem.text === newItem.text && oldItem.offset === newItem.offset);
|
|
111
|
+
const getClassNames = (0, signals_1.computedArray)(() => getIr()?.classNames ?? [], (oldItem, newItem) => oldItem.text === newItem.text && oldItem.offset === newItem.offset);
|
|
118
112
|
return () => mergeObject(base, {
|
|
119
113
|
get src() {
|
|
120
114
|
return getSrc();
|
|
@@ -136,8 +130,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
136
130
|
},
|
|
137
131
|
});
|
|
138
132
|
});
|
|
139
|
-
const customBlocks = (0, signals_1.
|
|
140
|
-
const base =
|
|
133
|
+
const customBlocks = (0, signals_1.reactiveArray)(() => getParseSfcResult()?.descriptor.customBlocks ?? [], (getBlock, i) => {
|
|
134
|
+
const base = useSfcBlock('custom_block_' + i, 'txt', getBlock);
|
|
141
135
|
const getType = (0, alien_signals_1.computed)(() => getBlock().type);
|
|
142
136
|
return () => mergeObject(base, {
|
|
143
137
|
get type() {
|
|
@@ -168,58 +162,34 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
168
162
|
return customBlocks;
|
|
169
163
|
},
|
|
170
164
|
};
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
let newTsAsts = exports.templateInlineTsAsts.get(newAst);
|
|
176
|
-
if (!newTsAsts) {
|
|
177
|
-
exports.templateInlineTsAsts.set(newAst, newTsAsts = new Map());
|
|
178
|
-
}
|
|
179
|
-
const oldTsAsts = oldAst && exports.templateInlineTsAsts.get(oldAst) || inlineTsAsts;
|
|
180
|
-
if (oldTsAsts) {
|
|
181
|
-
for (const [text, ast] of oldTsAsts) {
|
|
182
|
-
if (!ast.__volar_used) {
|
|
183
|
-
oldTsAsts.delete(text);
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
newTsAsts.set(text, ast);
|
|
187
|
-
ast.__volar_used = false;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
inlineTsAsts = new Map(newTsAsts);
|
|
192
|
-
}
|
|
193
|
-
return (0, alien_signals_1.computed)(() => {
|
|
194
|
-
if (cache?.template === base.content) {
|
|
195
|
-
return {
|
|
196
|
-
errors: [],
|
|
197
|
-
warnings: [],
|
|
198
|
-
ast: cache.result.ast,
|
|
199
|
-
};
|
|
165
|
+
function useParseTemplateResult(base) {
|
|
166
|
+
return (0, alien_signals_1.computed)(lastResult => {
|
|
167
|
+
if (lastResult?.template === base.content) {
|
|
168
|
+
return lastResult;
|
|
200
169
|
}
|
|
201
170
|
// incremental update
|
|
202
|
-
if (
|
|
203
|
-
|
|
171
|
+
if (lastResult?.result && lastResult.plugin?.updateSFCTemplate
|
|
172
|
+
&& !lastResult.errors.length
|
|
173
|
+
&& !lastResult.warnings.length) {
|
|
174
|
+
const change = getUntrackedSnapshot().getChangeRange(lastResult.snapshot);
|
|
204
175
|
if (change) {
|
|
205
176
|
const pausedSub = (0, alien_signals_1.setActiveSub)(undefined);
|
|
206
177
|
const templateOffset = base.startTagEnd;
|
|
207
178
|
(0, alien_signals_1.setActiveSub)(pausedSub);
|
|
208
179
|
const newText = getUntrackedSnapshot().getText(change.span.start, change.span.start + change.newLength);
|
|
209
|
-
const newResult =
|
|
180
|
+
const newResult = lastResult.plugin.updateSFCTemplate(lastResult.result, {
|
|
210
181
|
start: change.span.start - templateOffset,
|
|
211
|
-
end: change.span.start + change.span.length
|
|
182
|
+
end: change.span.start - templateOffset + change.span.length,
|
|
212
183
|
newText,
|
|
213
184
|
});
|
|
214
185
|
if (newResult) {
|
|
215
|
-
updateInlineTsAsts(newResult.ast, cache.result.ast);
|
|
216
|
-
cache.template = base.content;
|
|
217
|
-
cache.snapshot = getUntrackedSnapshot();
|
|
218
|
-
cache.result = newResult;
|
|
219
186
|
return {
|
|
187
|
+
snapshot: getUntrackedSnapshot(),
|
|
188
|
+
template: base.content,
|
|
189
|
+
result: newResult,
|
|
190
|
+
plugin: lastResult.plugin,
|
|
220
191
|
errors: [],
|
|
221
192
|
warnings: [],
|
|
222
|
-
ast: newResult.ast,
|
|
223
193
|
};
|
|
224
194
|
}
|
|
225
195
|
}
|
|
@@ -240,54 +210,49 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
240
210
|
}
|
|
241
211
|
}
|
|
242
212
|
for (const plugin of plugins) {
|
|
243
|
-
let result;
|
|
244
213
|
try {
|
|
245
|
-
result = plugin.compileSFCTemplate?.(base.lang, base.content, options);
|
|
214
|
+
const result = plugin.compileSFCTemplate?.(base.lang, base.content, options);
|
|
246
215
|
if (result) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
catch (e) {
|
|
251
|
-
const err = e;
|
|
252
|
-
errors.push(err);
|
|
253
|
-
}
|
|
254
|
-
if (result || errors.length) {
|
|
255
|
-
if (result && !errors.length && !warnings.length) {
|
|
256
|
-
cache = {
|
|
257
|
-
template: base.content,
|
|
216
|
+
(0, normalize_1.normalizeTemplateAST)(result.ast);
|
|
217
|
+
return {
|
|
258
218
|
snapshot: getUntrackedSnapshot(),
|
|
259
|
-
|
|
219
|
+
template: base.content,
|
|
220
|
+
result,
|
|
260
221
|
plugin,
|
|
222
|
+
errors,
|
|
223
|
+
warnings,
|
|
261
224
|
};
|
|
262
225
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
266
228
|
return {
|
|
267
|
-
|
|
229
|
+
snapshot: getUntrackedSnapshot(),
|
|
230
|
+
template: base.content,
|
|
231
|
+
plugin,
|
|
232
|
+
errors: [e],
|
|
268
233
|
warnings,
|
|
269
|
-
ast: result?.ast,
|
|
270
234
|
};
|
|
271
235
|
}
|
|
272
236
|
}
|
|
273
237
|
return {
|
|
238
|
+
snapshot: getUntrackedSnapshot(),
|
|
239
|
+
template: base.content,
|
|
274
240
|
errors,
|
|
275
241
|
warnings,
|
|
276
|
-
ast: undefined,
|
|
277
242
|
};
|
|
278
243
|
});
|
|
279
244
|
}
|
|
280
|
-
function
|
|
245
|
+
function useNullableSfcBlock(name, defaultLang, getBlock, resolve) {
|
|
281
246
|
const hasBlock = (0, alien_signals_1.computed)(() => !!getBlock());
|
|
282
247
|
return (0, alien_signals_1.computed)(() => {
|
|
283
248
|
if (!hasBlock()) {
|
|
284
249
|
return;
|
|
285
250
|
}
|
|
286
251
|
const _block = (0, alien_signals_1.computed)(() => getBlock());
|
|
287
|
-
return resolve(_block,
|
|
252
|
+
return resolve(_block, useSfcBlock(name, defaultLang, _block));
|
|
288
253
|
});
|
|
289
254
|
}
|
|
290
|
-
function
|
|
255
|
+
function useSfcBlock(name, defaultLang, getBlock) {
|
|
291
256
|
const getLang = (0, alien_signals_1.computed)(() => getBlock().lang ?? defaultLang);
|
|
292
257
|
const getAttrs = (0, alien_signals_1.computed)(() => getBlock().attrs); // TODO: computed it
|
|
293
258
|
const getContent = (0, alien_signals_1.computed)(() => getBlock().content);
|
|
@@ -321,7 +286,7 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
321
286
|
},
|
|
322
287
|
};
|
|
323
288
|
}
|
|
324
|
-
function
|
|
289
|
+
function useAttrValue(key, base, getBlock) {
|
|
325
290
|
return (0, alien_signals_1.computed)(() => {
|
|
326
291
|
const val = getBlock()[key];
|
|
327
292
|
if (typeof val === 'object') {
|
|
@@ -337,4 +302,4 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
337
302
|
function mergeObject(a, b) {
|
|
338
303
|
return Object.defineProperties(a, Object.getOwnPropertyDescriptors(b));
|
|
339
304
|
}
|
|
340
|
-
//# sourceMappingURL=
|
|
305
|
+
//# sourceMappingURL=ir.js.map
|