UNPKG

@vue-jsx-vapor/compiler

Version:
1,419 lines (1,399 loc) 107 kB
//#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion const __babel_parser = __toESM(require("@babel/parser")); const __vue_shared = __toESM(require("@vue/shared")); const source_map_js = __toESM(require("source-map-js")); const ast_kit = __toESM(require("ast-kit")); //#region src/utils/error.ts let ErrorCodes = /* @__PURE__ */ function(ErrorCodes$1) { ErrorCodes$1[ErrorCodes$1["X_V_IF_NO_EXPRESSION"] = 28] = "X_V_IF_NO_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_ELSE_NO_ADJACENT_IF"] = 30] = "X_V_ELSE_NO_ADJACENT_IF"; ErrorCodes$1[ErrorCodes$1["X_V_FOR_NO_EXPRESSION"] = 31] = "X_V_FOR_NO_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_FOR_MALFORMED_EXPRESSION"] = 32] = "X_V_FOR_MALFORMED_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_ON_NO_EXPRESSION"] = 35] = "X_V_ON_NO_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_SLOT_MIXED_SLOT_USAGE"] = 37] = "X_V_SLOT_MIXED_SLOT_USAGE"; ErrorCodes$1[ErrorCodes$1["X_V_SLOT_DUPLICATE_SLOT_NAMES"] = 38] = "X_V_SLOT_DUPLICATE_SLOT_NAMES"; ErrorCodes$1[ErrorCodes$1["X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN"] = 39] = "X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN"; ErrorCodes$1[ErrorCodes$1["X_V_SLOT_MISPLACED"] = 40] = "X_V_SLOT_MISPLACED"; ErrorCodes$1[ErrorCodes$1["X_V_MODEL_NO_EXPRESSION"] = 41] = "X_V_MODEL_NO_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_MODEL_MALFORMED_EXPRESSION"] = 42] = "X_V_MODEL_MALFORMED_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_HTML_NO_EXPRESSION"] = 53] = "X_V_HTML_NO_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_HTML_WITH_CHILDREN"] = 54] = "X_V_HTML_WITH_CHILDREN"; ErrorCodes$1[ErrorCodes$1["X_V_TEXT_NO_EXPRESSION"] = 55] = "X_V_TEXT_NO_EXPRESSION"; ErrorCodes$1[ErrorCodes$1["X_V_TEXT_WITH_CHILDREN"] = 56] = "X_V_TEXT_WITH_CHILDREN"; ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ON_INVALID_ELEMENT"] = 57] = "X_V_MODEL_ON_INVALID_ELEMENT"; ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ARG_ON_ELEMENT"] = 58] = "X_V_MODEL_ARG_ON_ELEMENT"; ErrorCodes$1[ErrorCodes$1["X_V_MODEL_ON_FILE_INPUT_ELEMENT"] = 59] = "X_V_MODEL_ON_FILE_INPUT_ELEMENT"; ErrorCodes$1[ErrorCodes$1["X_V_MODEL_UNNECESSARY_VALUE"] = 60] = "X_V_MODEL_UNNECESSARY_VALUE"; ErrorCodes$1[ErrorCodes$1["X_V_SHOW_NO_EXPRESSION"] = 61] = "X_V_SHOW_NO_EXPRESSION"; return ErrorCodes$1; }({}); const errorMessages = { [ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`, [ErrorCodes.X_V_ELSE_NO_ADJACENT_IF]: `v-else/v-else-if has no adjacent v-if or v-else-if.`, [ErrorCodes.X_V_FOR_NO_EXPRESSION]: `v-for is missing expression.`, [ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`, [ErrorCodes.X_V_ON_NO_EXPRESSION]: `v-on is missing expression.`, [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.", [ErrorCodes.X_V_SLOT_DUPLICATE_SLOT_NAMES]: `Duplicate slot names found. `, [ErrorCodes.X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN]: "Extraneous children found when component already has explicitly named default slot. These children will be ignored.", [ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`, [ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`, [ErrorCodes.X_V_SLOT_MISPLACED]: `v-slot can only be used on components or <template> tags.`, [ErrorCodes.X_V_HTML_NO_EXPRESSION]: `v-html is missing expression.`, [ErrorCodes.X_V_HTML_WITH_CHILDREN]: `v-html will override element children.`, [ErrorCodes.X_V_TEXT_NO_EXPRESSION]: `v-text is missing expression.`, [ErrorCodes.X_V_TEXT_WITH_CHILDREN]: `v-text will override element children.`, [ErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`, [ErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT]: `v-model can only be used on <input>, <textarea> and <select> elements.`, [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.`, [ErrorCodes.X_V_MODEL_UNNECESSARY_VALUE]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`, [ErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.` }; function createCompilerError(code, loc, messages, additionalMessage) { const msg = (messages || errorMessages)[code] + (additionalMessage || ``); const error = new SyntaxError(String(msg)); error.code = code; error.loc = loc; return error; } //#endregion //#region src/ir/component.ts let IRDynamicPropsKind = /* @__PURE__ */ function(IRDynamicPropsKind$1) { IRDynamicPropsKind$1[IRDynamicPropsKind$1["EXPRESSION"] = 0] = "EXPRESSION"; IRDynamicPropsKind$1[IRDynamicPropsKind$1["ATTRIBUTE"] = 1] = "ATTRIBUTE"; return IRDynamicPropsKind$1; }({}); let IRSlotType = /* @__PURE__ */ function(IRSlotType$1) { IRSlotType$1[IRSlotType$1["STATIC"] = 0] = "STATIC"; IRSlotType$1[IRSlotType$1["DYNAMIC"] = 1] = "DYNAMIC"; IRSlotType$1[IRSlotType$1["LOOP"] = 2] = "LOOP"; IRSlotType$1[IRSlotType$1["CONDITIONAL"] = 3] = "CONDITIONAL"; IRSlotType$1[IRSlotType$1["EXPRESSION"] = 4] = "EXPRESSION"; return IRSlotType$1; }({}); //#endregion //#region src/ir/index.ts let IRNodeTypes = /* @__PURE__ */ function(IRNodeTypes$1) { IRNodeTypes$1[IRNodeTypes$1["ROOT"] = 0] = "ROOT"; IRNodeTypes$1[IRNodeTypes$1["BLOCK"] = 1] = "BLOCK"; IRNodeTypes$1[IRNodeTypes$1["SET_PROP"] = 2] = "SET_PROP"; IRNodeTypes$1[IRNodeTypes$1["SET_DYNAMIC_PROPS"] = 3] = "SET_DYNAMIC_PROPS"; IRNodeTypes$1[IRNodeTypes$1["SET_TEXT"] = 4] = "SET_TEXT"; IRNodeTypes$1[IRNodeTypes$1["SET_EVENT"] = 5] = "SET_EVENT"; IRNodeTypes$1[IRNodeTypes$1["SET_DYNAMIC_EVENTS"] = 6] = "SET_DYNAMIC_EVENTS"; IRNodeTypes$1[IRNodeTypes$1["SET_HTML"] = 7] = "SET_HTML"; IRNodeTypes$1[IRNodeTypes$1["SET_TEMPLATE_REF"] = 8] = "SET_TEMPLATE_REF"; IRNodeTypes$1[IRNodeTypes$1["INSERT_NODE"] = 9] = "INSERT_NODE"; IRNodeTypes$1[IRNodeTypes$1["PREPEND_NODE"] = 10] = "PREPEND_NODE"; IRNodeTypes$1[IRNodeTypes$1["CREATE_COMPONENT_NODE"] = 11] = "CREATE_COMPONENT_NODE"; IRNodeTypes$1[IRNodeTypes$1["SLOT_OUTLET_NODE"] = 12] = "SLOT_OUTLET_NODE"; IRNodeTypes$1[IRNodeTypes$1["DIRECTIVE"] = 13] = "DIRECTIVE"; IRNodeTypes$1[IRNodeTypes$1["DECLARE_OLD_REF"] = 14] = "DECLARE_OLD_REF"; IRNodeTypes$1[IRNodeTypes$1["IF"] = 15] = "IF"; IRNodeTypes$1[IRNodeTypes$1["FOR"] = 16] = "FOR"; IRNodeTypes$1[IRNodeTypes$1["GET_TEXT_CHILD"] = 17] = "GET_TEXT_CHILD"; IRNodeTypes$1[IRNodeTypes$1["CREATE_NODES"] = 18] = "CREATE_NODES"; IRNodeTypes$1[IRNodeTypes$1["SET_NODES"] = 19] = "SET_NODES"; return IRNodeTypes$1; }({}); let DynamicFlag = /* @__PURE__ */ function(DynamicFlag$1) { DynamicFlag$1[DynamicFlag$1["NONE"] = 0] = "NONE"; /** * This node is referenced and needs to be saved as a variable. */ DynamicFlag$1[DynamicFlag$1["REFERENCED"] = 1] = "REFERENCED"; /** * This node is not generated from template, but is generated dynamically. */ DynamicFlag$1[DynamicFlag$1["NON_TEMPLATE"] = 2] = "NON_TEMPLATE"; /** * This node needs to be inserted back into the template. */ DynamicFlag$1[DynamicFlag$1["INSERT"] = 4] = "INSERT"; return DynamicFlag$1; }({}); function isBlockOperation(op) { const type = op.type; return type === IRNodeTypes.CREATE_COMPONENT_NODE || type === IRNodeTypes.SLOT_OUTLET_NODE || type === IRNodeTypes.IF || type === IRNodeTypes.FOR; } //#endregion //#region src/utils/ast.ts function findProp(expression, key) { if (expression?.type === "JSXElement") for (const attr of expression.openingElement.attributes) { const name = attr.type === "JSXAttribute" && (attr.name.type === "JSXIdentifier" ? attr.name.name : attr.name.type === "JSXNamespacedName" ? attr.name.namespace.name : "").split("_")[0]; if (name && ((0, __vue_shared.isString)(key) ? name === key : key.test(name))) return attr; } } const TS_NODE_TYPES = [ "TSAsExpression", "TSTypeAssertion", "TSNonNullExpression", "TSInstantiationExpression", "TSSatisfiesExpression" ]; function unwrapTSNode(node) { if (TS_NODE_TYPES.includes(node.type)) return unwrapTSNode(node.expression); else return node; } function isJSXComponent(node) { if (node.type !== "JSXElement") return false; const { openingElement } = node; if (openingElement.name.type === "JSXIdentifier") { const name = openingElement.name.name; return !(0, __vue_shared.isHTMLTag)(name) && !(0, __vue_shared.isSVGTag)(name); } else return openingElement.name.type === "JSXMemberExpression"; } function isMemberExpression(exp) { if (!exp.ast) return; const ret = unwrapTSNode(exp.ast); return ret.type === "MemberExpression" || ret.type === "OptionalMemberExpression" || ret.type === "Identifier" && ret.name !== "undefined"; } function isTemplate(node) { if (node.type === "JSXElement" && node.openingElement.name.type === "JSXIdentifier") return node.openingElement.name.name === "template"; } function isStaticNode(node) { node = unwrapTSNode(node); switch (node.type) { case "UnaryExpression": return isStaticNode(node.argument); case "LogicalExpression": case "BinaryExpression": return isStaticNode(node.left) && isStaticNode(node.right); case "ConditionalExpression": return isStaticNode(node.test) && isStaticNode(node.consequent) && isStaticNode(node.alternate); case "SequenceExpression": case "TemplateLiteral": return node.expressions.every((expr) => isStaticNode(expr)); case "ParenthesizedExpression": return isStaticNode(node.expression); case "StringLiteral": case "NumericLiteral": case "BooleanLiteral": case "NullLiteral": case "BigIntLiteral": return true; } return false; } function isConstantNode(node) { if (isStaticNode(node)) return true; node = unwrapTSNode(node); switch (node.type) { case "Identifier": return node.name === "undefined" || (0, __vue_shared.isGloballyAllowed)(node.name); case "RegExpLiteral": return true; case "ObjectExpression": return node.properties.every((prop) => { if (prop.type === "ObjectMethod") return false; if (prop.type === "SpreadElement") return isConstantNode(prop.argument); return (!prop.computed || isConstantNode(prop.key)) && isConstantNode(prop.value); }); case "ArrayExpression": return node.elements.every((element) => { if (element === null) return true; if (element.type === "SpreadElement") return isConstantNode(element.argument); return isConstantNode(element); }); } return false; } const isFnExpression = (exp) => { try { if (!exp.ast) return false; let ret = exp.ast; if (ret.type === "Program") { ret = ret.body[0]; if (ret.type === "ExpressionStatement") ret = ret.expression; } ret = unwrapTSNode(ret); return ret.type === "FunctionExpression" || ret.type === "ArrowFunctionExpression"; } catch { return false; } }; const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node); const isStaticProperty = (node) => !!node && (node.type === "ObjectProperty" || node.type === "ObjectMethod") && !node.computed; const nonIdentifierRE = /^$|^\d|[^$\w\u00A0-\uFFFF]/; const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name); function getTextLikeValue(node, excludeNumber) { node = node.type === "JSXExpressionContainer" ? node.expression : node; if (node.type === "StringLiteral") return node.value; else if (!excludeNumber && (node.type === "NumericLiteral" || node.type === "BigIntLiteral")) return String(node.value); else if (node.type === "TemplateLiteral" && node.expressions.length === 0) return node.quasis[0].value.cooked; } //#endregion //#region src/utils/text.ts const EMPTY_TEXT_REGEX = /^[\t\v\f \u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[\n\r]\s*$/; const START_EMPTY_TEXT_REGEX = /^\s*[\n\r]/; const END_EMPTY_TEXT_REGEX = /[\n\r]\s*$/; function resolveJSXText(node) { if (EMPTY_TEXT_REGEX.test(String(node.extra?.raw))) return ""; let value = node.value; if (START_EMPTY_TEXT_REGEX.test(value)) value = value.trimStart(); if (END_EMPTY_TEXT_REGEX.test(value)) value = value.trimEnd(); return value; } function isEmptyText(node) { return node.type === "JSXText" && EMPTY_TEXT_REGEX.test(String(node.extra?.raw)) || node.type === "JSXExpressionContainer" && node.expression.type === "JSXEmptyExpression"; } function getText(node, content) { return content.ir.source.slice(node.start, node.end); } //#endregion //#region src/utils/expression.ts const locStub = { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 0, index: 0 }, filename: "", identifierName: void 0 }; function createSimpleExpression(content, isStatic = false, ast) { return { loc: ast ? ast.loc : locStub, content, isStatic, ast }; } const isLiteralWhitelisted = /* @__PURE__ */ (0, __vue_shared.makeMap)("true,false,null,this"); function isConstantExpression(exp) { return isLiteralWhitelisted(exp.content) || (0, __vue_shared.isGloballyAllowed)(exp.content) || getLiteralExpressionValue(exp) !== null; } function getLiteralExpressionValue(exp) { if (exp.ast) { const res = getTextLikeValue(exp.ast); if (res != null) return res; } return exp.isStatic ? exp.content : null; } const EMPTY_EXPRESSION = createSimpleExpression("", true); function resolveExpression(node, context) { if (!node) return EMPTY_EXPRESSION; node = unwrapTSNode(node.type === "JSXExpressionContainer" ? node.expression : node); const isStatic = node.type === "StringLiteral" || node.type === "JSXText" || node.type === "JSXIdentifier"; 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); return createSimpleExpression(source, isStatic, node); } function propToExpression(prop, context) { return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION; } //#endregion //#region src/utils/directive.ts const namespaceRE = /^(?:\$([\w-]+)\$)?([\w-]+)?/; function resolveDirective(node, context) { const { value, name } = node; let nameString = name.type === "JSXNamespacedName" ? name.namespace.name : name.type === "JSXIdentifier" ? name.name : ""; const isDirective = nameString.startsWith("v-"); let modifiers = []; let isStatic = true; let argString = name.type === "JSXNamespacedName" ? name.name.name : ""; if (name.type !== "JSXNamespacedName" && !argString) [nameString, ...modifiers] = nameString.split("_"); else { const result = argString.match(namespaceRE); if (result) { let modifierString = ""; [, argString, modifierString] = result; if (argString) { argString = argString.replaceAll("_", "."); isStatic = false; if (modifierString && modifierString.startsWith("_")) modifiers = modifierString.slice(1).split("_"); } else if (modifierString) [argString, ...modifiers] = modifierString.split("_"); } } const arg = isDirective ? argString && name.type === "JSXNamespacedName" ? createSimpleExpression(argString, isStatic, name.name) : void 0 : createSimpleExpression(nameString, true, name); const exp = value ? resolveExpression(value, context) : void 0; return { name: isDirective ? nameString.slice(2) : "bind", rawName: getText(name, context), exp, arg, loc: node.loc, modifiers: modifiers.map((modifier) => createSimpleExpression(modifier)) }; } //#endregion //#region src/utils/transform.ts function newDynamic() { return { flags: DynamicFlag.REFERENCED, children: [] }; } function newBlock(node) { return { type: 1, node, dynamic: newDynamic(), effect: [], operation: [], returns: [], tempId: 0 }; } function createBranch(node, context, isVFor) { context.node = node = wrapFragment(node); const branch = newBlock(node); const exitBlock = context.enterBlock(branch, isVFor); context.reference(); return [branch, exitBlock]; } function wrapFragment(node) { if (node.type === "JSXFragment" || isTemplate(node)) return node; return { type: "JSXFragment", openingFragment: { type: "JSXOpeningFragment" }, closingFragment: { type: "JSXClosingFragment" }, children: [node.type === "JSXElement" ? node : { type: "JSXExpressionContainer", expression: node }] }; } //#endregion //#region src/utils/generate.ts const NEWLINE = Symbol(`newline`); const INDENT_START = Symbol(`indent start`); const INDENT_END = Symbol(`indent end`); let NewlineType = /* @__PURE__ */ function(NewlineType$1) { /** Start with `\n` */ NewlineType$1[NewlineType$1["Start"] = 0] = "Start"; /** Ends with `\n` */ NewlineType$1[NewlineType$1["End"] = -1] = "End"; /** No `\n` included */ NewlineType$1[NewlineType$1["None"] = -2] = "None"; /** Don't know, calc it */ NewlineType$1[NewlineType$1["Unknown"] = -3] = "Unknown"; return NewlineType$1; }({}); function buildCodeFragment(...frag) { const push = frag.push.bind(frag); const unshift = frag.unshift.bind(frag); return [ frag, push, unshift ]; } function genMulti([left, right, seg, placeholder], ...frags) { if (placeholder) { while (frags.length > 0 && !frags.at(-1)) frags.pop(); frags = frags.map((frag$1) => frag$1 || placeholder); } else frags = frags.filter(Boolean); const frag = []; push(left); for (const [i, fn] of frags.entries()) { push(fn); if (i < frags.length - 1) push(seg); } push(right); return frag; function push(fn) { if (!(0, __vue_shared.isArray)(fn)) fn = [fn]; frag.push(...fn); } } const DELIMITERS_ARRAY = [ "[", "]", ", " ]; const DELIMITERS_ARRAY_NEWLINE = [ [ "[", INDENT_START, NEWLINE ], [ INDENT_END, NEWLINE, "]" ], [", ", NEWLINE] ]; const DELIMITERS_OBJECT = [ "{ ", " }", ", " ]; const DELIMITERS_OBJECT_NEWLINE = [ [ "{", INDENT_START, NEWLINE ], [ INDENT_END, NEWLINE, "}" ], [", ", NEWLINE] ]; function genCall(name, ...frags) { const hasPlaceholder = (0, __vue_shared.isArray)(name); const fnName = hasPlaceholder ? name[0] : name; const placeholder = hasPlaceholder ? name[1] : "null"; return [fnName, ...genMulti([ "(", ")", ", ", placeholder ], ...frags)]; } function codeFragmentToString(code, context) { const { options: { filename, sourceMap } } = context; let map; if (sourceMap) { map = new source_map_js.SourceMapGenerator(); map.setSourceContent(filename, context.ir.source); map._sources.add(filename); } let codegen = ""; const pos = { line: 1, column: 0, index: 0 }; let indentLevel = 0; for (let frag of code) { if (!frag) continue; if (frag === NEWLINE) frag = [`\n${` `.repeat(indentLevel)}`, NewlineType.Start]; else if (frag === INDENT_START) { indentLevel++; continue; } else if (frag === INDENT_END) { indentLevel--; continue; } if ((0, __vue_shared.isString)(frag)) frag = [frag]; let [code$1, newlineIndex = NewlineType.None, loc, name] = frag; codegen += code$1; if (map) { if (loc) addMapping(loc.start, name); if (newlineIndex === NewlineType.Unknown) advancePositionWithMutation(pos, code$1); else { pos.index += code$1.length; if (newlineIndex === NewlineType.None) pos.column += code$1.length; else { if (newlineIndex === NewlineType.End) newlineIndex = code$1.length - 1; pos.line++; pos.column = code$1.length - newlineIndex; } } if (loc && loc !== locStub) addMapping(loc.end); } } return [codegen, map]; function addMapping(loc, name = null) { const { _names, _mappings } = map; if (name !== null && !_names.has(name)) _names.add(name); _mappings.add({ originalLine: loc.line, originalColumn: loc.column, generatedLine: pos.line, generatedColumn: pos.column - 1, source: filename, name }); } } function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) { let linesCount = 0; let lastNewLinePos = -1; for (let i = 0; i < numberOfCharacters; i++) if (source.charCodeAt(i) === 10) { linesCount++; lastNewLinePos = i; } pos.index += numberOfCharacters; pos.line += linesCount; pos.column = lastNewLinePos === -1 ? pos.column + numberOfCharacters : numberOfCharacters - lastNewLinePos; return pos; } function advancePositionWithClone(pos, source, numberOfCharacters = source.length) { return advancePositionWithMutation({ index: pos.index, line: pos.line, column: pos.column }, source, numberOfCharacters); } //#endregion //#region src/utils/dom.ts /** * Copied from https://github.com/MananTank/validate-html-nesting * with ISC license * * To avoid runtime dependency on validate-html-nesting * This file should not change very often in the original repo * but we may need to keep it up-to-date from time to time. */ /** * returns true if given parent-child nesting is valid HTML */ function isValidHTMLNesting(parent, child) { if (parent === "template") return true; if (parent in onlyValidChildren) return onlyValidChildren[parent].has(child); if (child in onlyValidParents) return onlyValidParents[child].has(parent); if (parent in knownInvalidChildren && knownInvalidChildren[parent].has(child)) return false; if (child in knownInvalidParents && knownInvalidParents[child].has(parent)) return false; return true; } const headings = new Set([ "h1", "h2", "h3", "h4", "h5", "h6" ]); const emptySet = new Set([]); /** * maps element to set of elements that can be it's children, no other */ const onlyValidChildren = { head: new Set([ "base", "basefront", "bgsound", "link", "meta", "title", "noscript", "noframes", "style", "script", "template" ]), optgroup: new Set(["option"]), select: new Set([ "optgroup", "option", "hr" ]), table: new Set([ "caption", "colgroup", "tbody", "tfoot", "thead" ]), tr: new Set(["td", "th"]), colgroup: new Set(["col"]), tbody: new Set(["tr"]), thead: new Set(["tr"]), tfoot: new Set(["tr"]), script: emptySet, iframe: emptySet, option: emptySet, textarea: emptySet, style: emptySet, title: emptySet }; /** maps elements to set of elements which can be it's parent, no other */ const onlyValidParents = { html: emptySet, body: new Set(["html"]), head: new Set(["html"]), td: new Set(["tr"]), colgroup: new Set(["table"]), caption: new Set(["table"]), tbody: new Set(["table"]), tfoot: new Set(["table"]), col: new Set(["colgroup"]), th: new Set(["tr"]), thead: new Set(["table"]), tr: new Set([ "tbody", "thead", "tfoot" ]), dd: new Set(["dl", "div"]), dt: new Set(["dl", "div"]), figcaption: new Set(["figure"]), summary: new Set(["details"]), area: new Set(["map"]) }; /** maps element to set of elements that can not be it's children, others can */ const knownInvalidChildren = { p: new Set([ "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", "main", "nav", "menu", "ol", "p", "pre", "section", "table", "ul" ]), svg: new Set([ "b", "blockquote", "br", "code", "dd", "div", "dl", "dt", "em", "embed", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "li", "menu", "meta", "ol", "p", "pre", "ruby", "s", "small", "span", "strong", "sub", "sup", "table", "u", "ul", "var" ]) }; /** maps element to set of elements that can not be it's parent, others can */ const knownInvalidParents = { a: new Set(["a"]), button: new Set(["button"]), dd: new Set(["dd", "dt"]), dt: new Set(["dd", "dt"]), form: new Set(["form"]), li: new Set(["li"]), h1: headings, h2: headings, h3: headings, h4: headings, h5: headings, h6: headings }; function toValidAssetId(name, type) { return `_${type}_${name.replaceAll(/\W/g, (searchValue, replaceValue) => { return searchValue === "-" ? "_" : name.charCodeAt(replaceValue).toString(); })}`; } //#endregion //#region src/generators/expression.ts function genExpression(node, context, assignment, needWrap = false) { let { content, ast, isStatic, loc } = node; if (needWrap) content = `() => (${content})`; if (isStatic) return [[ JSON.stringify(content), NewlineType.None, loc ]]; if (!node.content.trim() || isConstantExpression(node)) return [[ content, NewlineType.None, loc ], assignment && ` = ${assignment}`]; if (!ast) return genIdentifier(content, context, loc, assignment); const ids = []; const parentStackMap = /* @__PURE__ */ new Map(); const parentStack = []; (0, ast_kit.walkIdentifiers)(ast, (id) => { ids.push(id); parentStackMap.set(id, parentStack.slice()); }, false, parentStack); let hasMemberExpression = false; if (ids.length) { const [frag, push] = buildCodeFragment(); const isTSNode = ast && TS_NODE_TYPES.includes(ast.type); const offset = (ast?.start ? ast.start - 1 : 0) - (needWrap ? 7 : 0); ids.sort((a, b) => a.start - b.start).forEach((id, i) => { const start = id.start - 1 - offset; const end = id.end - 1 - offset; const last = ids[i - 1]; if (!isTSNode || i !== 0) { const leadingText = content.slice(last ? last.end - 1 - offset : 0, start); if (leadingText.length) push([leadingText, NewlineType.Unknown]); } const source = content.slice(start, end); const parentStack$1 = parentStackMap.get(id); const parent = parentStack$1.at(-1); hasMemberExpression ||= !!parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression"); push(...genIdentifier(source, context, { start: advancePositionWithClone(node.loc.start, source, start), end: advancePositionWithClone(node.loc.start, source, end), filename: "", identifierName: void 0 }, hasMemberExpression ? void 0 : assignment, parent)); if (i === ids.length - 1 && end < content.length && !isTSNode) push([content.slice(end), NewlineType.Unknown]); }); if (assignment && hasMemberExpression) push(` = ${assignment}`); return frag; } else return [[ content, NewlineType.Unknown, loc ]]; } function genIdentifier(raw, context, loc, assignment, parent) { const { identifiers } = context; const name = raw; const idMap = identifiers[raw]; if (idMap && idMap.length) { const replacement = idMap[0]; if ((0, __vue_shared.isString)(replacement)) if (parent && parent.type === "ObjectProperty" && parent.shorthand) return [[ `${name}: ${replacement}`, NewlineType.None, loc ]]; else return [[ replacement, NewlineType.None, loc ]]; else return genExpression(replacement, context, assignment); } let prefix; if (isStaticProperty(parent) && parent.shorthand) prefix = `${raw}: `; raw = withAssignment(raw); return [prefix, [ raw, NewlineType.None, loc, name ]]; function withAssignment(s) { return assignment ? `${s} = ${assignment}` : s; } } //#endregion //#region src/generators/vModel.ts const helperMap = { text: "applyTextModel", radio: "applyRadioModel", checkbox: "applyCheckboxModel", select: "applySelectModel", dynamic: "applyDynamicModel" }; function genVModel(oper, context) { const { modelType, element, dir: { exp, modifiers } } = oper; return [NEWLINE, ...genCall(context.helper(helperMap[modelType]), `n${element}`, [ `() => (`, ...genExpression(exp, context), `)` ], genModelHandler(exp, context), modifiers.length ? `{ ${modifiers.map((e) => `${e.content}: true`).join(",")} }` : void 0)]; } function genModelHandler(exp, context) { return [ "_value => (", ...genExpression(exp, context, "_value"), ")" ]; } //#endregion //#region src/generators/vShow.ts function genVShow(oper, context) { return [NEWLINE, ...genCall(context.helper("applyVShow"), `n${oper.element}`, [ `() => (`, ...genExpression(oper.dir.exp, context), `)` ])]; } //#endregion //#region src/generators/directive.ts function genBuiltinDirective(oper, context) { switch (oper.name) { case "show": return genVShow(oper, context); case "model": return genVModel(oper, context); default: return []; } } /** * user directives via `withVaporDirectives` * TODO the compiler side is implemented but no runtime support yet * it was removed due to perf issues */ function genDirectivesForElement(id, context) { const dirs = filterCustomDirectives(id, context.block.operation); return dirs.length ? genCustomDirectives(dirs, context) : []; } function genCustomDirectives(opers, context) { const { helper } = context; const element = `n${opers[0].element}`; const directiveItems = opers.map(genDirectiveItem); const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems); return [NEWLINE, ...genCall(helper("withVaporDirectives"), element, directives)]; function genDirectiveItem({ dir, name, asset }) { const directiveVar = asset ? toValidAssetId(name, "directive") : genExpression(createSimpleExpression(name), context); const value = dir.exp && ["() => ", ...genExpression(dir.exp, context)]; const argument = dir.arg && genExpression(dir.arg, context); const modifiers = !!dir.modifiers.length && [ "{ ", genDirectiveModifiers(dir.modifiers.map((m) => m.content)), " }" ]; return genMulti(DELIMITERS_ARRAY.concat("void 0"), directiveVar, value, argument, modifiers); } } function genDirectiveModifiers(modifiers) { return modifiers.map((value) => `${isSimpleIdentifier(value) ? value : JSON.stringify(value)}: true`).join(", "); } function filterCustomDirectives(id, operations) { return operations.filter((oper) => oper.type === IRNodeTypes.DIRECTIVE && oper.element === id && !oper.builtin); } //#endregion //#region src/generators/event.ts function genSetEvent(oper, context) { const { helper } = context; const { element, key, keyOverride, value, modifiers, delegate, effect } = oper; const name = genName(); const handler = genEventHandler(context, value, modifiers); const eventOptions = genEventOptions(); if (delegate) { context.delegates.add(key.content); if (!context.block.operation.some(isSameDelegateEvent)) return [ NEWLINE, `n${element}.$evt${key.content} = `, ...handler ]; } return [NEWLINE, ...genCall(helper(delegate ? "delegate" : "on"), `n${element}`, name, handler, eventOptions)]; function genName() { const expr = genExpression(key, context); if (keyOverride) { const find = JSON.stringify(keyOverride[0]); const replacement = JSON.stringify(keyOverride[1]); const wrapped = [ "(", ...expr, ")" ]; return [ ...wrapped, ` === ${find} ? ${replacement} : `, ...wrapped ]; } else return genExpression(key, context); } function genEventOptions() { const { options } = modifiers; if (!options.length && !effect) return; return genMulti(DELIMITERS_OBJECT_NEWLINE, effect && ["effect: true"], ...options.map((option) => [`${option}: true`])); } function isSameDelegateEvent(op) { if (op.type === IRNodeTypes.SET_EVENT && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true; } } function genSetDynamicEvents(oper, context) { const { helper } = context; return [NEWLINE, ...genCall(helper("setDynamicEvents"), `n${oper.element}`, genExpression(oper.event, context))]; } function genEventHandler(context, value, modifiers = { nonKeys: [], keys: [] }, extraWrap = false) { let handlerExp = [`() => {}`]; if (value && value.content.trim()) if (isMemberExpression(value)) { handlerExp = genExpression(value, context); if (!extraWrap) handlerExp = [ `e => `, ...handlerExp, `(e)` ]; } else if (isFnExpression(value)) handlerExp = genExpression(value, context); else { const hasMultipleStatements = value.content.includes(`;`); handlerExp = [ "() => ", hasMultipleStatements ? "{" : "(", ...genExpression(value, context), hasMultipleStatements ? "}" : ")" ]; } const { keys, nonKeys } = modifiers; if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys); if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys); if (extraWrap) handlerExp.unshift(`() => `); return handlerExp; } function genWithModifiers(context, handler, nonKeys) { return genCall(context.helper("withModifiers"), handler, JSON.stringify(nonKeys)); } function genWithKeys(context, handler, keys) { return genCall(context.helper("withKeys"), handler, JSON.stringify(keys)); } //#endregion //#region src/generators/prop.ts const helpers = { setText: { name: "setText" }, setHtml: { name: "setHtml" }, setClass: { name: "setClass" }, setStyle: { name: "setStyle" }, setValue: { name: "setValue" }, setAttr: { name: "setAttr", needKey: true }, setProp: { name: "setProp", needKey: true }, setDOMProp: { name: "setDOMProp", needKey: true }, setDynamicProps: { name: "setDynamicProps" } }; function genSetProp(oper, context) { const { helper } = context; const { prop: { key, values, modifier }, tag } = oper; const resolvedHelper = getRuntimeHelper(tag, key.content, modifier); const propValue = genPropValue(values, context); return [NEWLINE, ...genCall([helper(resolvedHelper.name), null], `n${oper.element}`, resolvedHelper.needKey ? genExpression(key, context) : false, propValue)]; } function genDynamicProps(oper, context) { const { helper } = context; const values = oper.props.map((props) => Array.isArray(props) ? genLiteralObjectProps(props, context) : props.kind === IRDynamicPropsKind.ATTRIBUTE ? genLiteralObjectProps([props], context) : genExpression(props.value, context)); return [NEWLINE, ...genCall(helper("setDynamicProps"), `n${oper.element}`, genMulti(DELIMITERS_ARRAY, ...values), oper.root && "true")]; } function genLiteralObjectProps(props, context) { return genMulti(DELIMITERS_OBJECT, ...props.map((prop) => [ ...genPropKey(prop, context), `: `, ...genPropValue(prop.values, context) ])); } function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModifiers }, context) { const { helper } = context; const handlerModifierPostfix = handlerModifiers && handlerModifiers.options ? handlerModifiers.options.map(__vue_shared.capitalize).join("") : ""; if (node.isStatic) { const keyName = (handler ? (0, __vue_shared.toHandlerKey)(node.content) : node.content) + handlerModifierPostfix; return [[ isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName), NewlineType.None, node.loc ]]; } let key = genExpression(node, context); if (runtimeCamelize) key = genCall(helper("camelize"), key); if (handler) key = genCall(helper("toHandlerKey"), key); return [ "[", modifier && `${JSON.stringify(modifier)} + `, ...key, handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : void 0, "]" ]; } function genPropValue(values, context) { if (values.length === 1) return genExpression(values[0], context); return genMulti(DELIMITERS_ARRAY, ...values.map((expr) => genExpression(expr, context))); } function getRuntimeHelper(tag, key, modifier) { const tagName = tag.toUpperCase(); if (modifier) if (modifier === ".") return getSpecialHelper(key, tagName) || helpers.setDOMProp; else return helpers.setAttr; const helper = getSpecialHelper(key, tagName); if (helper) return helper; if (/aria[A-Z]/.test(key)) return helpers.setDOMProp; if ((0, __vue_shared.isSVGTag)(tag)) return helpers.setAttr; if ((0, __vue_shared.shouldSetAsAttr)(tagName, key) || key.includes("-")) return helpers.setAttr; return helpers.setProp; } function getSpecialHelper(keyName, tagName) { if (keyName === "value" && (0, __vue_shared.canSetValueDirectly)(tagName)) return helpers.setValue; else if (keyName === "class") return helpers.setClass; else if (keyName === "style") return helpers.setStyle; else if (keyName === "innerHTML") return helpers.setHtml; else if (keyName === "textContent") return helpers.setText; } //#endregion //#region src/generators/component.ts function genCreateComponent(operation, context) { const { helper } = context; const tag = genTag(); const { root, props, slots, once } = operation; const rawProps = genRawProps(props, context); const rawSlots = genRawSlots(slots, context); return [ NEWLINE, `const n${operation.id} = `, ...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"), ...genDirectivesForElement(operation.id, context) ]; function genTag() { if (operation.dynamic) if (operation.dynamic.isStatic) return genCall(helper("resolveDynamicComponent"), genExpression(operation.dynamic, context)); else return [ "() => (", ...genExpression(operation.dynamic, context), ")" ]; else if (operation.asset) return toValidAssetId(operation.tag, "component"); else return genExpression(createSimpleExpression(operation.tag), context); } } function genRawProps(props, context) { const staticProps = props[0]; if ((0, __vue_shared.isArray)(staticProps)) { if (!staticProps.length && props.length === 1) return; return genStaticProps(staticProps, context, genDynamicProps$1(props.slice(1), context)); } else if (props.length) return genStaticProps([], context, genDynamicProps$1(props, context)); } function genStaticProps(props, context, dynamicProps) { const args = props.map((prop) => genProp(prop, context, true)); if (dynamicProps) args.push([`$: `, ...dynamicProps]); return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args); } function genDynamicProps$1(props, context) { const { helper } = context; const frags = []; for (const p of props) { let expr; if ((0, __vue_shared.isArray)(p)) { if (p.length) frags.push(genStaticProps(p, context)); continue; } else if (p.kind === IRDynamicPropsKind.ATTRIBUTE) expr = genMulti(DELIMITERS_OBJECT, genProp(p, context)); else { expr = genExpression(p.value, context); if (p.handler) expr = genCall(helper("toHandlers"), expr); } frags.push([ "() => (", ...expr, ")" ]); } if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags); } function genProp(prop, context, isStatic) { const values = genPropValue(prop.values, context); return [ ...genPropKey(prop, context), ": ", ...prop.handler ? genEventHandler(context, prop.values[0], prop.handlerModifiers, true) : isStatic ? [ "() => (", ...values, ")" ] : values, ...prop.model ? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)] : [] ]; } function genModelEvent(prop, context) { const name = prop.key.isStatic ? [JSON.stringify(`onUpdate:${(0, __vue_shared.camelize)(prop.key.content)}`)] : [ "[\"onUpdate:\" + ", ...genExpression(prop.key, context), "]" ]; const handler = genModelHandler(prop.values[0], context); return [ ",", NEWLINE, ...name, ": () => ", ...handler ]; } function genModelModifiers(prop, context) { const { key, modelModifiers } = prop; if (!modelModifiers || !modelModifiers.length) return []; const modifiersKey = key.isStatic ? [`${key.content}Modifiers`] : [ "[", ...genExpression(key, context), " + \"Modifiers\"]" ]; const modifiersVal = genDirectiveModifiers(modelModifiers); return [ ",", NEWLINE, ...modifiersKey, `: () => ({ ${modifiersVal} })` ]; } function genRawSlots(slots, context) { if (!slots.length) return; const staticSlots = slots[0]; if (staticSlots.slotType === IRSlotType.STATIC) return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0); else return genStaticSlots({ slotType: IRSlotType.STATIC, slots: {} }, context, slots); } function genStaticSlots({ slots }, context, dynamicSlots) { const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]); if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]); return genMulti(DELIMITERS_OBJECT_NEWLINE, ...args); } function genDynamicSlots(slots, context) { return genMulti(DELIMITERS_ARRAY_NEWLINE, ...slots.map((slot) => slot.slotType === IRSlotType.STATIC ? genStaticSlots(slot, context) : slot.slotType === IRSlotType.EXPRESSION ? slot.slots.content : genDynamicSlot(slot, context, true))); } function genDynamicSlot(slot, context, withFunction = false) { let frag; switch (slot.slotType) { case IRSlotType.DYNAMIC: frag = genBasicDynamicSlot(slot, context); break; case IRSlotType.LOOP: frag = genLoopSlot(slot, context); break; case IRSlotType.CONDITIONAL: frag = genConditionalSlot(slot, context); break; } return withFunction ? [ "() => (", ...frag, ")" ] : frag; } function genBasicDynamicSlot(slot, context) { const { name, fn } = slot; return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]); } function genLoopSlot(slot, context) { const { name, fn, loop } = slot; const { value, key, index, source } = loop; const rawValue = value && value.content; const rawKey = key && key.content; const rawIndex = index && index.content; const idMap = {}; if (rawValue) idMap[rawValue] = rawValue; if (rawKey) idMap[rawKey] = rawKey; if (rawIndex) idMap[rawIndex] = rawIndex; const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context), idMap)]); return [...genCall(context.helper("createForSlots"), genExpression(source, context), [ ...genMulti([ "(", ")", ", " ], rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0, rawKey ? rawKey : rawIndex ? "__" : void 0, rawIndex), " => (", ...slotExpr, ")" ])]; } function genConditionalSlot(slot, context) { const { condition, positive, negative } = slot; return [ ...genExpression(condition, context), INDENT_START, NEWLINE, "? ", ...genDynamicSlot(positive, context), NEWLINE, ": ", ...negative ? [...genDynamicSlot(negative, context)] : ["void 0"], INDENT_END ]; } function genSlotBlockWithProps(oper, context) { let isDestructureAssignment = false; let rawProps; let propsName; let exitScope; let depth; const { props } = oper; const idsOfProps = /* @__PURE__ */ new Set(); if (props) { rawProps = props.content; if (isDestructureAssignment = !!props.ast) { [depth, exitScope] = context.enterScope(); propsName = `_slotProps${depth}`; (0, ast_kit.walkIdentifiers)(props.ast, (id, _, __, isReference, isLocal) => { if (isReference && !isLocal) idsOfProps.add(id.name); }, true); } else idsOfProps.add(propsName = rawProps); } const idMap = {}; idsOfProps.forEach((id) => idMap[id] = isDestructureAssignment ? `${propsName}[${JSON.stringify(id)}]` : null); const blockFn = context.withId(() => genBlock(oper, context, [propsName]), idMap); exitScope && exitScope(); return blockFn; } //#endregion //#region src/generators/dom.ts function genInsertNode({ parent, elements, anchor }, { helper }) { let element = elements.map((el) => `n${el}`).join(", "); if (elements.length > 1) element = `[${element}]`; return [NEWLINE, ...genCall(helper("insert"), element, `n${parent}`, anchor === void 0 ? void 0 : `n${anchor}`)]; } function genPrependNode(oper, { helper }) { return [NEWLINE, ...genCall(helper("prepend"), `n${oper.parent}`, ...oper.elements.map((el) => `n${el}`))]; } //#endregion //#region src/generators/for.ts /** * Flags to optimize vapor `createFor` runtime behavior, shared between the * compiler and the runtime */ let VaporVForFlags = /* @__PURE__ */ function(VaporVForFlags$1) { /** * v-for is the only child of a parent container, so it can take the fast * path with textContent = '' when the whole list is emptied */ VaporVForFlags$1[VaporVForFlags$1["FAST_REMOVE"] = 1] = "FAST_REMOVE"; /** * v-for used on component - we can skip creating child scopes for each block * because the component itself already has a scope. */ VaporVForFlags$1[VaporVForFlags$1["IS_COMPONENT"] = 2] = "IS_COMPONENT"; /** * v-for inside v-ince */ VaporVForFlags$1[VaporVForFlags$1["ONCE"] = 4] = "ONCE"; return VaporVForFlags$1; }({}); function genFor(oper, context) { const { helper } = context; const { source, value, key, index, render, keyProp, once, id, component, onlyChild } = oper; let rawValue = null; const rawKey = key && key.content; const rawIndex = index && index.content; const sourceExpr = [ "() => (", ...genExpression(source, context), ")" ]; const idToPathMap = parseValueDestructure(); const [depth, exitScope] = context.enterScope(); const idMap = {}; const itemVar = `_for_item${depth}`; idMap[itemVar] = null; idToPathMap.forEach((pathInfo, id$1) => { let path = `${itemVar}.value${pathInfo ? pathInfo.path : ""}`; if (pathInfo) { if (pathInfo.helper) { idMap[pathInfo.helper] = null; path = `${pathInfo.helper}(${path}, ${pathInfo.helperArgs})`; } if (pathInfo.dynamic) { const node = idMap[id$1] = createSimpleExpression(path); node.ast = (0, __babel_parser.parseExpression)(`(${path})`, { plugins: context.options.expressionPlugins }); } else idMap[id$1] = path; } else idMap[id$1] = path; }); const args = [itemVar]; if (rawKey) { const keyVar = `_for_key${depth}`; args.push(`, ${keyVar}`); idMap[rawKey] = `${keyVar}.value`; idMap[keyVar] = null; } if (rawIndex) { const indexVar = `_for_index${depth}`; args.push(`, ${indexVar}`); idMap[rawIndex] = `${indexVar}.value`; idMap[indexVar] = null; } const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap, context.ir.source); const selectorDeclarations = []; const selectorSetup = []; for (const [i, { selector }] of selectorPatterns.entries()) { const selectorName = `_selector${id}_${i}`; selectorDeclarations.push(`let ${selectorName}`, NEWLINE); if (i === 0) selectorSetup.push(`({ createSelector }) => {`, INDENT_START); selectorSetup.push(NEWLINE, `${selectorName} = `, ...genCall(`createSelector`, [`() => `, ...genExpression(selector, context)])); if (i === selectorPatterns.length - 1) selectorSetup.push(INDENT_END, NEWLINE, "}"); } const blockFn = context.withId(() => { const frag = []; frag.push("(", ...args, ") => {", INDENT_START); if (selectorPatterns.length || keyOnlyBindingPatterns.length) frag.push(...genBlockContent(render, context, false, () => { const patternFrag = []; for (const [i, { effect }] of selectorPatterns.entries()) { patternFrag.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START); for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context)); patternFrag.push(INDENT_END, NEWLINE, `})`); } for (const { effect } of keyOnlyBindingPatterns) for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context)); return patternFrag; })); else frag.push(...genBlockContent(render, context)); frag.push(INDENT_END, NEWLINE, "}"); return frag; }, idMap); exitScope(); let flags = 0; if (onlyChild) flags |= VaporVForFlags.FAST_REMOVE; if (component) flags |= VaporVForFlags.IS_COMPONENT; if (once) flags |= VaporVForFlags.ONCE; return [ NEWLINE, ...selectorDeclarations, `const n${id} = `, ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0, selectorSetup.length ? selectorSetup : void 0) ]; function parseValueDestructure() { const map = /* @__PURE__ */ new Map(); if (value) { rawValue = value && value.content; if (value.ast && value.ast.type !== "Identifier") (0, ast_kit.walkIdentifiers)(value.ast, (id$1, _, parentStack, isReference, isLocal) => { if (isReference && !isLocal) { let path = ""; let isDynamic = false; let helper$1; let helperArgs; for (let i = 0; i < parentStack.length; i++) { const parent = parentStack[i]; const child = parentStack[i + 1] || id$1; if (parent.type === "ObjectProperty" && parent.value === child) if (parent.key.type === "StringLiteral") path += `[${JSON.stringify(parent.key.value)}]`; else if (parent.computed) { isDynamic = true; path += `[${value.content.slice(parent.key.start - 1, parent.key.end - 1)}]`; } else path += `.${parent.key.name}`; else if (parent.type === "ArrayExpression") { const index$1 = parent.elements.indexOf(child); if (child.type === "SpreadElement") path += `.slice(${index$1})`; else path += `[${index$1}]`; } else if (parent.type === "ObjectExpression" && child.type === "SpreadElement") { helper$1 = context.helper("getRestElement"); helperArgs = `[${parent.properties.filter((p) => p.type === "ObjectProperty").map((p) => { if (p.key.type === "StringLiteral") return JSON.stringify(p.key.value); else if (p.computed) { isDynami