@vue/language-core 3.1.4 → 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 +15 -20
- 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 +10 -19
- package/lib/codegen/template/context.js +82 -94
- package/lib/codegen/template/element.js +174 -65
- package/lib/codegen/template/elementDirectives.js +32 -12
- package/lib/codegen/template/elementEvents.d.ts +1 -1
- package/lib/codegen/template/elementEvents.js +30 -35
- package/lib/codegen/template/elementProps.d.ts +3 -3
- package/lib/codegen/template/elementProps.js +64 -83
- package/lib/codegen/template/index.d.ts +11 -22
- package/lib/codegen/template/index.js +85 -80
- package/lib/codegen/template/interpolation.d.ts +3 -3
- package/lib/codegen/template/interpolation.js +108 -155
- 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 +26 -14
- 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 -16
- 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 -6
- package/lib/codegen/utils/index.js +41 -26
- 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.js +4 -4
- package/lib/languagePlugin.d.ts +1 -1
- package/lib/languagePlugin.js +18 -25
- package/lib/plugins/vue-template-html.js +12 -9
- package/lib/plugins/vue-template-inline-css.js +8 -18
- package/lib/plugins/vue-template-inline-ts.js +12 -14
- package/lib/plugins/vue-tsx.d.ts +14 -23
- package/lib/plugins/vue-tsx.js +121 -69
- package/lib/plugins.js +1 -1
- package/lib/types.d.ts +5 -4
- package/lib/utils/parseSfc.js +10 -11
- package/lib/utils/shared.d.ts +1 -0
- package/lib/utils/shared.js +9 -0
- 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} +65 -96
- 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 -3
- package/lib/codegen/utils/wrapWith.js +0 -24
- 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,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
3
|
+
exports.useIR = useIR;
|
|
4
|
+
const CompilerDOM = require("@vue/compiler-dom");
|
|
5
5
|
const alien_signals_1 = require("alien-signals");
|
|
6
6
|
const signals_1 = require("../utils/signals");
|
|
7
|
-
|
|
8
|
-
function
|
|
7
|
+
const normalize_1 = require("./normalize");
|
|
8
|
+
function useIR(ts, plugins, fileName, getSnapshot, getParseSfcResult) {
|
|
9
9
|
const getUntrackedSnapshot = () => {
|
|
10
10
|
const pausedSub = (0, alien_signals_1.setActiveSub)(undefined);
|
|
11
11
|
const res = getSnapshot();
|
|
@@ -15,30 +15,25 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
15
15
|
const getContent = (0, alien_signals_1.computed)(() => {
|
|
16
16
|
return getSnapshot().getText(0, getSnapshot().getLength());
|
|
17
17
|
});
|
|
18
|
-
const getComments = (0,
|
|
19
|
-
|
|
20
|
-
if (oldValue?.length === newValue.length
|
|
21
|
-
&& oldValue.every((v, i) => v === newValue[i])) {
|
|
22
|
-
return oldValue;
|
|
23
|
-
}
|
|
24
|
-
return newValue;
|
|
18
|
+
const getComments = (0, signals_1.computedArray)(() => {
|
|
19
|
+
return getParseSfcResult()?.descriptor.comments ?? [];
|
|
25
20
|
});
|
|
26
|
-
const getTemplate =
|
|
27
|
-
const
|
|
21
|
+
const getTemplate = useNullableSfcBlock('template', 'html', (0, alien_signals_1.computed)(() => getParseSfcResult()?.descriptor.template ?? undefined), (_block, base) => {
|
|
22
|
+
const getParseTemplateResult = useParseTemplateResult(base);
|
|
28
23
|
return mergeObject(base, {
|
|
29
24
|
get ast() {
|
|
30
|
-
return
|
|
25
|
+
return getParseTemplateResult().result?.ast;
|
|
31
26
|
},
|
|
32
27
|
get errors() {
|
|
33
|
-
return
|
|
28
|
+
return getParseTemplateResult().errors;
|
|
34
29
|
},
|
|
35
30
|
get warnings() {
|
|
36
|
-
return
|
|
31
|
+
return getParseTemplateResult().warnings;
|
|
37
32
|
},
|
|
38
33
|
});
|
|
39
34
|
});
|
|
40
|
-
const getScript =
|
|
41
|
-
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);
|
|
42
37
|
const getAst = (0, alien_signals_1.computed)(() => {
|
|
43
38
|
for (const plugin of plugins) {
|
|
44
39
|
const ast = plugin.compileSFCScript?.(base.lang, base.content);
|
|
@@ -57,8 +52,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
57
52
|
},
|
|
58
53
|
});
|
|
59
54
|
});
|
|
60
|
-
const getOriginalScriptSetup =
|
|
61
|
-
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);
|
|
62
57
|
const getAst = (0, alien_signals_1.computed)(() => {
|
|
63
58
|
for (const plugin of plugins) {
|
|
64
59
|
const ast = plugin.compileSFCScript?.(base.lang, base.content);
|
|
@@ -77,8 +72,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
77
72
|
},
|
|
78
73
|
});
|
|
79
74
|
});
|
|
80
|
-
const hasScript = (0, alien_signals_1.computed)(() => !!
|
|
81
|
-
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);
|
|
82
77
|
const getScriptSetup = (0, alien_signals_1.computed)(() => {
|
|
83
78
|
if (!hasScript() && !hasScriptSetup()) {
|
|
84
79
|
// #region monkey fix: https://github.com/vuejs/language-tools/pull/2113
|
|
@@ -98,10 +93,10 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
98
93
|
}
|
|
99
94
|
return getOriginalScriptSetup();
|
|
100
95
|
});
|
|
101
|
-
const styles = (0, signals_1.
|
|
102
|
-
const base =
|
|
103
|
-
const getSrc =
|
|
104
|
-
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);
|
|
105
100
|
const getScoped = (0, alien_signals_1.computed)(() => !!getBlock().scoped);
|
|
106
101
|
const getIr = (0, alien_signals_1.computed)(() => {
|
|
107
102
|
for (const plugin of plugins) {
|
|
@@ -111,9 +106,9 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
111
106
|
}
|
|
112
107
|
}
|
|
113
108
|
});
|
|
114
|
-
const getImports = (0, signals_1.
|
|
115
|
-
const getBindings = (0, signals_1.
|
|
116
|
-
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);
|
|
117
112
|
return () => mergeObject(base, {
|
|
118
113
|
get src() {
|
|
119
114
|
return getSrc();
|
|
@@ -135,8 +130,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
135
130
|
},
|
|
136
131
|
});
|
|
137
132
|
});
|
|
138
|
-
const customBlocks = (0, signals_1.
|
|
139
|
-
const base =
|
|
133
|
+
const customBlocks = (0, signals_1.reactiveArray)(() => getParseSfcResult()?.descriptor.customBlocks ?? [], (getBlock, i) => {
|
|
134
|
+
const base = useSfcBlock('custom_block_' + i, 'txt', getBlock);
|
|
140
135
|
const getType = (0, alien_signals_1.computed)(() => getBlock().type);
|
|
141
136
|
return () => mergeObject(base, {
|
|
142
137
|
get type() {
|
|
@@ -167,68 +162,47 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
167
162
|
return customBlocks;
|
|
168
163
|
},
|
|
169
164
|
};
|
|
170
|
-
function
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
let newTsAsts = exports.templateInlineTsAsts.get(newAst);
|
|
175
|
-
if (!newTsAsts) {
|
|
176
|
-
exports.templateInlineTsAsts.set(newAst, newTsAsts = new Map());
|
|
177
|
-
}
|
|
178
|
-
const oldTsAsts = oldAst && exports.templateInlineTsAsts.get(oldAst) || inlineTsAsts;
|
|
179
|
-
if (oldTsAsts) {
|
|
180
|
-
for (const [text, ast] of oldTsAsts) {
|
|
181
|
-
if (!ast.__volar_used) {
|
|
182
|
-
oldTsAsts.delete(text);
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
newTsAsts.set(text, ast);
|
|
186
|
-
ast.__volar_used = false;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
inlineTsAsts = new Map(newTsAsts);
|
|
191
|
-
}
|
|
192
|
-
return (0, alien_signals_1.computed)(() => {
|
|
193
|
-
if (cache?.template === base.content) {
|
|
194
|
-
return {
|
|
195
|
-
errors: [],
|
|
196
|
-
warnings: [],
|
|
197
|
-
ast: cache.result.ast,
|
|
198
|
-
};
|
|
165
|
+
function useParseTemplateResult(base) {
|
|
166
|
+
return (0, alien_signals_1.computed)(lastResult => {
|
|
167
|
+
if (lastResult?.template === base.content) {
|
|
168
|
+
return lastResult;
|
|
199
169
|
}
|
|
200
170
|
// incremental update
|
|
201
|
-
if (
|
|
202
|
-
|
|
171
|
+
if (lastResult?.result && lastResult.plugin?.updateSFCTemplate
|
|
172
|
+
&& !lastResult.errors.length
|
|
173
|
+
&& !lastResult.warnings.length) {
|
|
174
|
+
const change = getUntrackedSnapshot().getChangeRange(lastResult.snapshot);
|
|
203
175
|
if (change) {
|
|
204
176
|
const pausedSub = (0, alien_signals_1.setActiveSub)(undefined);
|
|
205
177
|
const templateOffset = base.startTagEnd;
|
|
206
178
|
(0, alien_signals_1.setActiveSub)(pausedSub);
|
|
207
179
|
const newText = getUntrackedSnapshot().getText(change.span.start, change.span.start + change.newLength);
|
|
208
|
-
const newResult =
|
|
180
|
+
const newResult = lastResult.plugin.updateSFCTemplate(lastResult.result, {
|
|
209
181
|
start: change.span.start - templateOffset,
|
|
210
|
-
end: change.span.start + change.span.length
|
|
182
|
+
end: change.span.start - templateOffset + change.span.length,
|
|
211
183
|
newText,
|
|
212
184
|
});
|
|
213
185
|
if (newResult) {
|
|
214
|
-
updateInlineTsAsts(newResult.ast, cache.result.ast);
|
|
215
|
-
cache.template = base.content;
|
|
216
|
-
cache.snapshot = getUntrackedSnapshot();
|
|
217
|
-
cache.result = newResult;
|
|
218
186
|
return {
|
|
187
|
+
snapshot: getUntrackedSnapshot(),
|
|
188
|
+
template: base.content,
|
|
189
|
+
result: newResult,
|
|
190
|
+
plugin: lastResult.plugin,
|
|
219
191
|
errors: [],
|
|
220
192
|
warnings: [],
|
|
221
|
-
ast: newResult.ast,
|
|
222
193
|
};
|
|
223
194
|
}
|
|
224
195
|
}
|
|
225
196
|
}
|
|
226
197
|
const errors = [];
|
|
227
198
|
const warnings = [];
|
|
199
|
+
const [nodeTransforms, directiveTransforms] = CompilerDOM.getBaseTransformPreset();
|
|
228
200
|
let options = {
|
|
229
|
-
onError:
|
|
230
|
-
onWarn:
|
|
201
|
+
onError: err => errors.push(err),
|
|
202
|
+
onWarn: err => warnings.push(err),
|
|
231
203
|
expressionPlugins: ['typescript'],
|
|
204
|
+
nodeTransforms,
|
|
205
|
+
directiveTransforms,
|
|
232
206
|
};
|
|
233
207
|
for (const plugin of plugins) {
|
|
234
208
|
if (plugin.resolveTemplateCompilerOptions) {
|
|
@@ -236,54 +210,49 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
236
210
|
}
|
|
237
211
|
}
|
|
238
212
|
for (const plugin of plugins) {
|
|
239
|
-
let result;
|
|
240
213
|
try {
|
|
241
|
-
result = plugin.compileSFCTemplate?.(base.lang, base.content, options);
|
|
214
|
+
const result = plugin.compileSFCTemplate?.(base.lang, base.content, options);
|
|
242
215
|
if (result) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
catch (e) {
|
|
247
|
-
const err = e;
|
|
248
|
-
errors.push(err);
|
|
249
|
-
}
|
|
250
|
-
if (result || errors.length) {
|
|
251
|
-
if (result && !errors.length && !warnings.length) {
|
|
252
|
-
cache = {
|
|
253
|
-
template: base.content,
|
|
216
|
+
(0, normalize_1.normalizeTemplateAST)(result.ast);
|
|
217
|
+
return {
|
|
254
218
|
snapshot: getUntrackedSnapshot(),
|
|
255
|
-
|
|
219
|
+
template: base.content,
|
|
220
|
+
result,
|
|
256
221
|
plugin,
|
|
222
|
+
errors,
|
|
223
|
+
warnings,
|
|
257
224
|
};
|
|
258
225
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
262
228
|
return {
|
|
263
|
-
|
|
229
|
+
snapshot: getUntrackedSnapshot(),
|
|
230
|
+
template: base.content,
|
|
231
|
+
plugin,
|
|
232
|
+
errors: [e],
|
|
264
233
|
warnings,
|
|
265
|
-
ast: result?.ast,
|
|
266
234
|
};
|
|
267
235
|
}
|
|
268
236
|
}
|
|
269
237
|
return {
|
|
238
|
+
snapshot: getUntrackedSnapshot(),
|
|
239
|
+
template: base.content,
|
|
270
240
|
errors,
|
|
271
241
|
warnings,
|
|
272
|
-
ast: undefined,
|
|
273
242
|
};
|
|
274
243
|
});
|
|
275
244
|
}
|
|
276
|
-
function
|
|
245
|
+
function useNullableSfcBlock(name, defaultLang, getBlock, resolve) {
|
|
277
246
|
const hasBlock = (0, alien_signals_1.computed)(() => !!getBlock());
|
|
278
247
|
return (0, alien_signals_1.computed)(() => {
|
|
279
248
|
if (!hasBlock()) {
|
|
280
249
|
return;
|
|
281
250
|
}
|
|
282
251
|
const _block = (0, alien_signals_1.computed)(() => getBlock());
|
|
283
|
-
return resolve(_block,
|
|
252
|
+
return resolve(_block, useSfcBlock(name, defaultLang, _block));
|
|
284
253
|
});
|
|
285
254
|
}
|
|
286
|
-
function
|
|
255
|
+
function useSfcBlock(name, defaultLang, getBlock) {
|
|
287
256
|
const getLang = (0, alien_signals_1.computed)(() => getBlock().lang ?? defaultLang);
|
|
288
257
|
const getAttrs = (0, alien_signals_1.computed)(() => getBlock().attrs); // TODO: computed it
|
|
289
258
|
const getContent = (0, alien_signals_1.computed)(() => getBlock().content);
|
|
@@ -317,7 +286,7 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
317
286
|
},
|
|
318
287
|
};
|
|
319
288
|
}
|
|
320
|
-
function
|
|
289
|
+
function useAttrValue(key, base, getBlock) {
|
|
321
290
|
return (0, alien_signals_1.computed)(() => {
|
|
322
291
|
const val = getBlock()[key];
|
|
323
292
|
if (typeof val === 'object') {
|
|
@@ -333,4 +302,4 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
333
302
|
function mergeObject(a, b) {
|
|
334
303
|
return Object.defineProperties(a, Object.getOwnPropertyDescriptors(b));
|
|
335
304
|
}
|
|
336
|
-
//# sourceMappingURL=
|
|
305
|
+
//# sourceMappingURL=ir.js.map
|