@vue-jsx-vapor/compiler 2.6.6 → 2.6.7
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/dist/index.cjs +629 -287
- package/dist/index.d.cts +80 -22
- package/dist/index.d.ts +80 -22
- package/dist/index.js +594 -252
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
@@ -23,11 +23,64 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
23
23
|
//#endregion
|
24
24
|
const __babel_parser = __toESM(require("@babel/parser"));
|
25
25
|
const __vue_shared = __toESM(require("@vue/shared"));
|
26
|
-
const __vue_compiler_dom = __toESM(require("@vue/compiler-dom"));
|
27
|
-
const ast_kit = __toESM(require("ast-kit"));
|
28
|
-
const __babel_types = __toESM(require("@babel/types"));
|
29
26
|
const source_map_js = __toESM(require("source-map-js"));
|
27
|
+
const ast_kit = __toESM(require("ast-kit"));
|
28
|
+
|
29
|
+
//#region src/utils/error.ts
|
30
|
+
let ErrorCodes = /* @__PURE__ */ function(ErrorCodes$1) {
|
31
|
+
ErrorCodes$1[ErrorCodes$1["X_V_IF_NO_EXPRESSION"] = 28] = "X_V_IF_NO_EXPRESSION";
|
32
|
+
ErrorCodes$1[ErrorCodes$1["X_V_ELSE_NO_ADJACENT_IF"] = 30] = "X_V_ELSE_NO_ADJACENT_IF";
|
33
|
+
ErrorCodes$1[ErrorCodes$1["X_V_FOR_NO_EXPRESSION"] = 31] = "X_V_FOR_NO_EXPRESSION";
|
34
|
+
ErrorCodes$1[ErrorCodes$1["X_V_FOR_MALFORMED_EXPRESSION"] = 32] = "X_V_FOR_MALFORMED_EXPRESSION";
|
35
|
+
ErrorCodes$1[ErrorCodes$1["X_V_ON_NO_EXPRESSION"] = 35] = "X_V_ON_NO_EXPRESSION";
|
36
|
+
ErrorCodes$1[ErrorCodes$1["X_V_SLOT_MIXED_SLOT_USAGE"] = 37] = "X_V_SLOT_MIXED_SLOT_USAGE";
|
37
|
+
ErrorCodes$1[ErrorCodes$1["X_V_SLOT_DUPLICATE_SLOT_NAMES"] = 38] = "X_V_SLOT_DUPLICATE_SLOT_NAMES";
|
38
|
+
ErrorCodes$1[ErrorCodes$1["X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN"] = 39] = "X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN";
|
39
|
+
ErrorCodes$1[ErrorCodes$1["X_V_SLOT_MISPLACED"] = 40] = "X_V_SLOT_MISPLACED";
|
40
|
+
ErrorCodes$1[ErrorCodes$1["X_V_MODEL_NO_EXPRESSION"] = 41] = "X_V_MODEL_NO_EXPRESSION";
|
41
|
+
ErrorCodes$1[ErrorCodes$1["X_V_MODEL_MALFORMED_EXPRESSION"] = 42] = "X_V_MODEL_MALFORMED_EXPRESSION";
|
42
|
+
ErrorCodes$1[ErrorCodes$1["X_V_HTML_NO_EXPRESSION"] = 53] = "X_V_HTML_NO_EXPRESSION";
|
43
|
+
ErrorCodes$1[ErrorCodes$1["X_V_HTML_WITH_CHILDREN"] = 54] = "X_V_HTML_WITH_CHILDREN";
|
44
|
+
ErrorCodes$1[ErrorCodes$1["X_V_TEXT_NO_EXPRESSION"] = 55] = "X_V_TEXT_NO_EXPRESSION";
|
45
|
+
ErrorCodes$1[ErrorCodes$1["X_V_TEXT_WITH_CHILDREN"] = 56] = "X_V_TEXT_WITH_CHILDREN";
|
46
|
+
ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ON_INVALID_ELEMENT"] = 57] = "X_V_MODEL_ON_INVALID_ELEMENT";
|
47
|
+
ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ARG_ON_ELEMENT"] = 58] = "X_V_MODEL_ARG_ON_ELEMENT";
|
48
|
+
ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ON_FILE_INPUT_ELEMENT"] = 59] = "X_V_MODEL_ON_FILE_INPUT_ELEMENT";
|
49
|
+
ErrorCodes$1[ErrorCodes$1["X_V_MODEL_UNNECESSARY_VALUE"] = 60] = "X_V_MODEL_UNNECESSARY_VALUE";
|
50
|
+
ErrorCodes$1[ErrorCodes$1["X_V_SHOW_NO_EXPRESSION"] = 61] = "X_V_SHOW_NO_EXPRESSION";
|
51
|
+
return ErrorCodes$1;
|
52
|
+
}({});
|
53
|
+
const errorMessages = {
|
54
|
+
[ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`,
|
55
|
+
[ErrorCodes.X_V_ELSE_NO_ADJACENT_IF]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
|
56
|
+
[ErrorCodes.X_V_FOR_NO_EXPRESSION]: `v-for is missing expression.`,
|
57
|
+
[ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
|
58
|
+
[ErrorCodes.X_V_ON_NO_EXPRESSION]: `v-on is missing expression.`,
|
59
|
+
[ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE]: "Mixed v-slot usage on both the component and nested <template>. When there are multiple named slots, all slots should use <template> syntax to avoid scope ambiguity.",
|
60
|
+
[ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES]: `Duplicate slot names found. `,
|
61
|
+
[ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN]: "Extraneous children found when component already has explicitly named default slot. These children will be ignored.",
|
62
|
+
[ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
|
63
|
+
[ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
|
64
|
+
[ErrorCodes.X_V_SLOT_MISPLACED]: `v-slot can only be used on components or <template> tags.`,
|
65
|
+
[ErrorCodes.X_V_HTML_NO_EXPRESSION]: `v-html is missing expression.`,
|
66
|
+
[ErrorCodes.X_V_HTML_WITH_CHILDREN]: `v-html will override element children.`,
|
67
|
+
[ErrorCodes.X_V_TEXT_NO_EXPRESSION]: `v-text is missing expression.`,
|
68
|
+
[ErrorCodes.X_V_TEXT_WITH_CHILDREN]: `v-text will override element children.`,
|
69
|
+
[ErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`,
|
70
|
+
[ErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
|
71
|
+
[ErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
|
72
|
+
[ErrorCodes.X_V_MODEL_UNNECESSARY_VALUE]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
|
73
|
+
[ErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`
|
74
|
+
};
|
75
|
+
function createCompilerError(code, loc, messages, additionalMessage) {
|
76
|
+
const msg = (messages || errorMessages)[code] + (additionalMessage || ``);
|
77
|
+
const error = new SyntaxError(String(msg));
|
78
|
+
error.code = code;
|
79
|
+
error.loc = loc;
|
80
|
+
return error;
|
81
|
+
}
|
30
82
|
|
83
|
+
//#endregion
|
31
84
|
//#region src/ir/component.ts
|
32
85
|
let IRDynamicPropsKind = /* @__PURE__ */ function(IRDynamicPropsKind$1) {
|
33
86
|
IRDynamicPropsKind$1[IRDynamicPropsKind$1["EXPRESSION"] = 0] = "EXPRESSION";
|
@@ -90,62 +143,104 @@ function isBlockOperation(op) {
|
|
90
143
|
}
|
91
144
|
|
92
145
|
//#endregion
|
93
|
-
//#region src/
|
94
|
-
function
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
}
|
99
|
-
}
|
100
|
-
function newBlock(node) {
|
101
|
-
return {
|
102
|
-
type: 1,
|
103
|
-
node,
|
104
|
-
dynamic: newDynamic(),
|
105
|
-
effect: [],
|
106
|
-
operation: [],
|
107
|
-
returns: [],
|
108
|
-
tempId: 0
|
109
|
-
};
|
146
|
+
//#region src/utils/ast.ts
|
147
|
+
function findProp(expression, key) {
|
148
|
+
if (expression?.type === "JSXElement") for (const attr of expression.openingElement.attributes) {
|
149
|
+
const name = attr.type === "JSXAttribute" && (attr.name.type === "JSXIdentifier" ? attr.name.name : attr.name.type === "JSXNamespacedName" ? attr.name.namespace.name : "").split("_")[0];
|
150
|
+
if (name && ((0, __vue_shared.isString)(key) ? name === key : key.test(name))) return attr;
|
151
|
+
}
|
110
152
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
153
|
+
const TS_NODE_TYPES = [
|
154
|
+
"TSAsExpression",
|
155
|
+
"TSTypeAssertion",
|
156
|
+
"TSNonNullExpression",
|
157
|
+
"TSInstantiationExpression",
|
158
|
+
"TSSatisfiesExpression"
|
159
|
+
];
|
160
|
+
function unwrapTSNode(node) {
|
161
|
+
if (TS_NODE_TYPES.includes(node.type)) return unwrapTSNode(node.expression);
|
162
|
+
else return node;
|
117
163
|
}
|
118
|
-
function
|
119
|
-
if (node.type
|
120
|
-
|
164
|
+
function isJSXComponent(node) {
|
165
|
+
if (node.type !== "JSXElement") return false;
|
166
|
+
const { openingElement } = node;
|
167
|
+
if (openingElement.name.type === "JSXIdentifier") {
|
168
|
+
const name = openingElement.name.name;
|
169
|
+
return !(0, __vue_shared.isHTMLTag)(name) && !(0, __vue_shared.isSVGTag)(name);
|
170
|
+
} else return openingElement.name.type === "JSXMemberExpression";
|
121
171
|
}
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
//#region src/utils.ts
|
127
|
-
function propToExpression(prop, context) {
|
128
|
-
return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION;
|
172
|
+
function isMemberExpression(exp) {
|
173
|
+
if (!exp.ast) return;
|
174
|
+
const ret = unwrapTSNode(exp.ast);
|
175
|
+
return ret.type === "MemberExpression" || ret.type === "OptionalMemberExpression" || ret.type === "Identifier" && ret.name !== "undefined";
|
129
176
|
}
|
130
|
-
function
|
131
|
-
|
177
|
+
function isTemplate(node) {
|
178
|
+
if (node.type === "JSXElement" && node.openingElement.name.type === "JSXIdentifier") return node.openingElement.name.name === "template";
|
132
179
|
}
|
133
|
-
function
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
180
|
+
function isStaticNode(node) {
|
181
|
+
node = unwrapTSNode(node);
|
182
|
+
switch (node.type) {
|
183
|
+
case "UnaryExpression": return isStaticNode(node.argument);
|
184
|
+
case "LogicalExpression":
|
185
|
+
case "BinaryExpression": return isStaticNode(node.left) && isStaticNode(node.right);
|
186
|
+
case "ConditionalExpression": return isStaticNode(node.test) && isStaticNode(node.consequent) && isStaticNode(node.alternate);
|
187
|
+
case "SequenceExpression":
|
188
|
+
case "TemplateLiteral": return node.expressions.every((expr) => isStaticNode(expr));
|
189
|
+
case "ParenthesizedExpression": return isStaticNode(node.expression);
|
190
|
+
case "StringLiteral":
|
191
|
+
case "NumericLiteral":
|
192
|
+
case "BooleanLiteral":
|
193
|
+
case "NullLiteral":
|
194
|
+
case "BigIntLiteral": return true;
|
195
|
+
}
|
196
|
+
return false;
|
197
|
+
}
|
198
|
+
function isConstantNode(node) {
|
199
|
+
if (isStaticNode(node)) return true;
|
200
|
+
node = unwrapTSNode(node);
|
201
|
+
switch (node.type) {
|
202
|
+
case "Identifier": return node.name === "undefined" || (0, __vue_shared.isGloballyAllowed)(node.name);
|
203
|
+
case "RegExpLiteral": return true;
|
204
|
+
case "ObjectExpression": return node.properties.every((prop) => {
|
205
|
+
if (prop.type === "ObjectMethod") return false;
|
206
|
+
if (prop.type === "SpreadElement") return isConstantNode(prop.argument);
|
207
|
+
return (!prop.computed || isConstantNode(prop.key)) && isConstantNode(prop.value);
|
208
|
+
});
|
209
|
+
case "ArrayExpression": return node.elements.every((element) => {
|
210
|
+
if (element === null) return true;
|
211
|
+
if (element.type === "SpreadElement") return isConstantNode(element.argument);
|
212
|
+
return isConstantNode(element);
|
213
|
+
});
|
141
214
|
}
|
142
|
-
return
|
215
|
+
return false;
|
143
216
|
}
|
144
|
-
const
|
145
|
-
|
146
|
-
|
147
|
-
|
217
|
+
const isFnExpression = (exp) => {
|
218
|
+
try {
|
219
|
+
if (!exp.ast) return false;
|
220
|
+
let ret = exp.ast;
|
221
|
+
if (ret.type === "Program") {
|
222
|
+
ret = ret.body[0];
|
223
|
+
if (ret.type === "ExpressionStatement") ret = ret.expression;
|
224
|
+
}
|
225
|
+
ret = unwrapTSNode(ret);
|
226
|
+
return ret.type === "FunctionExpression" || ret.type === "ArrowFunctionExpression";
|
227
|
+
} catch {
|
228
|
+
return false;
|
229
|
+
}
|
148
230
|
};
|
231
|
+
const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node);
|
232
|
+
const isStaticProperty = (node) => !!node && (node.type === "ObjectProperty" || node.type === "ObjectMethod") && !node.computed;
|
233
|
+
const nonIdentifierRE = /^$|^\d|[^$\w\u00A0-\uFFFF]/;
|
234
|
+
const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
|
235
|
+
function getTextLikeValue(node, excludeNumber) {
|
236
|
+
node = node.type === "JSXExpressionContainer" ? node.expression : node;
|
237
|
+
if (node.type === "StringLiteral") return node.value;
|
238
|
+
else if (!excludeNumber && (node.type === "NumericLiteral" || node.type === "BigIntLiteral")) return String(node.value);
|
239
|
+
else if (node.type === "TemplateLiteral" && node.expressions.length === 0) return node.quasis[0].value.cooked;
|
240
|
+
}
|
241
|
+
|
242
|
+
//#endregion
|
243
|
+
//#region src/utils/text.ts
|
149
244
|
const EMPTY_TEXT_REGEX = /^[\t\v\f \u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[\n\r]\s*$/;
|
150
245
|
const START_EMPTY_TEXT_REGEX = /^\s*[\n\r]/;
|
151
246
|
const END_EMPTY_TEXT_REGEX = /[\n\r]\s*$/;
|
@@ -159,59 +254,61 @@ function resolveJSXText(node) {
|
|
159
254
|
function isEmptyText(node) {
|
160
255
|
return node.type === "JSXText" && EMPTY_TEXT_REGEX.test(String(node.extra?.raw)) || node.type === "JSXExpressionContainer" && node.expression.type === "JSXEmptyExpression";
|
161
256
|
}
|
162
|
-
function
|
163
|
-
|
164
|
-
|
165
|
-
|
257
|
+
function getText(node, content) {
|
258
|
+
return content.ir.source.slice(node.start, node.end);
|
259
|
+
}
|
260
|
+
|
261
|
+
//#endregion
|
262
|
+
//#region src/utils/expression.ts
|
263
|
+
const locStub = {
|
264
|
+
start: {
|
265
|
+
line: 1,
|
266
|
+
column: 0,
|
267
|
+
index: 0
|
268
|
+
},
|
269
|
+
end: {
|
270
|
+
line: 1,
|
271
|
+
column: 0,
|
272
|
+
index: 0
|
273
|
+
},
|
274
|
+
filename: "",
|
275
|
+
identifierName: void 0
|
276
|
+
};
|
277
|
+
function createSimpleExpression(content, isStatic = false, ast) {
|
278
|
+
return {
|
279
|
+
loc: ast ? ast.loc : locStub,
|
280
|
+
content,
|
281
|
+
isStatic,
|
282
|
+
ast
|
283
|
+
};
|
284
|
+
}
|
285
|
+
const isLiteralWhitelisted = /* @__PURE__ */ (0, __vue_shared.makeMap)("true,false,null,this");
|
286
|
+
function isConstantExpression(exp) {
|
287
|
+
return isLiteralWhitelisted(exp.content) || (0, __vue_shared.isGloballyAllowed)(exp.content) || getLiteralExpressionValue(exp) !== null;
|
288
|
+
}
|
289
|
+
function getLiteralExpressionValue(exp) {
|
290
|
+
if (exp.ast) {
|
291
|
+
const res = getTextLikeValue(exp.ast);
|
292
|
+
if (res != null) return res;
|
166
293
|
}
|
167
|
-
return exp;
|
294
|
+
return exp.isStatic ? exp.content : null;
|
168
295
|
}
|
169
|
-
|
170
|
-
|
171
|
-
|
296
|
+
const EMPTY_EXPRESSION = createSimpleExpression("", true);
|
297
|
+
function resolveExpression(node, context) {
|
298
|
+
if (!node) return EMPTY_EXPRESSION;
|
299
|
+
node = unwrapTSNode(node.type === "JSXExpressionContainer" ? node.expression : node);
|
172
300
|
const isStatic = node.type === "StringLiteral" || node.type === "JSXText" || node.type === "JSXIdentifier";
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
}
|
179
|
-
return resolveSimpleExpression(source, isStatic, location, isStatic ? void 0 : node);
|
180
|
-
}
|
181
|
-
function resolveSimpleExpression(source, isStatic, location, ast) {
|
182
|
-
const result = (0, __vue_compiler_dom.createSimpleExpression)(source, isStatic, resolveLocation(location, source));
|
183
|
-
result.ast = ast ?? null;
|
184
|
-
return result;
|
185
|
-
}
|
186
|
-
function resolveLocation(location, context) {
|
187
|
-
return location ? {
|
188
|
-
start: {
|
189
|
-
line: location.start.line,
|
190
|
-
column: location.start.column + 1,
|
191
|
-
offset: location.start.index
|
192
|
-
},
|
193
|
-
end: {
|
194
|
-
line: location.end.line,
|
195
|
-
column: location.end.column + 1,
|
196
|
-
offset: location.end.index
|
197
|
-
},
|
198
|
-
source: (0, __vue_shared.isString)(context) ? context : context.ir.source.slice(location.start.index, location.end.index)
|
199
|
-
} : {
|
200
|
-
start: {
|
201
|
-
line: 1,
|
202
|
-
column: 1,
|
203
|
-
offset: 0
|
204
|
-
},
|
205
|
-
end: {
|
206
|
-
line: 1,
|
207
|
-
column: 1,
|
208
|
-
offset: 0
|
209
|
-
},
|
210
|
-
source: ""
|
211
|
-
};
|
301
|
+
const source = node.type === "JSXEmptyExpression" ? "" : node.type === "JSXIdentifier" ? node.name : node.type === "StringLiteral" ? node.value : node.type === "JSXText" ? resolveJSXText(node) : node.type === "Identifier" ? node.name : context.ir.source.slice(node.start, node.end);
|
302
|
+
return createSimpleExpression(source, isStatic, node);
|
303
|
+
}
|
304
|
+
function propToExpression(prop, context) {
|
305
|
+
return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION;
|
212
306
|
}
|
307
|
+
|
308
|
+
//#endregion
|
309
|
+
//#region src/utils/directive.ts
|
213
310
|
const namespaceRE = /^(?:\$([\w-]+)\$)?([\w-]+)?/;
|
214
|
-
function resolveDirective(node, context
|
311
|
+
function resolveDirective(node, context) {
|
215
312
|
const { value, name } = node;
|
216
313
|
let nameString = name.type === "JSXNamespacedName" ? name.namespace.name : name.type === "JSXIdentifier" ? name.name : "";
|
217
314
|
const isDirective = nameString.startsWith("v-");
|
@@ -231,48 +328,73 @@ function resolveDirective(node, context, withFn = false) {
|
|
231
328
|
} else if (modifierString) [argString, ...modifiers] = modifierString.split("_");
|
232
329
|
}
|
233
330
|
}
|
234
|
-
const arg = isDirective ? argString && name.type === "JSXNamespacedName" ?
|
235
|
-
const exp = value ?
|
331
|
+
const arg = isDirective ? argString && name.type === "JSXNamespacedName" ? createSimpleExpression(argString, isStatic, name.name) : void 0 : createSimpleExpression(nameString, true, name);
|
332
|
+
const exp = value ? resolveExpression(value, context) : void 0;
|
236
333
|
return {
|
237
|
-
type: __vue_compiler_dom.NodeTypes.DIRECTIVE,
|
238
334
|
name: isDirective ? nameString.slice(2) : "bind",
|
239
335
|
rawName: getText(name, context),
|
240
336
|
exp,
|
241
337
|
arg,
|
242
|
-
loc:
|
243
|
-
modifiers: modifiers.map((modifier) =>
|
338
|
+
loc: node.loc,
|
339
|
+
modifiers: modifiers.map((modifier) => createSimpleExpression(modifier))
|
244
340
|
};
|
245
341
|
}
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
const name = openingElement.name.name;
|
255
|
-
return !(0, __vue_shared.isHTMLTag)(name) && !(0, __vue_shared.isSVGTag)(name);
|
256
|
-
} else return openingElement.name.type === "JSXMemberExpression";
|
342
|
+
|
343
|
+
//#endregion
|
344
|
+
//#region src/utils/transform.ts
|
345
|
+
function newDynamic() {
|
346
|
+
return {
|
347
|
+
flags: DynamicFlag.REFERENCED,
|
348
|
+
children: []
|
349
|
+
};
|
257
350
|
}
|
258
|
-
function
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
351
|
+
function newBlock(node) {
|
352
|
+
return {
|
353
|
+
type: 1,
|
354
|
+
node,
|
355
|
+
dynamic: newDynamic(),
|
356
|
+
effect: [],
|
357
|
+
operation: [],
|
358
|
+
returns: [],
|
359
|
+
tempId: 0
|
360
|
+
};
|
263
361
|
}
|
264
|
-
function
|
265
|
-
|
362
|
+
function createBranch(node, context, isVFor) {
|
363
|
+
context.node = node = wrapFragment(node);
|
364
|
+
const branch = newBlock(node);
|
365
|
+
const exitBlock = context.enterBlock(branch, isVFor);
|
366
|
+
context.reference();
|
367
|
+
return [branch, exitBlock];
|
266
368
|
}
|
267
|
-
function
|
268
|
-
if (node.type === "
|
369
|
+
function wrapFragment(node) {
|
370
|
+
if (node.type === "JSXFragment" || isTemplate(node)) return node;
|
371
|
+
return {
|
372
|
+
type: "JSXFragment",
|
373
|
+
openingFragment: { type: "JSXOpeningFragment" },
|
374
|
+
closingFragment: { type: "JSXClosingFragment" },
|
375
|
+
children: [node.type === "JSXElement" ? node : {
|
376
|
+
type: "JSXExpressionContainer",
|
377
|
+
expression: node
|
378
|
+
}]
|
379
|
+
};
|
269
380
|
}
|
270
381
|
|
271
382
|
//#endregion
|
272
|
-
//#region src/
|
383
|
+
//#region src/utils/generate.ts
|
273
384
|
const NEWLINE = Symbol(`newline`);
|
274
385
|
const INDENT_START = Symbol(`indent start`);
|
275
386
|
const INDENT_END = Symbol(`indent end`);
|
387
|
+
let NewlineType = /* @__PURE__ */ function(NewlineType$1) {
|
388
|
+
/** Start with `\n` */
|
389
|
+
NewlineType$1[NewlineType$1["Start"] = 0] = "Start";
|
390
|
+
/** Ends with `\n` */
|
391
|
+
NewlineType$1[NewlineType$1["End"] = -1] = "End";
|
392
|
+
/** No `\n` included */
|
393
|
+
NewlineType$1[NewlineType$1["None"] = -2] = "None";
|
394
|
+
/** Don't know, calc it */
|
395
|
+
NewlineType$1[NewlineType$1["Unknown"] = -3] = "Unknown";
|
396
|
+
return NewlineType$1;
|
397
|
+
}({});
|
276
398
|
function buildCodeFragment(...frag) {
|
277
399
|
const push = frag.push.bind(frag);
|
278
400
|
const unshift = frag.unshift.bind(frag);
|
@@ -358,13 +480,13 @@ function codeFragmentToString(code, context) {
|
|
358
480
|
let codegen = "";
|
359
481
|
const pos = {
|
360
482
|
line: 1,
|
361
|
-
column:
|
362
|
-
|
483
|
+
column: 0,
|
484
|
+
index: 0
|
363
485
|
};
|
364
486
|
let indentLevel = 0;
|
365
487
|
for (let frag of code) {
|
366
488
|
if (!frag) continue;
|
367
|
-
if (frag === NEWLINE) frag = [`\n${` `.repeat(indentLevel)}`,
|
489
|
+
if (frag === NEWLINE) frag = [`\n${` `.repeat(indentLevel)}`, NewlineType.Start];
|
368
490
|
else if (frag === INDENT_START) {
|
369
491
|
indentLevel++;
|
370
492
|
continue;
|
@@ -373,21 +495,21 @@ function codeFragmentToString(code, context) {
|
|
373
495
|
continue;
|
374
496
|
}
|
375
497
|
if ((0, __vue_shared.isString)(frag)) frag = [frag];
|
376
|
-
let [code$1, newlineIndex =
|
498
|
+
let [code$1, newlineIndex = NewlineType.None, loc, name] = frag;
|
377
499
|
codegen += code$1;
|
378
500
|
if (map) {
|
379
501
|
if (loc) addMapping(loc.start, name);
|
380
|
-
if (newlineIndex ===
|
502
|
+
if (newlineIndex === NewlineType.Unknown) advancePositionWithMutation(pos, code$1);
|
381
503
|
else {
|
382
|
-
pos.
|
383
|
-
if (newlineIndex ===
|
504
|
+
pos.index += code$1.length;
|
505
|
+
if (newlineIndex === NewlineType.None) pos.column += code$1.length;
|
384
506
|
else {
|
385
|
-
if (newlineIndex ===
|
507
|
+
if (newlineIndex === NewlineType.End) newlineIndex = code$1.length - 1;
|
386
508
|
pos.line++;
|
387
509
|
pos.column = code$1.length - newlineIndex;
|
388
510
|
}
|
389
511
|
}
|
390
|
-
if (loc && loc !==
|
512
|
+
if (loc && loc !== locStub) addMapping(loc.end);
|
391
513
|
}
|
392
514
|
}
|
393
515
|
return [codegen, map];
|
@@ -396,7 +518,7 @@ function codeFragmentToString(code, context) {
|
|
396
518
|
if (name !== null && !_names.has(name)) _names.add(name);
|
397
519
|
_mappings.add({
|
398
520
|
originalLine: loc.line,
|
399
|
-
originalColumn: loc.column
|
521
|
+
originalColumn: loc.column,
|
400
522
|
generatedLine: pos.line,
|
401
523
|
generatedColumn: pos.column - 1,
|
402
524
|
source: filename,
|
@@ -404,22 +526,234 @@ function codeFragmentToString(code, context) {
|
|
404
526
|
});
|
405
527
|
}
|
406
528
|
}
|
529
|
+
function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
|
530
|
+
let linesCount = 0;
|
531
|
+
let lastNewLinePos = -1;
|
532
|
+
for (let i = 0; i < numberOfCharacters; i++) if (source.charCodeAt(i) === 10) {
|
533
|
+
linesCount++;
|
534
|
+
lastNewLinePos = i;
|
535
|
+
}
|
536
|
+
pos.index += numberOfCharacters;
|
537
|
+
pos.line += linesCount;
|
538
|
+
pos.column = lastNewLinePos === -1 ? pos.column + numberOfCharacters : numberOfCharacters - lastNewLinePos;
|
539
|
+
return pos;
|
540
|
+
}
|
541
|
+
function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
|
542
|
+
return advancePositionWithMutation({
|
543
|
+
index: pos.index,
|
544
|
+
line: pos.line,
|
545
|
+
column: pos.column
|
546
|
+
}, source, numberOfCharacters);
|
547
|
+
}
|
548
|
+
|
549
|
+
//#endregion
|
550
|
+
//#region src/utils/dom.ts
|
551
|
+
/**
|
552
|
+
* Copied from https://github.com/MananTank/validate-html-nesting
|
553
|
+
* with ISC license
|
554
|
+
*
|
555
|
+
* To avoid runtime dependency on validate-html-nesting
|
556
|
+
* This file should not change very often in the original repo
|
557
|
+
* but we may need to keep it up-to-date from time to time.
|
558
|
+
*/
|
559
|
+
/**
|
560
|
+
* returns true if given parent-child nesting is valid HTML
|
561
|
+
*/
|
562
|
+
function isValidHTMLNesting(parent, child) {
|
563
|
+
if (parent === "template") return true;
|
564
|
+
if (parent in onlyValidChildren) return onlyValidChildren[parent].has(child);
|
565
|
+
if (child in onlyValidParents) return onlyValidParents[child].has(parent);
|
566
|
+
if (parent in knownInvalidChildren && knownInvalidChildren[parent].has(child)) return false;
|
567
|
+
if (child in knownInvalidParents && knownInvalidParents[child].has(parent)) return false;
|
568
|
+
return true;
|
569
|
+
}
|
570
|
+
const headings = new Set([
|
571
|
+
"h1",
|
572
|
+
"h2",
|
573
|
+
"h3",
|
574
|
+
"h4",
|
575
|
+
"h5",
|
576
|
+
"h6"
|
577
|
+
]);
|
578
|
+
const emptySet = new Set([]);
|
579
|
+
/**
|
580
|
+
* maps element to set of elements that can be it's children, no other */
|
581
|
+
const onlyValidChildren = {
|
582
|
+
head: new Set([
|
583
|
+
"base",
|
584
|
+
"basefront",
|
585
|
+
"bgsound",
|
586
|
+
"link",
|
587
|
+
"meta",
|
588
|
+
"title",
|
589
|
+
"noscript",
|
590
|
+
"noframes",
|
591
|
+
"style",
|
592
|
+
"script",
|
593
|
+
"template"
|
594
|
+
]),
|
595
|
+
optgroup: new Set(["option"]),
|
596
|
+
select: new Set([
|
597
|
+
"optgroup",
|
598
|
+
"option",
|
599
|
+
"hr"
|
600
|
+
]),
|
601
|
+
table: new Set([
|
602
|
+
"caption",
|
603
|
+
"colgroup",
|
604
|
+
"tbody",
|
605
|
+
"tfoot",
|
606
|
+
"thead"
|
607
|
+
]),
|
608
|
+
tr: new Set(["td", "th"]),
|
609
|
+
colgroup: new Set(["col"]),
|
610
|
+
tbody: new Set(["tr"]),
|
611
|
+
thead: new Set(["tr"]),
|
612
|
+
tfoot: new Set(["tr"]),
|
613
|
+
script: emptySet,
|
614
|
+
iframe: emptySet,
|
615
|
+
option: emptySet,
|
616
|
+
textarea: emptySet,
|
617
|
+
style: emptySet,
|
618
|
+
title: emptySet
|
619
|
+
};
|
620
|
+
/** maps elements to set of elements which can be it's parent, no other */
|
621
|
+
const onlyValidParents = {
|
622
|
+
html: emptySet,
|
623
|
+
body: new Set(["html"]),
|
624
|
+
head: new Set(["html"]),
|
625
|
+
td: new Set(["tr"]),
|
626
|
+
colgroup: new Set(["table"]),
|
627
|
+
caption: new Set(["table"]),
|
628
|
+
tbody: new Set(["table"]),
|
629
|
+
tfoot: new Set(["table"]),
|
630
|
+
col: new Set(["colgroup"]),
|
631
|
+
th: new Set(["tr"]),
|
632
|
+
thead: new Set(["table"]),
|
633
|
+
tr: new Set([
|
634
|
+
"tbody",
|
635
|
+
"thead",
|
636
|
+
"tfoot"
|
637
|
+
]),
|
638
|
+
dd: new Set(["dl", "div"]),
|
639
|
+
dt: new Set(["dl", "div"]),
|
640
|
+
figcaption: new Set(["figure"]),
|
641
|
+
summary: new Set(["details"]),
|
642
|
+
area: new Set(["map"])
|
643
|
+
};
|
644
|
+
/** maps element to set of elements that can not be it's children, others can */
|
645
|
+
const knownInvalidChildren = {
|
646
|
+
p: new Set([
|
647
|
+
"address",
|
648
|
+
"article",
|
649
|
+
"aside",
|
650
|
+
"blockquote",
|
651
|
+
"center",
|
652
|
+
"details",
|
653
|
+
"dialog",
|
654
|
+
"dir",
|
655
|
+
"div",
|
656
|
+
"dl",
|
657
|
+
"fieldset",
|
658
|
+
"figure",
|
659
|
+
"footer",
|
660
|
+
"form",
|
661
|
+
"h1",
|
662
|
+
"h2",
|
663
|
+
"h3",
|
664
|
+
"h4",
|
665
|
+
"h5",
|
666
|
+
"h6",
|
667
|
+
"header",
|
668
|
+
"hgroup",
|
669
|
+
"hr",
|
670
|
+
"li",
|
671
|
+
"main",
|
672
|
+
"nav",
|
673
|
+
"menu",
|
674
|
+
"ol",
|
675
|
+
"p",
|
676
|
+
"pre",
|
677
|
+
"section",
|
678
|
+
"table",
|
679
|
+
"ul"
|
680
|
+
]),
|
681
|
+
svg: new Set([
|
682
|
+
"b",
|
683
|
+
"blockquote",
|
684
|
+
"br",
|
685
|
+
"code",
|
686
|
+
"dd",
|
687
|
+
"div",
|
688
|
+
"dl",
|
689
|
+
"dt",
|
690
|
+
"em",
|
691
|
+
"embed",
|
692
|
+
"h1",
|
693
|
+
"h2",
|
694
|
+
"h3",
|
695
|
+
"h4",
|
696
|
+
"h5",
|
697
|
+
"h6",
|
698
|
+
"hr",
|
699
|
+
"i",
|
700
|
+
"img",
|
701
|
+
"li",
|
702
|
+
"menu",
|
703
|
+
"meta",
|
704
|
+
"ol",
|
705
|
+
"p",
|
706
|
+
"pre",
|
707
|
+
"ruby",
|
708
|
+
"s",
|
709
|
+
"small",
|
710
|
+
"span",
|
711
|
+
"strong",
|
712
|
+
"sub",
|
713
|
+
"sup",
|
714
|
+
"table",
|
715
|
+
"u",
|
716
|
+
"ul",
|
717
|
+
"var"
|
718
|
+
])
|
719
|
+
};
|
720
|
+
/** maps element to set of elements that can not be it's parent, others can */
|
721
|
+
const knownInvalidParents = {
|
722
|
+
a: new Set(["a"]),
|
723
|
+
button: new Set(["button"]),
|
724
|
+
dd: new Set(["dd", "dt"]),
|
725
|
+
dt: new Set(["dd", "dt"]),
|
726
|
+
form: new Set(["form"]),
|
727
|
+
li: new Set(["li"]),
|
728
|
+
h1: headings,
|
729
|
+
h2: headings,
|
730
|
+
h3: headings,
|
731
|
+
h4: headings,
|
732
|
+
h5: headings,
|
733
|
+
h6: headings
|
734
|
+
};
|
735
|
+
function toValidAssetId(name, type) {
|
736
|
+
return `_${type}_${name.replaceAll(/\W/g, (searchValue, replaceValue) => {
|
737
|
+
return searchValue === "-" ? "_" : name.charCodeAt(replaceValue).toString();
|
738
|
+
})}`;
|
739
|
+
}
|
407
740
|
|
408
741
|
//#endregion
|
409
742
|
//#region src/generators/expression.ts
|
410
|
-
function genExpression(node, context, assignment) {
|
411
|
-
|
743
|
+
function genExpression(node, context, assignment, needWrap = false) {
|
744
|
+
let { content, ast, isStatic, loc } = node;
|
745
|
+
if (needWrap) content = `() => (${content})`;
|
412
746
|
if (isStatic) return [[
|
413
747
|
JSON.stringify(content),
|
414
|
-
|
748
|
+
NewlineType.None,
|
415
749
|
loc
|
416
750
|
]];
|
417
|
-
if (!node.content.trim() ||
|
751
|
+
if (!node.content.trim() || isConstantExpression(node)) return [[
|
418
752
|
content,
|
419
|
-
|
753
|
+
NewlineType.None,
|
420
754
|
loc
|
421
755
|
], assignment && ` = ${assignment}`];
|
422
|
-
if (ast
|
756
|
+
if (!ast) return genIdentifier(content, context, loc, assignment);
|
423
757
|
const ids = [];
|
424
758
|
const parentStackMap = /* @__PURE__ */ new Map();
|
425
759
|
const parentStack = [];
|
@@ -430,32 +764,33 @@ function genExpression(node, context, assignment) {
|
|
430
764
|
let hasMemberExpression = false;
|
431
765
|
if (ids.length) {
|
432
766
|
const [frag, push] = buildCodeFragment();
|
433
|
-
const isTSNode = ast &&
|
434
|
-
const offset = (ast?.start ? ast.start - 1 : 0) - (
|
767
|
+
const isTSNode = ast && TS_NODE_TYPES.includes(ast.type);
|
768
|
+
const offset = (ast?.start ? ast.start - 1 : 0) - (needWrap ? 7 : 0);
|
435
769
|
ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
|
436
770
|
const start = id.start - 1 - offset;
|
437
771
|
const end = id.end - 1 - offset;
|
438
772
|
const last = ids[i - 1];
|
439
773
|
if (!isTSNode || i !== 0) {
|
440
774
|
const leadingText = content.slice(last ? last.end - 1 - offset : 0, start);
|
441
|
-
if (leadingText.length) push([leadingText,
|
775
|
+
if (leadingText.length) push([leadingText, NewlineType.Unknown]);
|
442
776
|
}
|
443
777
|
const source = content.slice(start, end);
|
444
778
|
const parentStack$1 = parentStackMap.get(id);
|
445
779
|
const parent = parentStack$1.at(-1);
|
446
780
|
hasMemberExpression ||= !!parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression");
|
447
781
|
push(...genIdentifier(source, context, {
|
448
|
-
start:
|
449
|
-
end:
|
450
|
-
|
782
|
+
start: advancePositionWithClone(node.loc.start, source, start),
|
783
|
+
end: advancePositionWithClone(node.loc.start, source, end),
|
784
|
+
filename: "",
|
785
|
+
identifierName: void 0
|
451
786
|
}, hasMemberExpression ? void 0 : assignment, parent));
|
452
|
-
if (i === ids.length - 1 && end < content.length && !isTSNode) push([content.slice(end),
|
787
|
+
if (i === ids.length - 1 && end < content.length && !isTSNode) push([content.slice(end), NewlineType.Unknown]);
|
453
788
|
});
|
454
789
|
if (assignment && hasMemberExpression) push(` = ${assignment}`);
|
455
790
|
return frag;
|
456
791
|
} else return [[
|
457
792
|
content,
|
458
|
-
|
793
|
+
NewlineType.Unknown,
|
459
794
|
loc
|
460
795
|
]];
|
461
796
|
}
|
@@ -467,22 +802,22 @@ function genIdentifier(raw, context, loc, assignment, parent) {
|
|
467
802
|
const replacement = idMap[0];
|
468
803
|
if ((0, __vue_shared.isString)(replacement)) if (parent && parent.type === "ObjectProperty" && parent.shorthand) return [[
|
469
804
|
`${name}: ${replacement}`,
|
470
|
-
|
805
|
+
NewlineType.None,
|
471
806
|
loc
|
472
807
|
]];
|
473
808
|
else return [[
|
474
809
|
replacement,
|
475
|
-
|
810
|
+
NewlineType.None,
|
476
811
|
loc
|
477
812
|
]];
|
478
813
|
else return genExpression(replacement, context, assignment);
|
479
814
|
}
|
480
815
|
let prefix;
|
481
|
-
if (
|
816
|
+
if (isStaticProperty(parent) && parent.shorthand) prefix = `${raw}: `;
|
482
817
|
raw = withAssignment(raw);
|
483
818
|
return [prefix, [
|
484
819
|
raw,
|
485
|
-
|
820
|
+
NewlineType.None,
|
486
821
|
loc,
|
487
822
|
name
|
488
823
|
]];
|
@@ -510,7 +845,7 @@ function genVModel(oper, context) {
|
|
510
845
|
}
|
511
846
|
function genModelHandler(exp, context) {
|
512
847
|
return [
|
513
|
-
|
848
|
+
"_value => (",
|
514
849
|
...genExpression(exp, context, "_value"),
|
515
850
|
")"
|
516
851
|
];
|
@@ -551,7 +886,7 @@ function genCustomDirectives(opers, context) {
|
|
551
886
|
const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems);
|
552
887
|
return [NEWLINE, ...genCall(helper("withVaporDirectives"), element, directives)];
|
553
888
|
function genDirectiveItem({ dir, name, asset }) {
|
554
|
-
const directiveVar = asset ?
|
889
|
+
const directiveVar = asset ? toValidAssetId(name, "directive") : genExpression(createSimpleExpression(name), context);
|
555
890
|
const value = dir.exp && ["() => ", ...genExpression(dir.exp, context)];
|
556
891
|
const argument = dir.arg && genExpression(dir.arg, context);
|
557
892
|
const modifiers = !!dir.modifiers.length && [
|
@@ -563,7 +898,7 @@ function genCustomDirectives(opers, context) {
|
|
563
898
|
}
|
564
899
|
}
|
565
900
|
function genDirectiveModifiers(modifiers) {
|
566
|
-
return modifiers.map((value) => `${
|
901
|
+
return modifiers.map((value) => `${isSimpleIdentifier(value) ? value : JSON.stringify(value)}: true`).join(", ");
|
567
902
|
}
|
568
903
|
function filterCustomDirectives(id, operations) {
|
569
904
|
return operations.filter((oper) => oper.type === IRNodeTypes.DIRECTIVE && oper.element === id && !oper.builtin);
|
@@ -621,22 +956,20 @@ function genEventHandler(context, value, modifiers = {
|
|
621
956
|
keys: []
|
622
957
|
}, extraWrap = false) {
|
623
958
|
let handlerExp = [`() => {}`];
|
624
|
-
if (value && value.content.trim()) if (
|
959
|
+
if (value && value.content.trim()) if (isMemberExpression(value)) {
|
625
960
|
handlerExp = genExpression(value, context);
|
626
961
|
if (!extraWrap) handlerExp = [
|
627
962
|
`e => `,
|
628
963
|
...handlerExp,
|
629
964
|
`(e)`
|
630
965
|
];
|
631
|
-
} else if (
|
966
|
+
} else if (isFnExpression(value)) handlerExp = genExpression(value, context);
|
632
967
|
else {
|
633
|
-
const referencesEvent = value.content.includes("$event");
|
634
968
|
const hasMultipleStatements = value.content.includes(`;`);
|
635
|
-
const expr = referencesEvent ? context.withId(() => genExpression(value, context), { $event: null }) : genExpression(value, context);
|
636
969
|
handlerExp = [
|
637
|
-
|
970
|
+
"() => ",
|
638
971
|
hasMultipleStatements ? "{" : "(",
|
639
|
-
...
|
972
|
+
...genExpression(value, context),
|
640
973
|
hasMultipleStatements ? "}" : ")"
|
641
974
|
];
|
642
975
|
}
|
@@ -700,8 +1033,8 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
|
|
700
1033
|
if (node.isStatic) {
|
701
1034
|
const keyName = (handler ? (0, __vue_shared.toHandlerKey)(node.content) : node.content) + handlerModifierPostfix;
|
702
1035
|
return [[
|
703
|
-
|
704
|
-
|
1036
|
+
isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
|
1037
|
+
NewlineType.None,
|
705
1038
|
node.loc
|
706
1039
|
]];
|
707
1040
|
}
|
@@ -760,8 +1093,8 @@ function genCreateComponent(operation, context) {
|
|
760
1093
|
...genExpression(operation.dynamic, context),
|
761
1094
|
")"
|
762
1095
|
];
|
763
|
-
else if (operation.asset) return
|
764
|
-
else return genExpression(
|
1096
|
+
else if (operation.asset) return toValidAssetId(operation.tag, "component");
|
1097
|
+
else return genExpression(createSimpleExpression(operation.tag), context);
|
765
1098
|
}
|
766
1099
|
}
|
767
1100
|
function genRawProps(props, context) {
|
@@ -930,8 +1263,8 @@ function genSlotBlockWithProps(oper, context) {
|
|
930
1263
|
if (isDestructureAssignment = !!props.ast) {
|
931
1264
|
[depth, exitScope] = context.enterScope();
|
932
1265
|
propsName = `_slotProps${depth}`;
|
933
|
-
(0, ast_kit.walkIdentifiers)(props.ast, (id, _, __,
|
934
|
-
if (isLocal) idsOfProps.add(id.name);
|
1266
|
+
(0, ast_kit.walkIdentifiers)(props.ast, (id, _, __, isReference, isLocal) => {
|
1267
|
+
if (isReference && !isLocal) idsOfProps.add(id.name);
|
935
1268
|
}, true);
|
936
1269
|
} else idsOfProps.add(propsName = rawProps);
|
937
1270
|
}
|
@@ -1000,9 +1333,8 @@ function genFor(oper, context) {
|
|
1000
1333
|
path = `${pathInfo.helper}(${path}, ${pathInfo.helperArgs})`;
|
1001
1334
|
}
|
1002
1335
|
if (pathInfo.dynamic) {
|
1003
|
-
const node = idMap[id$1] =
|
1004
|
-
|
1005
|
-
node.ast = (0, __babel_parser.parseExpression)(`(${path})`, { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] });
|
1336
|
+
const node = idMap[id$1] = createSimpleExpression(path);
|
1337
|
+
node.ast = (0, __babel_parser.parseExpression)(`(${path})`, { plugins: context.options.expressionPlugins });
|
1006
1338
|
} else idMap[id$1] = path;
|
1007
1339
|
} else idMap[id$1] = path;
|
1008
1340
|
});
|
@@ -1019,7 +1351,7 @@ function genFor(oper, context) {
|
|
1019
1351
|
idMap[rawIndex] = `${indexVar}.value`;
|
1020
1352
|
idMap[indexVar] = null;
|
1021
1353
|
}
|
1022
|
-
const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
|
1354
|
+
const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap, context.ir.source);
|
1023
1355
|
const selectorDeclarations = [];
|
1024
1356
|
const selectorSetup = [];
|
1025
1357
|
for (const [i, { selector }] of selectorPatterns.entries()) {
|
@@ -1061,8 +1393,8 @@ function genFor(oper, context) {
|
|
1061
1393
|
const map = /* @__PURE__ */ new Map();
|
1062
1394
|
if (value) {
|
1063
1395
|
rawValue = value && value.content;
|
1064
|
-
if (value.ast) (0,
|
1065
|
-
if (isLocal) {
|
1396
|
+
if (value.ast && value.ast.type !== "Identifier") (0, ast_kit.walkIdentifiers)(value.ast, (id$1, _, parentStack, isReference, isLocal) => {
|
1397
|
+
if (isReference && !isLocal) {
|
1066
1398
|
let path = "";
|
1067
1399
|
let isDynamic = false;
|
1068
1400
|
let helper$1;
|
@@ -1075,11 +1407,11 @@ function genFor(oper, context) {
|
|
1075
1407
|
isDynamic = true;
|
1076
1408
|
path += `[${value.content.slice(parent.key.start - 1, parent.key.end - 1)}]`;
|
1077
1409
|
} else path += `.${parent.key.name}`;
|
1078
|
-
else if (parent.type === "
|
1410
|
+
else if (parent.type === "ArrayExpression") {
|
1079
1411
|
const index$1 = parent.elements.indexOf(child);
|
1080
|
-
if (child.type === "
|
1412
|
+
if (child.type === "SpreadElement") path += `.slice(${index$1})`;
|
1081
1413
|
else path += `[${index$1}]`;
|
1082
|
-
} else if (parent.type === "
|
1414
|
+
} else if (parent.type === "ObjectExpression" && child.type === "SpreadElement") {
|
1083
1415
|
helper$1 = context.helper("getRestElement");
|
1084
1416
|
helperArgs = `[${parent.properties.filter((p) => p.type === "ObjectProperty").map((p) => {
|
1085
1417
|
if (p.key.type === "StringLiteral") return JSON.stringify(p.key.value);
|
@@ -1089,11 +1421,6 @@ function genFor(oper, context) {
|
|
1089
1421
|
} else return JSON.stringify(p.key.name);
|
1090
1422
|
}).join(", ")}]`;
|
1091
1423
|
}
|
1092
|
-
if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
|
1093
|
-
isDynamic = true;
|
1094
|
-
helper$1 = context.helper("getDefaultValue");
|
1095
|
-
helperArgs = value.content.slice(child.right.start - 1, child.right.end - 1);
|
1096
|
-
}
|
1097
1424
|
}
|
1098
1425
|
map.set(id$1.name, {
|
1099
1426
|
path,
|
@@ -1129,17 +1456,17 @@ function genFor(oper, context) {
|
|
1129
1456
|
return idMap$1;
|
1130
1457
|
}
|
1131
1458
|
}
|
1132
|
-
function matchPatterns(render, keyProp, idMap) {
|
1459
|
+
function matchPatterns(render, keyProp, idMap, source) {
|
1133
1460
|
const selectorPatterns = [];
|
1134
1461
|
const keyOnlyBindingPatterns = [];
|
1135
1462
|
render.effect = render.effect.filter((effect) => {
|
1136
1463
|
if (keyProp !== void 0) {
|
1137
|
-
const selector = matchSelectorPattern(effect, keyProp.
|
1464
|
+
const selector = matchSelectorPattern(effect, keyProp.content, idMap, source);
|
1138
1465
|
if (selector) {
|
1139
1466
|
selectorPatterns.push(selector);
|
1140
1467
|
return false;
|
1141
1468
|
}
|
1142
|
-
const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.
|
1469
|
+
const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content, source);
|
1143
1470
|
if (keyOnly) {
|
1144
1471
|
keyOnlyBindingPatterns.push(keyOnly);
|
1145
1472
|
return false;
|
@@ -1152,37 +1479,37 @@ function matchPatterns(render, keyProp, idMap) {
|
|
1152
1479
|
selectorPatterns
|
1153
1480
|
};
|
1154
1481
|
}
|
1155
|
-
function matchKeyOnlyBindingPattern(effect,
|
1482
|
+
function matchKeyOnlyBindingPattern(effect, key, source) {
|
1156
1483
|
if (effect.expressions.length === 1) {
|
1157
1484
|
const ast = effect.expressions[0].ast;
|
1158
|
-
if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast,
|
1485
|
+
if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, key, source)) return { effect };
|
1159
1486
|
}
|
1160
1487
|
}
|
1161
|
-
function matchSelectorPattern(effect,
|
1488
|
+
function matchSelectorPattern(effect, key, idMap, source) {
|
1162
1489
|
if (effect.expressions.length === 1) {
|
1163
1490
|
const ast = effect.expressions[0].ast;
|
1164
|
-
const offset = effect.expressions[0].loc.start.
|
1491
|
+
const offset = effect.expressions[0].loc.start.index;
|
1165
1492
|
if (typeof ast === "object" && ast) {
|
1166
1493
|
const matcheds = [];
|
1167
1494
|
(0, ast_kit.walkAST)(ast, { enter(node) {
|
1168
1495
|
if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
|
1169
1496
|
const { left, right } = node;
|
1170
1497
|
for (const [a, b] of [[left, right], [right, left]]) {
|
1171
|
-
const aIsKey = isKeyOnlyBinding(a,
|
1172
|
-
const bIsKey = isKeyOnlyBinding(b,
|
1498
|
+
const aIsKey = isKeyOnlyBinding(a, key, source);
|
1499
|
+
const bIsKey = isKeyOnlyBinding(b, key, source);
|
1173
1500
|
const bVars = analyzeVariableScopes(b, idMap);
|
1174
1501
|
if (aIsKey && !bIsKey && !bVars.locals.length) matcheds.push([a, b]);
|
1175
1502
|
}
|
1176
1503
|
}
|
1177
1504
|
} });
|
1178
1505
|
if (matcheds.length === 1) {
|
1179
|
-
const [key, selector] = matcheds[0];
|
1506
|
+
const [key$1, selector] = matcheds[0];
|
1180
1507
|
const content$1 = effect.expressions[0].content;
|
1181
1508
|
let hasExtraId = false;
|
1182
1509
|
const parentStackMap = /* @__PURE__ */ new Map();
|
1183
1510
|
const parentStack = [];
|
1184
|
-
(0,
|
1185
|
-
if (id.start !== key.start && id.start !== selector.start) hasExtraId = true;
|
1511
|
+
(0, ast_kit.walkIdentifiers)(ast, (id) => {
|
1512
|
+
if (id.start !== key$1.start && id.start !== selector.start) hasExtraId = true;
|
1186
1513
|
parentStackMap.set(id, parentStack.slice());
|
1187
1514
|
}, false, parentStack);
|
1188
1515
|
if (!hasExtraId) {
|
@@ -1203,12 +1530,12 @@ function matchSelectorPattern(effect, keyAst, idMap) {
|
|
1203
1530
|
}
|
1204
1531
|
}
|
1205
1532
|
const content = effect.expressions[0].content;
|
1206
|
-
if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" &&
|
1533
|
+
if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && isConstantNode(ast.consequent) && isConstantNode(ast.alternate)) {
|
1207
1534
|
const left = ast.test.left;
|
1208
1535
|
const right = ast.test.right;
|
1209
1536
|
for (const [a, b] of [[left, right], [right, left]]) {
|
1210
|
-
const aIsKey = isKeyOnlyBinding(a,
|
1211
|
-
const bIsKey = isKeyOnlyBinding(b,
|
1537
|
+
const aIsKey = isKeyOnlyBinding(a, key, source);
|
1538
|
+
const bIsKey = isKeyOnlyBinding(b, key, source);
|
1212
1539
|
const bVars = analyzeVariableScopes(b, idMap);
|
1213
1540
|
if (aIsKey && !bIsKey && !bVars.locals.length) return {
|
1214
1541
|
effect,
|
@@ -1229,7 +1556,7 @@ function analyzeVariableScopes(ast, idMap) {
|
|
1229
1556
|
const ids = [];
|
1230
1557
|
const parentStackMap = /* @__PURE__ */ new Map();
|
1231
1558
|
const parentStack = [];
|
1232
|
-
(0,
|
1559
|
+
(0, ast_kit.walkIdentifiers)(ast, (id) => {
|
1233
1560
|
ids.push(id);
|
1234
1561
|
parentStackMap.set(id, parentStack.slice());
|
1235
1562
|
}, false, parentStack);
|
@@ -1243,10 +1570,10 @@ function analyzeVariableScopes(ast, idMap) {
|
|
1243
1570
|
locals
|
1244
1571
|
};
|
1245
1572
|
}
|
1246
|
-
function isKeyOnlyBinding(expr,
|
1573
|
+
function isKeyOnlyBinding(expr, key, source) {
|
1247
1574
|
let only = true;
|
1248
1575
|
(0, ast_kit.walkAST)(expr, { enter(node) {
|
1249
|
-
if ((
|
1576
|
+
if (source.slice(node.start, node.end) === key) {
|
1250
1577
|
this.skip();
|
1251
1578
|
return;
|
1252
1579
|
}
|
@@ -1302,7 +1629,7 @@ function genDeclareOldRef(oper) {
|
|
1302
1629
|
function genSetText(oper, context) {
|
1303
1630
|
const { helper } = context;
|
1304
1631
|
const { element, values, generated } = oper;
|
1305
|
-
const texts = combineValues(values, context, true);
|
1632
|
+
const texts = combineValues(values, context, true, true);
|
1306
1633
|
return [NEWLINE, ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)];
|
1307
1634
|
}
|
1308
1635
|
function genGetTextChild(oper, context) {
|
@@ -1310,21 +1637,22 @@ function genGetTextChild(oper, context) {
|
|
1310
1637
|
}
|
1311
1638
|
function genSetNodes(oper, context) {
|
1312
1639
|
const { helper } = context;
|
1313
|
-
const { element, values, generated } = oper;
|
1314
|
-
return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context))];
|
1640
|
+
const { element, values, generated, once } = oper;
|
1641
|
+
return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context, once))];
|
1315
1642
|
}
|
1316
1643
|
function genCreateNodes(oper, context) {
|
1317
1644
|
const { helper } = context;
|
1318
|
-
const { id, values } = oper;
|
1645
|
+
const { id, values, once } = oper;
|
1319
1646
|
return [
|
1320
1647
|
NEWLINE,
|
1321
1648
|
`const n${id} = `,
|
1322
|
-
...genCall(helper("createNodes"), values && combineValues(values, context))
|
1649
|
+
...genCall(helper("createNodes"), values && combineValues(values, context, once))
|
1323
1650
|
];
|
1324
1651
|
}
|
1325
|
-
function combineValues(values, context, setText) {
|
1652
|
+
function combineValues(values, context, once, setText) {
|
1326
1653
|
return values.flatMap((value, i) => {
|
1327
|
-
|
1654
|
+
const { content, isStatic, ast } = value;
|
1655
|
+
let exp = genExpression(value, context, void 0, !once && !setText && !!content && !isStatic && !!ast && !isConstantNode(ast));
|
1328
1656
|
if (setText && getLiteralExpressionValue(value) == null) exp = genCall(context.helper("toDisplayString"), exp);
|
1329
1657
|
if (i > 0) exp.unshift(setText ? " + " : ", ");
|
1330
1658
|
return exp;
|
@@ -1474,7 +1802,7 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
|
1474
1802
|
const resetBlock = context.enterBlock(block);
|
1475
1803
|
if (root) {
|
1476
1804
|
for (let name of context.ir.component) {
|
1477
|
-
const id =
|
1805
|
+
const id = toValidAssetId(name, "component");
|
1478
1806
|
const maybeSelfReference = name.endsWith("__self");
|
1479
1807
|
if (maybeSelfReference) name = name.slice(0, -6);
|
1480
1808
|
push(NEWLINE, `const ${id} = `, ...genCall(context.helper("resolveComponent"), JSON.stringify(name), maybeSelfReference ? "true" : void 0));
|
@@ -1492,7 +1820,7 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
|
1492
1820
|
resetBlock();
|
1493
1821
|
return frag;
|
1494
1822
|
function genResolveAssets(kind, helper) {
|
1495
|
-
for (const name of context.ir[kind]) push(NEWLINE, `const ${
|
1823
|
+
for (const name of context.ir[kind]) push(NEWLINE, `const ${toValidAssetId(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name)));
|
1496
1824
|
}
|
1497
1825
|
}
|
1498
1826
|
|
@@ -1531,18 +1859,10 @@ var CodegenContext = class {
|
|
1531
1859
|
constructor(ir, options) {
|
1532
1860
|
this.ir = ir;
|
1533
1861
|
const defaultOptions$1 = {
|
1534
|
-
mode: "module",
|
1535
1862
|
sourceMap: false,
|
1536
|
-
filename: `
|
1537
|
-
|
1538
|
-
|
1539
|
-
runtimeModuleName: `vue`,
|
1540
|
-
ssrRuntimeModuleName: "vue/server-renderer",
|
1541
|
-
ssr: false,
|
1542
|
-
isTS: false,
|
1543
|
-
inSSR: false,
|
1544
|
-
templates: [],
|
1545
|
-
expressionPlugins: []
|
1863
|
+
filename: `index.jsx`,
|
1864
|
+
expressionPlugins: ["jsx"],
|
1865
|
+
templates: []
|
1546
1866
|
};
|
1547
1867
|
this.options = (0, __vue_shared.extend)(defaultOptions$1, options);
|
1548
1868
|
this.block = ir.block;
|
@@ -1573,26 +1893,18 @@ function generate(ir, options = {}) {
|
|
1573
1893
|
//#region src/transform.ts
|
1574
1894
|
const defaultOptions = {
|
1575
1895
|
source: "",
|
1576
|
-
|
1577
|
-
|
1578
|
-
hmr: false,
|
1579
|
-
cacheHandlers: false,
|
1896
|
+
sourceMap: false,
|
1897
|
+
filename: "index.jsx",
|
1580
1898
|
nodeTransforms: [],
|
1581
1899
|
directiveTransforms: {},
|
1582
1900
|
templates: [],
|
1583
|
-
transformHoist: null,
|
1584
|
-
isBuiltInComponent: __vue_shared.NOOP,
|
1585
1901
|
isCustomElement: __vue_shared.NOOP,
|
1586
1902
|
expressionPlugins: [],
|
1587
|
-
scopeId: null,
|
1588
|
-
slotted: true,
|
1589
|
-
ssr: false,
|
1590
|
-
inSSR: false,
|
1591
|
-
ssrCssVars: ``,
|
1592
1903
|
isTS: false,
|
1593
1904
|
withFallback: false,
|
1594
|
-
onError:
|
1595
|
-
|
1905
|
+
onError: (error) => {
|
1906
|
+
throw error;
|
1907
|
+
}
|
1596
1908
|
};
|
1597
1909
|
var TransformContext = class TransformContext {
|
1598
1910
|
parent = null;
|
@@ -1605,7 +1917,6 @@ var TransformContext = class TransformContext {
|
|
1605
1917
|
dynamic;
|
1606
1918
|
inVOnce = false;
|
1607
1919
|
inVFor = 0;
|
1608
|
-
comment = [];
|
1609
1920
|
component;
|
1610
1921
|
directive;
|
1611
1922
|
slots = [];
|
@@ -1658,7 +1969,7 @@ var TransformContext = class TransformContext {
|
|
1658
1969
|
registerEffect(expressions, operation, getEffectIndex = () => this.block.effect.length, getOperationIndex = () => this.block.operation.length) {
|
1659
1970
|
const operations = [operation].flat();
|
1660
1971
|
expressions = expressions.filter((exp) => !isConstantExpression(exp));
|
1661
|
-
if (this.inVOnce || expressions.length === 0 || expressions.every((e) => e.ast &&
|
1972
|
+
if (this.inVOnce || expressions.length === 0 || expressions.every((e) => e.ast && isConstantNode(e.ast))) return this.registerOperation(operations, getOperationIndex);
|
1662
1973
|
this.block.effect.splice(getEffectIndex(), 0, {
|
1663
1974
|
expressions,
|
1664
1975
|
operations
|
@@ -1830,10 +2141,8 @@ function transformComponentElement(tag, propsResult, singleRoot, context) {
|
|
1830
2141
|
context.slots = [];
|
1831
2142
|
}
|
1832
2143
|
function transformNativeElement(tag, propsResult, singleRoot, context, getEffectIndex, getOperationIndex) {
|
1833
|
-
const { scopeId } = context.options;
|
1834
2144
|
let template = "";
|
1835
2145
|
template += `<${tag}`;
|
1836
|
-
if (scopeId) template += ` ${scopeId}`;
|
1837
2146
|
const dynamicProps = [];
|
1838
2147
|
if (propsResult[0]) {
|
1839
2148
|
const [, dynamicArgs, expressions] = propsResult;
|
@@ -1862,7 +2171,7 @@ function transformNativeElement(tag, propsResult, singleRoot, context, getEffect
|
|
1862
2171
|
template += `>${context.childrenTemplate.join("")}`;
|
1863
2172
|
if (!(0, __vue_shared.isVoidTag)(tag)) template += `</${tag}>`;
|
1864
2173
|
if (singleRoot) context.ir.rootTemplateIndex = context.ir.templates.length;
|
1865
|
-
if (context.parent && context.parent.node.type === "JSXElement" && context.parent.node.openingElement.name.type === "JSXIdentifier" && !
|
2174
|
+
if (context.parent && context.parent.node.type === "JSXElement" && context.parent.node.openingElement.name.type === "JSXIdentifier" && !isValidHTMLNesting(context.parent.node.openingElement.name.name, tag)) {
|
1866
2175
|
context.reference();
|
1867
2176
|
context.dynamic.template = context.pushTemplate(template);
|
1868
2177
|
context.dynamic.flags |= DynamicFlag.INSERT | DynamicFlag.NON_TEMPLATE;
|
@@ -1891,7 +2200,7 @@ function buildProps(node, context, isComponent) {
|
|
1891
2200
|
});
|
1892
2201
|
continue;
|
1893
2202
|
}
|
1894
|
-
const result = transformProp(prop, node, context);
|
2203
|
+
const result = transformProp(prop, node, isComponent, context);
|
1895
2204
|
if (result) {
|
1896
2205
|
dynamicExpr.push(result.key, result.value);
|
1897
2206
|
if (isComponent && !result.key.isStatic) {
|
@@ -1911,15 +2220,16 @@ function buildProps(node, context, isComponent) {
|
|
1911
2220
|
const irProps = dedupeProperties(results);
|
1912
2221
|
return [false, irProps];
|
1913
2222
|
}
|
1914
|
-
function transformProp(prop, node, context) {
|
2223
|
+
function transformProp(prop, node, isComponent, context) {
|
1915
2224
|
if (prop.type === "JSXSpreadAttribute") return;
|
1916
2225
|
let name = prop.name.type === "JSXIdentifier" ? prop.name.name : prop.name.type === "JSXNamespacedName" ? prop.name.namespace.name : "";
|
1917
2226
|
name = name.split("_")[0];
|
1918
|
-
|
2227
|
+
let value;
|
2228
|
+
if (!isDirectiveRegex.test(name) && !isEventRegex.test(name) && (!prop.value || (value = getTextLikeValue(prop.value, isComponent)) != null)) {
|
1919
2229
|
if (isReservedProp(name)) return;
|
1920
2230
|
return {
|
1921
|
-
key:
|
1922
|
-
value: prop.value
|
2231
|
+
key: createSimpleExpression(name, true, prop.name),
|
2232
|
+
value: prop.value ? createSimpleExpression(value, true, prop.value) : createSimpleExpression("true")
|
1923
2233
|
};
|
1924
2234
|
}
|
1925
2235
|
name = isEventRegex.test(name) ? "on" : isDirectiveRegex.test(name) ? name.slice(2) : "bind";
|
@@ -2000,7 +2310,7 @@ function processConditionalExpression(node, context) {
|
|
2000
2310
|
id,
|
2001
2311
|
condition,
|
2002
2312
|
positive: branch,
|
2003
|
-
once: context.inVOnce ||
|
2313
|
+
once: context.inVOnce || isConstantNode(test)
|
2004
2314
|
};
|
2005
2315
|
return [() => {
|
2006
2316
|
onExit();
|
@@ -2066,7 +2376,7 @@ const transformText = (node, context) => {
|
|
2066
2376
|
else processInterpolation(context);
|
2067
2377
|
else if (node.type === "JSXText") {
|
2068
2378
|
const value = resolveJSXText(node);
|
2069
|
-
if (value) context.template += value;
|
2379
|
+
if (value) context.template += (0, __vue_shared.escapeHtml)(value);
|
2070
2380
|
else context.dynamic.flags |= DynamicFlag.NON_TEMPLATE;
|
2071
2381
|
}
|
2072
2382
|
};
|
@@ -2087,6 +2397,7 @@ function processInterpolation(context) {
|
|
2087
2397
|
if (isFragmentNode(parent) || findProp(parent, "v-slot")) context.registerOperation({
|
2088
2398
|
type: IRNodeTypes.CREATE_NODES,
|
2089
2399
|
id,
|
2400
|
+
once: context.inVOnce,
|
2090
2401
|
values
|
2091
2402
|
});
|
2092
2403
|
else {
|
@@ -2094,6 +2405,7 @@ function processInterpolation(context) {
|
|
2094
2405
|
context.registerOperation({
|
2095
2406
|
type: IRNodeTypes.SET_NODES,
|
2096
2407
|
element: id,
|
2408
|
+
once: context.inVOnce,
|
2097
2409
|
values
|
2098
2410
|
});
|
2099
2411
|
}
|
@@ -2101,7 +2413,7 @@ function processInterpolation(context) {
|
|
2101
2413
|
function processTextContainer(children, context) {
|
2102
2414
|
const values = createTextLikeExpressions(children, context);
|
2103
2415
|
const literals = values.map(getLiteralExpressionValue);
|
2104
|
-
if (literals.every((l) => l != null)) context.childrenTemplate = literals
|
2416
|
+
if (literals.every((l) => l != null)) context.childrenTemplate = literals;
|
2105
2417
|
else {
|
2106
2418
|
context.childrenTemplate = [" "];
|
2107
2419
|
context.registerOperation({
|
@@ -2111,6 +2423,7 @@ function processTextContainer(children, context) {
|
|
2111
2423
|
context.registerOperation({
|
2112
2424
|
type: IRNodeTypes.SET_NODES,
|
2113
2425
|
element: context.reference(),
|
2426
|
+
once: context.inVOnce,
|
2114
2427
|
values,
|
2115
2428
|
generated: true
|
2116
2429
|
});
|
@@ -2121,7 +2434,7 @@ function createTextLikeExpressions(nodes, context) {
|
|
2121
2434
|
for (const node of nodes) {
|
2122
2435
|
markNonTemplate(node, context);
|
2123
2436
|
if (isEmptyText(node)) continue;
|
2124
|
-
values.push(resolveExpression(node, context
|
2437
|
+
values.push(resolveExpression(node, context));
|
2125
2438
|
}
|
2126
2439
|
return values;
|
2127
2440
|
}
|
@@ -2136,7 +2449,7 @@ const transformVBind = (dir, node, context) => {
|
|
2136
2449
|
if (!loc || name.type === "JSXNamespacedName") return;
|
2137
2450
|
const [nameString, ...modifiers] = name.name.split("_");
|
2138
2451
|
const exp = resolveExpression(value, context);
|
2139
|
-
let arg =
|
2452
|
+
let arg = createSimpleExpression(nameString, true, dir.name);
|
2140
2453
|
if (arg.isStatic && isReservedProp(arg.content)) return;
|
2141
2454
|
let camel = false;
|
2142
2455
|
if (modifiers.includes("camel")) if (arg.isStatic) arg = (0, __vue_shared.extend)({}, arg, { content: (0, __vue_shared.camelize)(arg.content) });
|
@@ -2156,12 +2469,12 @@ const transformVFor = createStructuralDirectiveTransform("for", processFor);
|
|
2156
2469
|
function processFor(node, dir, context) {
|
2157
2470
|
const { value, index, key, source } = getForParseResult(dir, context);
|
2158
2471
|
if (!source) {
|
2159
|
-
context.options.onError(
|
2472
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION, dir.loc));
|
2160
2473
|
return;
|
2161
2474
|
}
|
2162
2475
|
const keyProp = findProp(node, "key");
|
2163
2476
|
const keyProperty = keyProp && propToExpression(keyProp, context);
|
2164
|
-
const isComponent = isJSXComponent(node);
|
2477
|
+
const isComponent = isJSXComponent(node) || isTemplateWithSingleComponent(node);
|
2165
2478
|
const id = context.reference();
|
2166
2479
|
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT;
|
2167
2480
|
const [render, exitBlock] = createBranch(node, context, true);
|
@@ -2178,7 +2491,7 @@ function processFor(node, dir, context) {
|
|
2178
2491
|
index,
|
2179
2492
|
keyProp: keyProperty,
|
2180
2493
|
render,
|
2181
|
-
once: context.inVOnce || !!(source.ast &&
|
2494
|
+
once: context.inVOnce || !!(source.ast && isConstantNode(source.ast)),
|
2182
2495
|
component: isComponent,
|
2183
2496
|
onlyChild: !!isOnlyChild
|
2184
2497
|
};
|
@@ -2190,13 +2503,13 @@ function getForParseResult(dir, context) {
|
|
2190
2503
|
if (dir.value.type === "JSXExpressionContainer" && dir.value.expression.type === "BinaryExpression") {
|
2191
2504
|
if (dir.value.expression.left.type === "SequenceExpression") {
|
2192
2505
|
const expressions = dir.value.expression.left.expressions;
|
2193
|
-
value = expressions[0] &&
|
2506
|
+
value = expressions[0] && resolveExpression(expressions[0], context);
|
2194
2507
|
key = expressions[1] && resolveExpression(expressions[1], context);
|
2195
2508
|
index = expressions[2] && resolveExpression(expressions[2], context);
|
2196
|
-
} else value =
|
2509
|
+
} else value = resolveExpression(dir.value.expression.left, context);
|
2197
2510
|
source = resolveExpression(dir.value.expression.right, context);
|
2198
2511
|
}
|
2199
|
-
} else context.options.onError(
|
2512
|
+
} else context.options.onError(createCompilerError(ErrorCodes.X_V_FOR_NO_EXPRESSION, dir.loc));
|
2200
2513
|
return {
|
2201
2514
|
value,
|
2202
2515
|
index,
|
@@ -2204,18 +2517,21 @@ function getForParseResult(dir, context) {
|
|
2204
2517
|
source
|
2205
2518
|
};
|
2206
2519
|
}
|
2520
|
+
function isTemplateWithSingleComponent(node) {
|
2521
|
+
const nonCommentChildren = node.children.filter((c) => !isEmptyText(c));
|
2522
|
+
return nonCommentChildren.length === 1 && isJSXComponent(nonCommentChildren[0]);
|
2523
|
+
}
|
2207
2524
|
|
2208
2525
|
//#endregion
|
2209
2526
|
//#region src/transforms/vHtml.ts
|
2210
2527
|
const transformVHtml = (dir, node, context) => {
|
2211
2528
|
let exp;
|
2212
|
-
const loc = resolveLocation(dir.loc, context);
|
2213
2529
|
if (!dir.value) {
|
2214
|
-
context.options.onError((
|
2530
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_HTML_NO_EXPRESSION, dir.loc));
|
2215
2531
|
exp = EMPTY_EXPRESSION;
|
2216
2532
|
} else exp = resolveExpression(dir.value, context);
|
2217
2533
|
if (node.children.length) {
|
2218
|
-
context.options.onError((
|
2534
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_HTML_WITH_CHILDREN, dir.loc));
|
2219
2535
|
context.childrenTemplate.length = 0;
|
2220
2536
|
}
|
2221
2537
|
context.registerEffect([exp], {
|
@@ -2236,9 +2552,8 @@ const transformedIfNode = /* @__PURE__ */ new WeakMap();
|
|
2236
2552
|
function processIf(node, attribute, context) {
|
2237
2553
|
const dir = resolveDirective(attribute, context);
|
2238
2554
|
if (dir.name !== "else" && (!dir.exp || !dir.exp.content.trim())) {
|
2239
|
-
|
2240
|
-
|
2241
|
-
dir.exp = (0, __vue_compiler_dom.createSimpleExpression)(`true`, false, loc);
|
2555
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_IF_NO_EXPRESSION, dir.loc));
|
2556
|
+
dir.exp = createSimpleExpression(`true`, false, dir.exp ? dir.exp.ast : node);
|
2242
2557
|
}
|
2243
2558
|
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE;
|
2244
2559
|
transformedIfNode.set(node, dir);
|
@@ -2253,7 +2568,7 @@ function processIf(node, attribute, context) {
|
|
2253
2568
|
id,
|
2254
2569
|
condition: dir.exp,
|
2255
2570
|
positive: branch,
|
2256
|
-
once: context.inVOnce ||
|
2571
|
+
once: context.inVOnce || isConstantNode(attribute.value)
|
2257
2572
|
};
|
2258
2573
|
};
|
2259
2574
|
} else {
|
@@ -2268,12 +2583,11 @@ function processIf(node, attribute, context) {
|
|
2268
2583
|
}
|
2269
2584
|
}
|
2270
2585
|
if (!siblingIf || !lastIfNode || lastIfNode.type !== IRNodeTypes.IF) {
|
2271
|
-
context.options.onError(
|
2586
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, node.loc));
|
2272
2587
|
return;
|
2273
2588
|
}
|
2274
2589
|
while (lastIfNode.negative && lastIfNode.negative.type === IRNodeTypes.IF) lastIfNode = lastIfNode.negative;
|
2275
|
-
if (dir.name === "else-if" && lastIfNode.negative) context.options.onError(
|
2276
|
-
context.root.comment = [];
|
2590
|
+
if (dir.name === "else-if" && lastIfNode.negative) context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, node.loc));
|
2277
2591
|
const [branch, onExit] = createBranch(node, context);
|
2278
2592
|
if (dir.name === "else") lastIfNode.negative = branch;
|
2279
2593
|
else lastIfNode.negative = {
|
@@ -2305,22 +2619,22 @@ const transformVModel = (_dir, node, context) => {
|
|
2305
2619
|
const dir = resolveDirective(_dir, context);
|
2306
2620
|
const { exp, arg } = dir;
|
2307
2621
|
if (!exp) {
|
2308
|
-
context.options.onError(
|
2622
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_NO_EXPRESSION, dir.loc));
|
2309
2623
|
return;
|
2310
2624
|
}
|
2311
2625
|
const expString = exp.content;
|
2312
|
-
if (!expString.trim() || !
|
2313
|
-
context.options.onError(
|
2626
|
+
if (!expString.trim() || !isMemberExpression(exp)) {
|
2627
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION, exp.loc));
|
2314
2628
|
return;
|
2315
2629
|
}
|
2316
2630
|
const isComponent = isJSXComponent(node);
|
2317
2631
|
if (isComponent) return {
|
2318
|
-
key: arg ? arg :
|
2632
|
+
key: arg ? arg : createSimpleExpression("modelValue", true),
|
2319
2633
|
value: exp,
|
2320
2634
|
model: true,
|
2321
2635
|
modelModifiers: dir.modifiers.map((m) => m.content)
|
2322
2636
|
};
|
2323
|
-
if (dir.arg) context.options.onError((
|
2637
|
+
if (dir.arg) context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_ARG_ON_ELEMENT, dir.arg.loc));
|
2324
2638
|
const tag = getText(node.openingElement.name, context);
|
2325
2639
|
const isCustomElement = context.options.isCustomElement(tag);
|
2326
2640
|
let modelType = "text";
|
@@ -2337,7 +2651,7 @@ const transformVModel = (_dir, node, context) => {
|
|
2337
2651
|
break;
|
2338
2652
|
case "file":
|
2339
2653
|
modelType = void 0;
|
2340
|
-
context.options.onError((
|
2654
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT, dir.loc));
|
2341
2655
|
break;
|
2342
2656
|
default:
|
2343
2657
|
checkDuplicatedValue();
|
@@ -2347,7 +2661,7 @@ const transformVModel = (_dir, node, context) => {
|
|
2347
2661
|
else checkDuplicatedValue();
|
2348
2662
|
} else if (tag === "select") modelType = "select";
|
2349
2663
|
else checkDuplicatedValue();
|
2350
|
-
else context.options.onError((
|
2664
|
+
else context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT, dir.loc));
|
2351
2665
|
if (modelType) context.registerOperation({
|
2352
2666
|
type: IRNodeTypes.DIRECTIVE,
|
2353
2667
|
element: context.reference(),
|
@@ -2358,7 +2672,7 @@ const transformVModel = (_dir, node, context) => {
|
|
2358
2672
|
});
|
2359
2673
|
function checkDuplicatedValue() {
|
2360
2674
|
const value = findProp(node, "value");
|
2361
|
-
if (value && value.value?.type !== "StringLiteral") context.options.onError((
|
2675
|
+
if (value && value.value?.type !== "StringLiteral") context.options.onError(createCompilerError(ErrorCodes.X_V_MODEL_UNNECESSARY_VALUE, value.loc));
|
2362
2676
|
}
|
2363
2677
|
};
|
2364
2678
|
function hasDynamicKeyVBind(node) {
|
@@ -2373,10 +2687,10 @@ const transformVOn = (dir, node, context) => {
|
|
2373
2687
|
if (!name) return;
|
2374
2688
|
const isComponent = isJSXComponent(node);
|
2375
2689
|
const [nameString, ...modifiers] = context.ir.source.slice(name.start, name.end).replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
2376
|
-
if (!value && !modifiers.length) context.options.onError(
|
2377
|
-
let arg =
|
2690
|
+
if (!value && !modifiers.length) context.options.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc));
|
2691
|
+
let arg = createSimpleExpression(nameString, true, dir.name);
|
2378
2692
|
const exp = resolveExpression(dir.value, context);
|
2379
|
-
const { keyModifiers, nonKeyModifiers, eventOptionModifiers } =
|
2693
|
+
const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(arg.isStatic ? `on${nameString}` : arg, modifiers.map((modifier) => createSimpleExpression(modifier)));
|
2380
2694
|
let keyOverride;
|
2381
2695
|
const isStaticClick = arg.isStatic && arg.content.toLowerCase() === "click";
|
2382
2696
|
if (nonKeyModifiers.includes("middle")) {
|
@@ -2418,6 +2732,35 @@ const transformVOn = (dir, node, context) => {
|
|
2418
2732
|
};
|
2419
2733
|
context.registerEffect([arg], operation);
|
2420
2734
|
};
|
2735
|
+
const isEventOptionModifier = /* @__PURE__ */ (0, __vue_shared.makeMap)(`passive,once,capture`);
|
2736
|
+
const isNonKeyModifier = /* @__PURE__ */ (0, __vue_shared.makeMap)("stop,prevent,self,ctrl,shift,alt,meta,exact,middle");
|
2737
|
+
const maybeKeyModifier = /* @__PURE__ */ (0, __vue_shared.makeMap)("left,right");
|
2738
|
+
const isKeyboardEvent = /* @__PURE__ */ (0, __vue_shared.makeMap)(`onkeyup,onkeydown,onkeypress`);
|
2739
|
+
const resolveModifiers = (key, modifiers) => {
|
2740
|
+
const keyModifiers = [];
|
2741
|
+
const nonKeyModifiers = [];
|
2742
|
+
const eventOptionModifiers = [];
|
2743
|
+
for (const modifier_ of modifiers) {
|
2744
|
+
const modifier = modifier_.content;
|
2745
|
+
if (isEventOptionModifier(modifier)) eventOptionModifiers.push(modifier);
|
2746
|
+
else {
|
2747
|
+
const keyString = (0, __vue_shared.isString)(key) ? key : key.isStatic ? key.content : null;
|
2748
|
+
if (maybeKeyModifier(modifier)) if (keyString) if (isKeyboardEvent(keyString.toLowerCase())) keyModifiers.push(modifier);
|
2749
|
+
else nonKeyModifiers.push(modifier);
|
2750
|
+
else {
|
2751
|
+
keyModifiers.push(modifier);
|
2752
|
+
nonKeyModifiers.push(modifier);
|
2753
|
+
}
|
2754
|
+
else if (isNonKeyModifier(modifier)) nonKeyModifiers.push(modifier);
|
2755
|
+
else keyModifiers.push(modifier);
|
2756
|
+
}
|
2757
|
+
}
|
2758
|
+
return {
|
2759
|
+
keyModifiers,
|
2760
|
+
nonKeyModifiers,
|
2761
|
+
eventOptionModifiers
|
2762
|
+
};
|
2763
|
+
};
|
2421
2764
|
|
2422
2765
|
//#endregion
|
2423
2766
|
//#region src/transforms/vOnce.ts
|
@@ -2431,7 +2774,7 @@ const transformVShow = (_dir, node, context) => {
|
|
2431
2774
|
const dir = resolveDirective(_dir, context);
|
2432
2775
|
const { exp, loc } = dir;
|
2433
2776
|
if (!exp) {
|
2434
|
-
context.options.onError((
|
2777
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_SHOW_NO_EXPRESSION, loc));
|
2435
2778
|
return;
|
2436
2779
|
}
|
2437
2780
|
context.registerOperation({
|
@@ -2449,13 +2792,13 @@ const transformVSlot = (node, context) => {
|
|
2449
2792
|
if (node.type !== "JSXElement") return;
|
2450
2793
|
const { children } = node;
|
2451
2794
|
const dir = findProp(node, "v-slot");
|
2452
|
-
const resolvedDirective = dir ? resolveDirective(dir, context
|
2795
|
+
const resolvedDirective = dir ? resolveDirective(dir, context) : void 0;
|
2453
2796
|
const { parent } = context;
|
2454
2797
|
const isComponent = isJSXComponent(node);
|
2455
2798
|
const isSlotTemplate = isTemplate(node) && parent && parent.node.type === "JSXElement" && isJSXComponent(parent.node);
|
2456
2799
|
if (isComponent && children.length) return transformComponentSlot(node, resolvedDirective, context);
|
2457
2800
|
else if (isSlotTemplate && resolvedDirective) return transformTemplateSlot(node, resolvedDirective, context);
|
2458
|
-
else if (!isComponent && dir) context.options.onError(
|
2801
|
+
else if (!isComponent && dir) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MISPLACED, dir.loc));
|
2459
2802
|
};
|
2460
2803
|
function transformComponentSlot(node, dir, context) {
|
2461
2804
|
const { children } = node;
|
@@ -2467,10 +2810,10 @@ function transformComponentSlot(node, dir, context) {
|
|
2467
2810
|
onExit();
|
2468
2811
|
const hasOtherSlots = !!slots.length;
|
2469
2812
|
if (dir && hasOtherSlots) {
|
2470
|
-
context.options.onError(
|
2813
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE, dir.loc));
|
2471
2814
|
return;
|
2472
2815
|
}
|
2473
|
-
if (nonSlotTemplateChildren.length) if (hasStaticSlot(slots, "default")) context.options.onError(
|
2816
|
+
if (nonSlotTemplateChildren.length) if (hasStaticSlot(slots, "default")) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN, nonSlotTemplateChildren[0].loc));
|
2474
2817
|
else {
|
2475
2818
|
registerSlot(slots, arg, block);
|
2476
2819
|
context.slots = slots;
|
@@ -2481,7 +2824,7 @@ function transformComponentSlot(node, dir, context) {
|
|
2481
2824
|
const elseIfRE = /^v-else(-if)?$/;
|
2482
2825
|
function transformTemplateSlot(node, dir, context) {
|
2483
2826
|
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE;
|
2484
|
-
const arg = dir.arg
|
2827
|
+
const arg = dir.arg;
|
2485
2828
|
const vFor = findProp(node, "v-for");
|
2486
2829
|
const vIf = findProp(node, "v-if");
|
2487
2830
|
const vElse = findProp(node, elseIfRE);
|
@@ -2489,7 +2832,7 @@ function transformTemplateSlot(node, dir, context) {
|
|
2489
2832
|
const [block, onExit] = createSlotBlock(node, dir, context);
|
2490
2833
|
if (!vFor && !vIf && !vElse) {
|
2491
2834
|
const slotName = arg ? arg.isStatic && arg.content : "default";
|
2492
|
-
if (slotName && hasStaticSlot(slots, slotName)) context.options.onError(
|
2835
|
+
if (slotName && hasStaticSlot(slots, slotName)) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES, dir.loc));
|
2493
2836
|
else registerSlot(slots, arg, block);
|
2494
2837
|
} else if (vIf) {
|
2495
2838
|
const vIfDir = resolveDirective(vIf, context);
|
@@ -2522,7 +2865,7 @@ function transformTemplateSlot(node, dir, context) {
|
|
2522
2865
|
fn: block
|
2523
2866
|
};
|
2524
2867
|
ifNode.negative = negative;
|
2525
|
-
} else context.options.onError(
|
2868
|
+
} else context.options.onError(createCompilerError(ErrorCodes.X_V_ELSE_NO_ADJACENT_IF, vElseDir.loc));
|
2526
2869
|
} else if (vFor) {
|
2527
2870
|
const forParseResult = getForParseResult(vFor, context);
|
2528
2871
|
if (forParseResult.source) registerDynamicSlot(slots, {
|
@@ -2580,18 +2923,17 @@ const transformVSlots = (dir, node, context) => {
|
|
2580
2923
|
//#region src/transforms/vText.ts
|
2581
2924
|
const transformVText = (dir, node, context) => {
|
2582
2925
|
let exp;
|
2583
|
-
const loc = resolveLocation(dir.loc, context);
|
2584
2926
|
if (!dir.value) {
|
2585
|
-
context.options.onError((
|
2927
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_TEXT_NO_EXPRESSION, dir.loc));
|
2586
2928
|
exp = EMPTY_EXPRESSION;
|
2587
2929
|
} else exp = resolveExpression(dir.value, context);
|
2588
2930
|
if (node.children.length) {
|
2589
|
-
context.options.onError((
|
2931
|
+
context.options.onError(createCompilerError(ErrorCodes.X_V_TEXT_WITH_CHILDREN, dir.loc));
|
2590
2932
|
context.childrenTemplate.length = 0;
|
2591
2933
|
}
|
2592
2934
|
if ((0, __vue_shared.isVoidTag)(getText(node.openingElement.name, context))) return;
|
2593
2935
|
const literal = getLiteralExpressionValue(exp);
|
2594
|
-
if (literal != null) context.childrenTemplate = [String(literal)];
|
2936
|
+
if (literal != null) context.childrenTemplate = [(0, __vue_shared.escapeHtml)(String(literal))];
|
2595
2937
|
else {
|
2596
2938
|
context.childrenTemplate = [" "];
|
2597
2939
|
context.registerOperation({
|