/** * @vue/compiler-vapor v3.6.0-rc.10 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT **/ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); let _vue_compiler_dom = require("@vue/compiler-dom"); let _vue_shared = require("@vue/shared"); let source_map_js = require("source-map-js"); let _babel_parser = require("@babel/parser"); let estree_walker = require("estree-walker"); //#region packages/compiler-vapor/src/ir/component.ts const IRDynamicPropsKind = { "EXPRESSION": 0, "0": "EXPRESSION", "ATTRIBUTE": 1, "1": "ATTRIBUTE" }; const IRSlotType = { "STATIC": 0, "0": "STATIC", "DYNAMIC": 1, "1": "DYNAMIC", "LOOP": 2, "2": "LOOP", "CONDITIONAL": 3, "3": "CONDITIONAL", "EXPRESSION": 4, "4": "EXPRESSION" }; //#endregion //#region packages/compiler-vapor/src/ir/index.ts const IRNodeTypes = { "ROOT": 0, "0": "ROOT", "BLOCK": 1, "1": "BLOCK", "SET_BLOCK_KEY": 2, "2": "SET_BLOCK_KEY", "SET_PROP": 3, "3": "SET_PROP", "SET_DYNAMIC_PROPS": 4, "4": "SET_DYNAMIC_PROPS", "SET_TEXT": 5, "5": "SET_TEXT", "SET_EVENT": 6, "6": "SET_EVENT", "SET_DYNAMIC_EVENTS": 7, "7": "SET_DYNAMIC_EVENTS", "SET_HTML": 8, "8": "SET_HTML", "SET_TEMPLATE_REF": 9, "9": "SET_TEMPLATE_REF", "INSERT_NODE": 10, "10": "INSERT_NODE", "CREATE_COMPONENT_NODE": 11, "11": "CREATE_COMPONENT_NODE", "SLOT_OUTLET_NODE": 12, "12": "SLOT_OUTLET_NODE", "DIRECTIVE": 13, "13": "DIRECTIVE", "IF": 14, "14": "IF", "FOR": 15, "15": "FOR", "KEY": 16, "16": "KEY", "GET_TEXT_CHILD": 17, "17": "GET_TEXT_CHILD" }; var TemplateRegistry = class { constructor() { this.entries = []; } keys() { return this.entries.map(({ content }) => content); } }; const DynamicFlag = { "NONE": 0, "0": "NONE", "REFERENCED": 1, "1": "REFERENCED", "NON_TEMPLATE": 2, "2": "NON_TEMPLATE", "INSERT": 4, "4": "INSERT" }; function isBlockOperation(op) { const type = op.type; return type === 11 || type === 12 || type === 14 || type === 16 || type === 15; } //#endregion //#region packages/compiler-vapor/src/transforms/utils.ts const newDynamic = () => ({ flags: 1, children: [] }); const newBlock = (node) => ({ type: 1, node, dynamic: newDynamic(), effect: [], operation: [], returns: [], tempId: 0 }); function wrapTemplate(node, dirs) { if (node.tagType === 3) { const otherStructuralDirs = [ "if", "else-if", "else", "for" ]; if (!node.props.some((prop) => prop.type === 7 && otherStructuralDirs.includes(prop.name) && !dirs.includes(prop.name))) return node; const reserved = []; const pass = []; node.props.forEach((prop) => { if (prop.type === 7 && dirs.includes(prop.name)) reserved.push(prop); else pass.push(prop); }); return (0, _vue_shared.extend)({}, node, { type: 1, tag: "template", props: reserved, tagType: 3, children: [(0, _vue_shared.extend)({}, node, { props: pass })] }); } const reserved = []; const pass = []; node.props.forEach((prop) => { if (prop.type === 7 && (dirs.includes(prop.name) || prop.name === "bind" && prop.arg && prop.arg.type === 4 && prop.arg.content === "key" && dirs.includes("key"))) reserved.push(prop); else pass.push(prop); }); return (0, _vue_shared.extend)({}, node, { type: 1, tag: "template", props: reserved, tagType: 3, children: [(0, _vue_shared.extend)({}, node, { props: pass })] }); } const EMPTY_EXPRESSION = (0, _vue_compiler_dom.createSimpleExpression)("", true); //#endregion //#region packages/compiler-vapor/src/utils.ts const findProp$1 = _vue_compiler_dom.findProp; /** find directive */ const findDir$5 = _vue_compiler_dom.findDir; function propToExpression(prop) { return prop.type === 6 ? prop.value ? (0, _vue_compiler_dom.createSimpleExpression)(prop.value.content, true, prop.value.loc) : EMPTY_EXPRESSION : prop.exp; } function isConstantExpression(exp) { return (0, _vue_compiler_dom.isLiteralWhitelisted)(exp.content) || (0, _vue_shared.isGloballyAllowed)(exp.content) || getLiteralExpressionValue(exp) !== null; } function isConstantBinding$1(exp, bindings) { return isConstantExpression(exp) || isStaticExpression(exp, bindings); } function isStaticExpression(node, bindings) { if (node.ast) return (0, _vue_compiler_dom.isConstantNode)(node.ast, bindings); else if (node.ast === null) { if (!node.isStatic && (node.content === "true" || node.content === "false" || node.content === "null")) return true; return bindings[node.content] === "literal-const"; } return false; } function resolveExpression(exp, isComponent) { if (!exp.isStatic) { const value = getLiteralExpressionValue(exp, isComponent); if (value !== null) return (0, _vue_compiler_dom.createSimpleExpression)(value, true, exp.loc); } return exp; } function getLiteralExpressionValue(exp, excludeNumber) { if (exp.ast) { if (exp.ast.type === "StringLiteral") return exp.ast.value; else if (!excludeNumber && (exp.ast.type === "NumericLiteral" || exp.ast.type === "BigIntLiteral")) return String(exp.ast.value); else if (exp.ast.type === "TemplateLiteral") { let result = ""; for (const [index, quasi] of exp.ast.quasis.entries()) { result += quasi.value.cooked; if (exp.ast.expressions[index]) { let expressionValue = getLiteralExpressionValue({ ast: exp.ast.expressions[index] }); if (expressionValue == null) return null; else result += expressionValue; } } return result; } } return exp.isStatic ? exp.content : null; } function isInTransition(context) { const parentNode = context.parent && context.parent.node; return !!(parentNode && isTransitionNode(parentNode)); } function isTransitionNode(node) { return node.type === 1 && isTransitionTag(node.tag); } /** Transition or TransitionGroup: hosts whose children render specially. */ function isTransitionHostNode(node) { return node.type === 1 && (isTransitionTag(node.tag) || isTransitionGroupTag(node.tag)); } function isTransitionTag(tag) { tag = tag.toLowerCase(); return tag === "transition" || tag === "vaportransition"; } function isTransitionGroupTag(tag) { tag = tag.toLowerCase().replace(/-/g, ""); return tag === "transitiongroup" || tag === "vaportransitiongroup"; } function isKeepAliveTag(tag) { tag = tag.toLowerCase().replace(/-/g, ""); return tag === "keepalive" || tag === "vaporkeepalive"; } function isTeleportTag(tag) { tag = tag.toLowerCase(); return tag === "teleport" || tag === "vaporteleport"; } function isComponentTag(tag) { return tag === "component" || tag === "Component"; } function isBuiltInComponent(tag) { if (isTeleportTag(tag)) return "VaporTeleport"; else if (tag === "Suspense" || tag === "suspense") return "Suspense"; else if (isKeepAliveTag(tag)) return "VaporKeepAlive"; else if (isTransitionTag(tag)) return "VaporTransition"; else if (isTransitionGroupTag(tag)) return "VaporTransitionGroup"; } function getBlockShape(block) { if (block.returns.length !== 1) return 2; const root = block.dynamic.children.find((c) => c.id === block.returns[0]); if (root && root.operation && root.operation.type === 14) return 2; return block.node.type === 1 && block.node.children.every((child) => child.type === 2 || child.type === 5) ? 2 : 1; } //#endregion //#region packages/compiler-vapor/src/transform.ts const generatedVarRE = /^[nxr](\d+)$/; const childContextInfoCache = /* @__PURE__ */ new WeakMap(); var TransformContext = class TransformContext { constructor(ir, node, options = {}) { this.ir = ir; this.node = node; this.selfName = null; this.parent = null; this.effectiveParent = null; this.index = 0; this.block = this.ir.block; this.template = ""; this.templateRoot = false; this.templateIndexMap = /* @__PURE__ */ new Map(); this.childrenTemplate = []; this.dynamic = this.ir.block.dynamic; this.imports = []; this.inVOnce = false; this.inVFor = 0; this.comment = []; this.component = this.ir.component; this.directive = this.ir.directive; this.slots = []; this.effectIndex = this.block.effect.length; this.operationIndex = this.block.operation.length; this.isLastEffectiveChild = true; this.isOnRightmostPath = true; this.isSingleRoot = false; this.templateCloseTags = void 0; this.templateCloseBlocks = false; this.globalId = 0; this.nextIdMap = null; this.ifIndex = 0; this.increaseId = () => { const id = getNextId(this.nextIdMap, this.globalId); this.globalId = getNextId(this.nextIdMap, id + 1); return id; }; this.options = (0, _vue_shared.extend)({}, defaultOptions, options); this.root = this; if (options.filename) this.selfName = (0, _vue_compiler_dom.getSelfName)(options.filename); this.initNextIdMap(); } enterBlock(ir, isVFor = false) { const { block, template, templateRoot, templateIndexMap, dynamic, childrenTemplate, slots, effectIndex, operationIndex } = this; this.block = ir; this.dynamic = ir.dynamic; this.template = ""; this.templateRoot = false; this.templateIndexMap = templateIndexMap; this.childrenTemplate = []; this.slots = []; this.effectIndex = ir.effect.length; this.operationIndex = ir.operation.length; isVFor && this.inVFor++; return () => { this.registerTemplate(); this.block = block; this.template = template; this.templateRoot = templateRoot; this.templateIndexMap = templateIndexMap; this.dynamic = dynamic; this.childrenTemplate = childrenTemplate; this.slots = slots; this.effectIndex = effectIndex; this.operationIndex = operationIndex; isVFor && this.inVFor--; }; } initNextIdMap() { const binding = this.root.options.bindingMetadata; if (!binding) return; const keys = Object.keys(binding); if (keys.length === 0) return; const numbers = /* @__PURE__ */ new Set(); for (const name of keys) { const m = generatedVarRE.exec(name); if (m) numbers.add(Number(m[1])); } if (numbers.size === 0) return; this.globalId = getNextId(this.nextIdMap = buildNextIdMap(numbers), 0); } reference() { if (this.dynamic.id !== void 0) return this.dynamic.id; this.dynamic.flags |= 1; return this.dynamic.id = this.increaseId(); } nextIfIndex() { return this.ifIndex++; } getTemplateNamespace() { return this.node.type === 1 ? this.node.ns : 0; } canUseStaticTemplate() { if (!this.template) return false; if (this.inVFor) return false; if (this.dynamic.hasDynamicChild) return false; if (this.block.effect.length !== this.effectIndex) return false; if (this.block.operation.length !== this.operationIndex) return false; if (this.node.type === 2 || this.node.type === 3) return true; return this.node.type === 1 && this.node.tagType === 0 && !(this.options.isCustomElement(this.node.tag) || this.node.tag === "template"); } pushTemplate(content, { root = false, static: isStatic = false } = {}) { const templateKey = JSON.stringify([ this.getTemplateNamespace(), root, isStatic, content ]); const existingIndex = this.templateIndexMap.get(templateKey); if (existingIndex !== void 0) return existingIndex; const ns = this.getTemplateNamespace(); const newIndex = this.ir.template.entries.length; this.ir.template.entries.push({ content, ns, root, static: isStatic }); this.templateIndexMap.set(templateKey, newIndex); return newIndex; } registerTemplate() { if (!this.template) return -1; const id = this.pushTemplate(this.template, { root: this.templateRoot, static: this.canUseStaticTemplate() }); return this.dynamic.template = id; } registerEffect(expressions, operation, getIndex, preserveOrder = false) { const operations = [operation].flat(); expressions = expressions.filter((exp) => !isConstantExpression(exp)); const once = expressions.every((e) => isConstantBinding$1(e, this.root.options.bindingMetadata)); const needsEffect = operations.some((op) => op.type === 4 && op.listeners); if (this.inVOnce || once && !preserveOrder && !needsEffect) { this.registerOperation(...operations); return false; } const index = getIndex ? getIndex() : this.block.effect.length; this.block.effect.splice(index, 0, { expressions, operations, ...once && !needsEffect ? { once: true } : {} }); if (getIndex) this.shiftEffectBoundaries(index); return true; } registerOperation(...node) { this.block.operation.push(...node); } effectBoundary() { return { operationIndex: this.operationIndex, effectIndex: this.effectIndex }; } create(node, index) { let effectiveParent = this; while (effectiveParent && effectiveParent.node.type === 1 && effectiveParent.node.tagType === 3) effectiveParent = effectiveParent.parent; const childInfo = this.getChildContextInfo(); const isLastEffectiveChild = childInfo.isLastEffectiveChild[index]; const isOnRightmostPath = this.isOnRightmostPath && isLastEffectiveChild; const isSingleRoot = this.isSingleRootChild(childInfo); return Object.assign(Object.create(TransformContext.prototype), this, { node, parent: this, index, inVOnce: this.inVOnce && !isComponentNode(this.node), template: "", templateRoot: false, childrenTemplate: [], templateIndexMap: this.templateIndexMap, dynamic: newDynamic(), effectIndex: this.block.effect.length, operationIndex: this.block.operation.length, effectiveParent, isLastEffectiveChild, isOnRightmostPath, isSingleRoot, templateCloseTags: this.templateCloseTags, templateCloseBlocks: this.templateCloseBlocks }); } shiftEffectBoundaries(index, dynamic = this.dynamic) { const operation = dynamic.operation; if (operation && isBlockOperation(operation) && operation.effectIndex !== void 0 && operation.effectIndex >= index) operation.effectIndex++; for (const child of dynamic.children) this.shiftEffectBoundaries(index, child); } getChildContextInfo() { const node = this.node; if (node.type !== 0 && node.type !== 1) return { node, hasSingleRootChild: true, isLastEffectiveChild: [] }; const cached = childContextInfoCache.get(this); if (cached && cached.node === node) return cached; const { children } = node; const isLastEffectiveChild = new Array(children.length); let hasFollowingEffectiveChild = false; for (let i = children.length - 1; i >= 0; i--) { isLastEffectiveChild[i] = !hasFollowingEffectiveChild; if (!isComponentChild(children[i])) hasFollowingEffectiveChild = true; } const childInfo = { node, hasSingleRootChild: hasSingleRootChild(children), isLastEffectiveChild }; childContextInfoCache.set(this, childInfo); return childInfo; } isSingleRootChild(childInfo) { if (this.inVFor || !childInfo.hasSingleRootChild) return false; if (this.node.type === 0) return true; return this.node.type === 1 && (this.node.tagType === 3 || isTransitionNode(this.node) || isKeepAliveTag(this.node.tag)) && !!this.parent && this.isSingleRoot; } }; function hasSingleRootChild(children) { let nonCommentChildren = 0; let hasEncounteredIf = false; let isSingleIfBlock = true; for (const child of children) { if ((0, _vue_compiler_dom.isCommentOrWhitespace)(child)) continue; nonCommentChildren++; if (isIfChild(child)) { if (hasEncounteredIf) isSingleIfBlock = false; hasEncounteredIf = true; } else if (!hasEncounteredIf || !isElseChild(child)) isSingleIfBlock = false; } return nonCommentChildren === 1 || isSingleIfBlock; } function isComponentChild(child) { return child.type === 1 && child.tagType === 1; } function isIfChild(child) { return child.type === 9 || child.type === 1 && !!(0, _vue_compiler_dom.findDir)(child, "if"); } function isElseChild(child) { return child.type === 1 && !!(0, _vue_compiler_dom.findDir)(child, /^else(-if)?$/, true); } const defaultOptions = { filename: "", prefixIdentifiers: true, hoistStatic: false, hmr: false, cacheHandlers: false, nodeTransforms: [], directiveTransforms: {}, transformHoist: null, isBuiltInComponent: _vue_shared.NOOP, isCustomElement: _vue_shared.NOOP, expressionPlugins: [], scopeId: null, slotted: true, ssr: false, inSSR: false, ssrCssVars: ``, bindingMetadata: _vue_shared.EMPTY_OBJ, inline: false, isTS: false, onError: _vue_compiler_dom.defaultOnError, onWarn: _vue_compiler_dom.defaultOnWarn }; function transform(node, options = {}) { const ir = { type: 0, node, source: node.source, template: new TemplateRegistry(), component: /* @__PURE__ */ new Set(), directive: /* @__PURE__ */ new Set(), block: newBlock(node), hasTemplateRef: false }; const context = new TransformContext(ir, node, options); transformNode(context); ir.node.imports = context.imports; return ir; } function transformNode(context) { let { node } = context; const { nodeTransforms } = context.options; const exitFns = []; for (const nodeTransform of nodeTransforms) { const onExit = nodeTransform(node, context); if (onExit) { if ((0, _vue_shared.isArray)(onExit)) exitFns.push(...onExit); else exitFns.push(onExit); } if (!context.node) return; else node = context.node; } context.node = node; let i = exitFns.length; while (i--) exitFns[i](); if (context.node.type === 0) context.registerTemplate(); } function createStructuralDirectiveTransform(name, fn) { const matches = (n) => (0, _vue_shared.isString)(name) ? n === name : name.includes(n); return (node, context) => { if (node.type === 1) { const { props } = node; if (node.tagType === 3 && props.some(_vue_compiler_dom.isVSlot)) return; const exitFns = []; for (const prop of props) if (prop.type === 7 && matches(prop.name)) { const onExit = fn(node, prop, context); if (onExit) exitFns.push(onExit); } return exitFns; } }; } /** * Build a "next-id" map from an occupied number set. * For each consecutive range [start..end], map every v in the range to end + 1. * Example: input [0, 1, 2, 4] => { 0: 3, 1: 3, 2: 3, 4: 5 }. */ function buildNextIdMap(nums) { const map = /* @__PURE__ */ new Map(); const arr = Array.from(new Set(nums)).sort((a, b) => a - b); if (arr.length === 0) return map; for (let i = 0; i < arr.length; i++) { let start = arr[i]; let end = start; while (i + 1 < arr.length && arr[i + 1] === end + 1) { i++; end = arr[i]; } for (let v = start; v <= end; v++) map.set(v, end + 1); } return map; } /** * Return the available id for n using a map built by buildNextIdMap: * - If n is not occupied, return n. * - If n is occupied, return the mapped value */ function getNextId(map, n) { if (map && map.has(n)) return map.get(n); return n; } function isComponentNode(node) { return node.type === 1 && node.tagType === 1; } //#endregion //#region packages/compiler-vapor/src/generators/utils.ts /** * Run a helper call inside the once ambient: a helper that creates its own * effects at a v-once site has them run once like compiled ones do. */ function genOnce(call, context) { return genCall(context.helper("withOnce"), ["() => ", ...call]); } const IMPORT_EXP_START = "__IMPORT_EXP_START__"; const IMPORT_EXP_END = "__IMPORT_EXP_END__"; const IMPORT_EXPR_RE = new RegExp(`${IMPORT_EXP_START}(.*?)${IMPORT_EXP_END}`, "g"); const NEWLINE = Symbol(`newline`); /** increase offset but don't push actual code */ const LF = Symbol(`line feed`); const INDENT_START = Symbol(`indent start`); const INDENT_END = Symbol(`indent end`); function buildCodeFragment(...frag) { return [ frag, frag.push.bind(frag), frag.unshift.bind(frag) ]; } function genMulti([left, right, seg, placeholder], ...frags) { if (placeholder) { while (frags.length > 0 && !frags[frags.length - 1]) frags.pop(); frags = frags.map((frag) => frag || placeholder); } else frags = frags.filter(Boolean); const frag = []; push(left); for (let [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); return [hasPlaceholder ? name[0] : name, ...genMulti([ "(", ")", ", ", hasPlaceholder ? name[1] : "null" ], ...frags)]; } function getParserOptions(plugins) { return { plugins: plugins ? plugins.some((plugin) => plugin === "typescript") ? plugins : [...plugins, "typescript"] : ["typescript"] }; } 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: 1, offset: 0 }; let indentLevel = 0; for (let frag of code) { if (!frag) continue; if (frag === NEWLINE) frag = [`\n${` `.repeat(indentLevel)}`, 0]; else if (frag === INDENT_START) { indentLevel++; continue; } else if (frag === INDENT_END) { indentLevel--; continue; } else if (frag === LF) { pos.line++; pos.column = 0; pos.offset++; continue; } if ((0, _vue_shared.isString)(frag)) frag = [frag]; let [code, newlineIndex = -2, loc, name] = frag; codegen += code; if (map) { if (loc) addMapping(loc.start, name); if (newlineIndex === -3) (0, _vue_compiler_dom.advancePositionWithMutation)(pos, code); else { pos.offset += code.length; if (newlineIndex === -2) pos.column += code.length; else { if (newlineIndex === -1) newlineIndex = code.length - 1; pos.line++; pos.column = code.length - newlineIndex; } } if (loc && loc !== _vue_compiler_dom.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 - 1, generatedLine: pos.line, generatedColumn: pos.column - 1, source: filename, name }); } } /** Formats a numeric flags argument with its dev-only name annotation. */ function genFlags(flags, names) { return `${flags} /* ${names.join(", ")} */`; } //#endregion //#region packages/compiler-vapor/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}`)]; } //#endregion //#region packages/compiler-vapor/src/generators/expression.ts function genExpression(node, context, assignment, asParams = false) { node = context.getExpressionReplacement(node); const { content, ast, isStatic, loc } = node; const { options } = context; const { inline } = options; if (isStatic) return [[ JSON.stringify(content), -2, loc ]]; if (!node.content.trim() || ast === false || isConstantExpression(node)) return [[ content, -2, loc ], assignment && ` = ${assignment}`]; if (ast === null) return genIdentifier(content, context, loc, assignment); const ids = []; const parentStackMap = /* @__PURE__ */ new Map(); const parentStack = []; (0, _vue_compiler_dom.walkIdentifiers)(ast, (id, _, __, isReference, isLocal) => { if (isLocal) { if (!id.typeAnnotation && !id.optional) return; } else if (!isReference) return; ids.push(id); parentStackMap.set(id, parentStack.slice()); }, asParams, parentStack); let hasMemberExpression = false; if (ids.length) { const [frag, push] = buildCodeFragment(); let lastEnd = 0; ids.sort((a, b) => a.start - b.start).forEach((id) => { const idStart = id.start - 1; const idEnd = id.end - 1; const source = content.slice(idStart, idEnd); const parentStack = parentStackMap.get(id); const parent = parentStack[parentStack.length - 1]; let start = idStart; let end = idEnd; if (inline && options.bindingMetadata && options.bindingMetadata[source] === "setup-let" && parent && parent.type === "UpdateExpression" && parent.argument === id) { start = parent.start - 1; end = parent.end - 1; } if (start < lastEnd) return; const leadingText = content.slice(lastEnd, start); if (leadingText.length) push([leadingText, -3]); hasMemberExpression || (hasMemberExpression = parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression")); push(...genIdentifier(asParams ? id.name : source, context, { start: (0, _vue_compiler_dom.advancePositionWithClone)(node.loc.start, source, start), end: (0, _vue_compiler_dom.advancePositionWithClone)(node.loc.start, source, end), source }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack, node)); lastEnd = end; }); if (lastEnd < content.length) push([content.slice(lastEnd), -3]); if (assignment && hasMemberExpression) push(` = ${assignment}`); return frag; } else return [[ content, -3, loc ]]; } function genIdentifier(raw, context, loc, assignment, id, parent, parentStack, sourceNode) { const { options, helper, identifiers } = context; const { inline, bindingMetadata } = options; let 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}`, -2, loc ]]; else return [[ replacement, -2, loc ]]; } else return genExpression(replacement, context, assignment); } let prefix; const type = bindingMetadata && bindingMetadata[raw]; const isDestructureAssignment = parent && (0, _vue_compiler_dom.isInDestructureAssignment)(parent, parentStack || []); const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id; const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id; if ((0, _vue_compiler_dom.isStaticProperty)(parent) && parent.shorthand && !(inline && type === "setup-let" && isDestructureAssignment)) prefix = `${raw}: `; if (inline) switch (type) { case "setup-let": if (isAssignmentLVal) { const { right, operator } = parent; const source = sourceNode; const sourceContent = source.content; const rightStart = right.start - 1; const rightEnd = right.end - 1; const rightContent = sourceContent.slice(rightStart, rightEnd); const rightExp = (0, _vue_compiler_dom.createSimpleExpression)(rightContent, false, { start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, sourceContent, rightStart), end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, sourceContent, rightEnd), source: rightContent }); rightExp.ast = parseExp(context, rightContent); return [ prefix, `${helper("isRef")}(${raw}) ? ${raw}.value ${operator} `, ...genExpression(rightExp, context), ` : `, [ raw, -2, loc, name ] ]; } else if (isUpdateArg) { const { prefix: isPrefix, operator } = parent; const updatePrefix = isPrefix ? operator : ``; const updatePostfix = isPrefix ? `` : operator; raw = `${helper("isRef")}(${raw}) ? ${updatePrefix}${raw}.value${updatePostfix} : ${updatePrefix}${raw}${updatePostfix}`; } else if (!isDestructureAssignment) name = raw = assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref(); break; case "setup-ref": name = raw = withAssignment(`${raw}.value`); break; case "setup-maybe-ref": raw = isAssignmentLVal || isUpdateArg || isDestructureAssignment ? name = `${raw}.value` : assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : null` : unref(); break; case "props": raw = (0, _vue_shared.genPropsAccessExp)(raw); break; case "props-aliased": raw = (0, _vue_shared.genPropsAccessExp)(bindingMetadata.__propsAliases[raw]); break; default: raw = withAssignment(raw); } else { if (canPrefix(raw)) { if (type === "props-aliased") raw = `$props['${bindingMetadata.__propsAliases[raw]}']`; else raw = `${type === "props" ? "$props" : "_ctx"}.${raw}`; } raw = withAssignment(raw); } return [prefix, [ raw, -2, loc, name ]]; function withAssignment(s) { return assignment ? `${s} = ${assignment}` : s; } function unref() { return `${helper("unref")}(${raw})`; } } function canPrefix(name) { if ((0, _vue_shared.isGloballyAllowed)(name)) return false; if (name === "require" || name === "$props" || name === "$emit" || name === "$attrs" || name === "$slots") return false; return true; } function processExpressions(context, expressions, shouldDeclare) { const expressionReplacements = /* @__PURE__ */ new Map(); const { seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, eagerVariable } = analyzeExpressions(expressions); const reservedNames = new Set(seenIdentifier); const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, eagerVariable, reservedNames, expressionReplacements); const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements); return { ...genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare), expressionReplacements }; } function analyzeExpressions(expressions) { const seenVariable = Object.create(null); const variableToExpMap = /* @__PURE__ */ new Map(); const expressionRecords = /* @__PURE__ */ new Map(); const seenIdentifier = /* @__PURE__ */ new Set(); const updatedVariable = /* @__PURE__ */ new Set(); const eagerVariable = /* @__PURE__ */ new Set(); const getRecord = (exp) => { let record = expressionRecords.get(exp); if (!record) expressionRecords.set(exp, record = { variables: [] }); return record; }; const registerVariable = (name, exp, isIdentifier, loc, parentStack = []) => { if (isIdentifier) seenIdentifier.add(name); seenVariable[name] = (seenVariable[name] || 0) + 1; variableToExpMap.set(name, (variableToExpMap.get(name) || /* @__PURE__ */ new Set()).add(exp)); getRecord(exp).variables.push({ name, loc }); if (parentStack.some((p) => p.type === "UpdateExpression" || p.type === "AssignmentExpression")) updatedVariable.add(name); if (isIdentifier || !isLazilyEvaluated(parentStack)) eagerVariable.add(name); }; for (const exp of expressions) { if (!exp.ast) { exp.ast === null && registerVariable(exp.content, exp, true); continue; } const seenParents = /* @__PURE__ */ new Set(); (0, _vue_compiler_dom.walkIdentifiers)(exp.ast, (currentNode, parent, parentStack) => { if (parent && isMemberExpression$3(parent) && !seenParents.has(parent)) { var _parentStack$index; seenParents.add(parent); let hasGlobalIdentifier = false; const memberExp = extractMemberExpression(parent, (id) => { registerVariable(id.name, exp, true, { start: id.start, end: id.end }); if ((0, _vue_shared.isGloballyAllowed)(id.name)) hasGlobalIdentifier = true; }); if (memberExp === void 0) return; const parentOfMemberExp = parentStack[parentStack.length - 2]; if (parentOfMemberExp && isCallExpression(parentOfMemberExp)) return; let chainChild = parent; let index = parentStack.length - 2; while (((_parentStack$index = parentStack[index]) === null || _parentStack$index === void 0 ? void 0 : _parentStack$index.type) === "TSNonNullExpression") chainChild = parentStack[index--]; const chainParent = parentStack[index]; if (chainParent && chainParent.type === "OptionalMemberExpression" && !chainParent.optional && chainParent.object === chainChild) return; if (hasGlobalIdentifier) return; registerVariable(memberExp, exp, false, { start: parent.start, end: parent.end }, parentStack); } else if (!parentStack.some(isMemberExpression$3)) registerVariable(currentNode.name, exp, true, { start: currentNode.start, end: currentNode.end }, parentStack); }); } return { seenVariable, seenIdentifier, variableToExpMap, expressionRecords, updatedVariable, eagerVariable }; } function getProcessedExpression(exp, expressionReplacements) { return expressionReplacements.get(exp) || exp; } function setExpressionReplacement(expressionReplacements, exp, content, ast) { expressionReplacements.set(exp, (0, _vue_shared.extend)({ ast }, (0, _vue_compiler_dom.createSimpleExpression)(content, exp.isStatic, exp.loc, exp.constType))); } /** * Whether a node is only evaluated lazily, given its ancestor chain - i.e. it * may be skipped entirely when a preceding condition is not met. */ const isLazilyEvaluated = (parentStack) => { for (let i = parentStack.length - 1; i > 0; i--) { const child = parentStack[i]; const parent = parentStack[i - 1]; switch (parent.type) { case "ConditionalExpression": if (parent.test !== child) return true; break; case "LogicalExpression": if (parent.right === child) return true; break; case "OptionalCallExpression": if (parent.arguments.includes(child)) return true; break; case "OptionalMemberExpression": if (parent.computed && parent.property === child) return true; break; default: if ((0, _vue_compiler_dom.isFunctionType)(parent)) return true; } } return false; }; function processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, eagerVariable, reservedNames, expressionReplacements) { const declarations = []; const declaredNames = /* @__PURE__ */ new Set(); const replacementPlan = /* @__PURE__ */ new Map(); for (const [name, exps] of variableToExpMap) { if (updatedVariable.has(name)) continue; if (!eagerVariable.has(name)) continue; if ((0, _vue_shared.isGloballyAllowed)(name)) continue; if (seenVariable[name] > 1 && exps.size > 0) { const isIdentifier = seenIdentifier.has(name); const varName = isIdentifier ? name : getUniqueDeclarationName(genVarName(name), reservedNames); exps.forEach((node) => { if (node.ast && varName !== name) { for (const variable of getExpressionVariables(expressionRecords, node)) if (variable.name === name && variable.loc) queueContentReplacement(replacementPlan, node, { start: variable.loc.start - 1, end: variable.loc.end - 1, content: varName }); } }); if (!declaredNames.has(varName) && (!isIdentifier || shouldDeclareVariable(name, expressionRecords, exps))) { declaredNames.add(varName); declarations.push({ name: varName, isIdentifier, value: (0, _vue_shared.extend)({ ast: isIdentifier ? null : parseExp(context, name) }, (0, _vue_compiler_dom.createSimpleExpression)(name)), rawName: name, exps, seenCount: seenVariable[name] }); } } } applyReplacementPlan(context, expressionReplacements, replacementPlan); return declarations; } function shouldDeclareVariable(name, expressionRecords, exps) { const variableUsages = []; let allSingleVariable = true; let hasRepeatedName = false; let hasDifferentLength = false; outer: for (const exp of exps) { const variables = getExpressionVariables(expressionRecords, exp); if (allSingleVariable && variables.length !== 1) allSingleVariable = false; if (!hasDifferentLength && variableUsages.length > 0 && variables.length !== variableUsages[0].length) hasDifferentLength = true; let nameCount = 0; for (const variable of variables) if (variable.name === name && ++nameCount > 1) { hasRepeatedName = true; break outer; } variableUsages.push(variables); } if (allSingleVariable) return true; if (hasRepeatedName) return true; const first = variableUsages[0]; if (hasDifferentLength) { for (const variables of variableUsages) { if (variables.length === first.length) continue; const longer = variables.length > first.length ? variables : first; const shorter = variables.length > first.length ? first : variables; const shorterNames = /* @__PURE__ */ new Set(); for (const variable of shorter) shorterNames.add(variable.name); let isSubset = true; for (const variable of longer) if (!shorterNames.has(variable.name)) { isSubset = false; break; } if (isSubset) return false; } return true; } for (const variables of variableUsages) for (let i = 0; i < variables.length; i++) if (variables[i].name !== first[i].name) return true; return false; } function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements) { const declarations = []; const seenExp = /* @__PURE__ */ new Map(); for (const exp of expressions) { var _expressionRecords$ge; const vars = (_expressionRecords$ge = expressionRecords.get(exp)) === null || _expressionRecords$ge === void 0 ? void 0 : _expressionRecords$ge.variables; if (!vars) continue; const processed = getProcessedExpression(exp, expressionReplacements); if (canCacheExpression(processed, vars, updatedVariable)) { const seen = seenExp.get(processed.content); if (seen) seen.count++; else seenExp.set(processed.content, { count: 1, first: exp }); } } const repeatedExpressions = [...seenExp].sort(([contentA], [contentB]) => contentB.length - contentA.length); for (const [content, { count, first }] of repeatedExpressions) if (count > 1) { const removedDeclarations = []; for (let i = varDeclarations.length - 1; i >= 0; i--) { const item = varDeclarations[i]; if (!item.exps || !item.seenCount) continue; if ([...item.exps].every((node) => getProcessedExpression(node, expressionReplacements).content === content && item.seenCount === count)) { removedDeclarations.push({ name: item.name, rawName: item.rawName }); reservedNames.delete(item.name); varDeclarations.splice(i, 1); } } const value = (0, _vue_shared.extend)({}, getProcessedExpression(first, expressionReplacements)); const restorePlan = []; for (const { name, rawName } of removedDeclarations) restorePlan.push(...findIdentifierReplacements(value, name, rawName)); if (restorePlan.length) { value.content = applyContentReplacements(value.content, restorePlan); if (value.ast) value.ast = parseExp(context, value.content); } const varName = getUniqueDeclarationName(genVarName(content), reservedNames); declarations.push({ name: varName, value }); for (const exp of expressions) { const processed = getProcessedExpression(exp, expressionReplacements); if (processed.content === content) setExpressionReplacement(expressionReplacements, exp, varName, null); else if (!content.includes("?.") && processed.content.includes(content)) { const replacements = findContentReplacements(processed, content, varName); if (replacements.length) { const replacedContent = applyContentReplacements(processed.content, replacements); setExpressionReplacement(expressionReplacements, exp, replacedContent, parseExp(context, replacedContent)); } } } } return declarations; } function canCacheExpression(processed, vars, updatedVariable) { if (!processed.ast || processed.ast.type === "Identifier") return false; for (const { name } of vars) if (updatedVariable.has(name) || (0, _vue_shared.isGloballyAllowed)(name)) return false; return true; } function getExpressionVariables(expressionRecords, exp) { var _expressionRecords$ge2; return ((_expressionRecords$ge2 = expressionRecords.get(exp)) === null || _expressionRecords$ge2 === void 0 ? void 0 : _expressionRecords$ge2.variables) || []; } function queueContentReplacement(replacementPlan, exp, replacement) { const replacements = replacementPlan.get(exp); if (replacements) replacements.push(replacement); else replacementPlan.set(exp, [replacement]); } function applyReplacementPlan(context, expressionReplacements, replacementPlan) { for (const [exp, replacements] of replacementPlan) { if (!replacements.length) continue; const content = applyContentReplacements(getProcessedExpression(exp, expressionReplacements).content, replacements); setExpressionReplacement(expressionReplacements, exp, content, parseExp(context, content)); } } function findContentReplacements(exp, content, replacement) { const nodeRanges = getNodeRanges(exp); if (!nodeRanges.size) return []; const replacements = []; let searchStart = 0; let start = exp.content.indexOf(content, searchStart); while (start !== -1) { const end = start + content.length; if (nodeRanges.has(`${start}:${end}`)) { replacements.push({ start, end, content: replacement }); searchStart = end; } else searchStart = start + 1; start = exp.content.indexOf(content, searchStart); } return replacements; } function findIdentifierReplacements(exp, name, replacement) { const replacements = []; for (const { start, end } of getIdentifierRanges(exp)) if (exp.content.slice(start, end) === name) replacements.push({ start, end, content: replacement }); return replacements; } function getNodeRanges(exp) { const ranges = /* @__PURE__ */ new Set(); if (!exp.ast || typeof exp.ast !== "object") return ranges; (0, estree_walker.walk)(exp.ast, { enter(node) { if ((0, _vue_compiler_dom.isFunctionType)(node) || node.type === "TemplateElement" || node.type.startsWith("TS") && !_vue_compiler_dom.TS_NODE_TYPES.includes(node.type)) return this.skip(); if (node.start != null && node.end != null) ranges.add(`${node.start - 1}:${node.end - 1}`); } }); return ranges; } function getIdentifierRanges(exp) { if (!exp.ast || typeof exp.ast !== "object") return []; const identifiers = []; (0, _vue_compiler_dom.walkIdentifiers)(exp.ast, (id) => { identifiers.push({ start: id.start - 1, end: id.end - 1 }); }, false); return identifiers; } function applyContentReplacements(content, replacements) { replacements.sort((a, b) => b.start - a.start).forEach(({ start, end, content: replacement }) => { content = content.slice(0, start) + replacement + content.slice(end); }); return content; } function genDeclarations(declarations, context, shouldDeclare) { const [frag, push] = buildCodeFragment(); const ids = Object.create(null); const varNames = /* @__PURE__ */ new Set(); declarations.forEach(({ name, isIdentifier, value }) => { if (isIdentifier) { const varName = ids[name] = context.getUniqueLocalName(`_${name}`, varNames); if (shouldDeclare) push(`const `); push(`${varName} = `, ...genExpression(value, context), NEWLINE); } }); declarations.forEach(({ name, isIdentifier, value }) => { if (!isIdentifier) { const varName = context.getUniqueLocalName(`_${name}`, varNames); if (shouldDeclare) push(`const `); push(`${varName} = `, ...context.withId(() => genExpression(value, context), ids), NEWLINE); ids[name] = varName; } }); return { ids, frag, varNames: [...varNames] }; } function parseExp(context, content) { return (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins)); } function genVarName(exp) { return `${exp.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/_+$/, "")}`; } function getUniqueDeclarationName(baseName, reservedNames) { const normalizedBase = baseName || "exp"; let name = normalizedBase; let i = 1; while (reservedNames.has(name)) name = `${normalizedBase}_${i++}`; reservedNames.add(name); return name; } /** * Returns the source of a member expression, or `undefined` if it contains a * node that cannot be extracted, e.g. `foo[bar ? 'a' : 'b']`. Such expressions * must not be cached - the extracted source would be incomplete. */ function extractMemberExpression(exp, onIdentifier) { if (!exp) return; switch (exp.type) { case "Identifier": onIdentifier(exp); return exp.name; case "StringLiteral": return exp.extra ? exp.extra.raw : exp.value; case "NumericLiteral": return exp.value.toString(); case "BinaryExpression": { var _exp$extra; const left = extractMemberExpression(exp.left, onIdentifier); const right = extractMemberExpression(exp.right, onIdentifier); if (left === void 0 || right === void 0) return; const expression = `${left} ${exp.operator} ${right}`; return ((_exp$extra = exp.extra) === null || _exp$extra === void 0 ? void 0 : _exp$extra.parenthesized) ? `(${expression})` : expression; } case "CallExpression": case "OptionalCallExpression": { const callee = extractMemberExpression(exp.callee, onIdentifier); const args = exp.arguments.map((arg) => extractMemberExpression(arg, onIdentifier)); if (callee === void 0 || args.some((arg) => arg === void 0)) return; return `${callee}${exp.type === "OptionalCallExpression" ? "?." : ""}(${args.join(", ")})`; } case "MemberExpression": case "OptionalMemberExpression": { const object = extractMemberExpression(exp.object, onIdentifier); const property = extractMemberExpression(exp.property, exp.computed ? onIdentifier : _vue_shared.NOOP); if (object === void 0 || property === void 0) return; const optional = exp.type === "OptionalMemberExpression" && exp.optional; return `${object}${exp.computed ? `${optional ? "?." : ""}[${property}]` : `${optional ? "?." : "."}${property}`}`; } case "TSNonNullExpression": return extractMemberExpression(exp.expression, onIdentifier); default: return; } } const isCallExpression = (node) => { return node.type === "CallExpression" || node.type === "OptionalCallExpression"; }; const isMemberExpression$3 = (node) => { return node.type === "MemberExpression" || node.type === "OptionalMemberExpression" || node.type === "TSNonNullExpression"; }; //#endregion //#region packages/compiler-vapor/src/generators/event.ts function genSetEvent(oper, context) { const { helper } = context; const { element, key, keyOverride, value, modifiers, delegate, effect } = oper; let handler; if (delegate) { context.delegates.add(key.content); if (!context.block.operation.some(isSameDelegateEvent)) return [ NEWLINE, `n${element}.$evt${key.content} = `, ...genDirectHandler() ]; } const name = genName(); const eventOptions = genEventOptions(); return [NEWLINE, ...genCall(helper(effect ? "onBinding" : delegate ? "delegate" : "on"), `n${element}`, name, genHandler(), eventOptions)]; function genHandler() { return handler || (handler = genEventHandler(context, [value], modifiers)); } function genInvoker() { return [ `${helper("createInvoker")}(`, ...genHandler(), `)` ]; } function genDirectHandler() { return modifiers.keys.length || modifiers.nonKeys.length ? genEventHandler(context, [value], modifiers, { modifierHelper: "vapor" }) : genInvoker(); } 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() { let { options } = modifiers; if (!options.length) return; return genMulti(DELIMITERS_OBJECT_NEWLINE, ...options.map((option) => [`${option}: true`])); } function isSameDelegateEvent(op) { if (op.type === 6 && 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, values, modifiers = { nonKeys: [], keys: [] }, options = {}) { const { asComponentProp = false, extraWrap = false, modifierHelper = "runtime" } = options; const useVaporModifierHelper = modifierHelper === "vapor"; let handlerExp = []; if (values) { values.forEach((value, index) => { let exp = []; if (value && value.content.trim()) { if ((0, _vue_compiler_dom.isMemberExpression)(value, context.options)) { exp = genExpression(value, context); if (!isConstantBinding(value, context) && !asComponentProp) { const isTSNode = value.ast && _vue_compiler_dom.TS_NODE_TYPES.includes(value.ast.type); exp = [ `e => `, isTSNode ? "(" : "", ...exp, isTSNode ? ")" : "", `(e)` ]; } } else if ((0, _vue_compiler_dom.isFnExpression)(value, context.options)) exp = genExpression(value, context); else { const referencesEvent = value.content.includes("$event"); const hasMultipleStatements = value.content.includes(`;`); const expr = referencesEvent ? context.withId(() => genExpression(value, context), { $event: null }) : genExpression(value, context); exp = [ referencesEvent ? "$event => " : "() => ", hasMultipleStatements ? "{" : "(", ...expr, hasMultipleStatements ? "}" : ")" ]; } handlerExp = handlerExp.concat([index !== 0 ? ", " : "", ...exp]); } }); if (values.length > 1) handlerExp = [ "[", ...handlerExp, "]" ]; } if (handlerExp.length === 0) handlerExp = ["() => {}"]; const { keys, nonKeys } = modifiers; if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys, useVaporModifierHelper && !keys.length); if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys, useVaporModifierHelper); if (extraWrap) handlerExp.unshift(`() => `); return handlerExp; } function genWithModifiers(context, handler, nonKeys, useVaporHelper = false) { return genCall(context.helper(useVaporHelper ? "withVaporModifiers" : "withModifiers"), handler, JSON.stringify(nonKeys)); } function genWithKeys(context, handler, keys, useVaporHelper = false) { return genCall(context.helper(useVaporHelper ? "withVaporKeys" : "withKeys"), handler, JSON.stringify(keys)); } function isConstantBinding(value, context) { if (value.ast === null) { if (context.options.bindingMetadata[value.content] === "setup-const") return true; } } //#endregion //#region packages/compiler-vapor/src/generators/for.ts function genFor(oper, context) { const { helper } = context; const { source, value, key, index, render, keyProp, once, id, component, onlyChild, slotRoot, wrappedRows } = oper; const sourceExpr = [ "() => (", ...genExpression(source, context), ")" ]; const plugins = context.options.expressionPlugins; const idToPathMap = parseValueDestructure(value, context); const keyToPathMap = parseValueDestructure(key, context); const indexToPathMap = parseValueDestructure(index, context); const [depth, exitScope] = context.enterScope(); const itemVar = `_for_item${depth}`; const idMap = buildDestructureIdMap(idToPathMap, `${itemVar}.value`, plugins); idMap[itemVar] = null; const args = [itemVar]; if (key) { const keyVar = `_for_key${depth}`; args.push(`, ${keyVar}`); Object.assign(idMap, buildDestructureIdMap(keyToPathMap, `${keyVar}.value`, plugins)); idMap[keyVar] = null; } else if (index) args.push(", _"); if (index) { const indexVar = `_for_index${depth}`; args.push(`, ${indexVar}`); Object.assign(idMap, buildDestructureIdMap(indexToPathMap, `${indexVar}.value`, plugins)); idMap[indexVar] = null; } const { selectorPatterns, keyOnlyBindingPatterns, skippedEffectIndexes } = matchPatterns(render, keyProp, idMap, context); const selectorDeclarations = []; const selectorName = (i) => selectorPatterns.length > 1 ? `_selector${id}_${i}` : `_selector${id}`; for (let i = 0; i < selectorPatterns.length; i++) { const { selector } = selectorPatterns[i]; selectorDeclarations.push(`const ${selectorName(i)} = `, ...genCall(helper("createSelector"), [`() => `, ...genExpression(selector, context)]), 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 (let i = 0; i < selectorPatterns.length; i++) { const { effect } = selectorPatterns[i]; patternFrag.push(NEWLINE, `${selectorName(i)}(`, ...genExpression(keyProp, context), `, () => {`, INDENT_START); for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context)); patternFrag.push(INDENT_END, NEWLINE, `})`); } for (const { effect } of keyOnlyBindingPatterns) for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context)); return patternFrag; }, skippedEffectIndexes)); else frag.push(...genBlockContent(render, context)); frag.push(INDENT_END, NEWLINE, "}"); return frag; }, idMap); exitScope(); const flags = genForFlags(onlyChild, component, isFragmentBlock(render), !component && isSingleNodeBlock(render), once, slotRoot, wrappedRows); const onResetCalls = []; for (let i = 0; i < selectorPatterns.length; i++) onResetCalls.push(NEWLINE, `n${id}.onReset(${selectorName(i)}.reset)`); return [ NEWLINE, ...selectorDeclarations, `const n${id} = `, ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags), ...onResetCalls ]; function genCallback(expr) { if (!expr) return false; return context.withId(() => [ ...genAliasParams(value, key, index, context), " => (", ...genExpression(expr, context), ")" ], genSimpleIdMap()); } function genSimpleIdMap() { const idMap = {}; const collect = (map) => map.forEach((_, id) => idMap[id] = null); collect(idToPathMap); collect(keyToPathMap); collect(indexToPathMap); return idMap; } } function genForFlags(onlyChild, component, isFragment, isSingleNode, once, slotRoot, wrappedRows) { let flags = 0; const names = []; if (onlyChild) { flags |= 1; names.push("FAST_REMOVE"); } if (component) { flags |= 2; names.push("IS_COMPONENT"); } if (isFragment) { flags |= 16; names.push("IS_FRAGMENT"); } if (isSingleNode) { flags |= 8; names.push("IS_SINGLE_NODE"); } if (once) { flags |= 4; names.push("ONCE"); } if (slotRoot) { flags |= 32; names.push("SLOT_ROOT"); } if (wrappedRows) { flags |= 64; names.push("WRAPPED_ROWS"); } if (!flags) return; return genFlags(flags, names); } function isSingleNodeBlock(block) { const child = getSingleReturnedChild(block); return !!child && child.template != null; } function isFragmentBlock(block) { const child = getSingleReturnedChild(block); const operation = child && child.operation; if (!operation) return false; return operation.type === 12 || operation.type === 15 || operation.type === 16 || operation.type === 14 && !operation.once || operation.type === 11 && !!operation.dynamic && !operation.dynamic.isStatic; } function getSingleReturnedChild(block) { if (block.returns.length !== 1) return; const id = block.returns[0]; for (const child of block.dynamic.children) if (child.id === id) return child; } function genAliasParams(value, key, index, context) { return genMulti([ "(", ")", ", " ], value ? genExpression(value, context, void 0, true) : key || index ? "_" : void 0, key ? genExpression(key, context, void 0, true) : index ? "__" : void 0, index && genExpression(index, context, void 0, true)); } function parseValueDestructure(value, context) { const map = /* @__PURE__ */ new Map(); if (value) { const rawValue = value.content; if (value.ast) (0, _vue_compiler_dom.walkIdentifiers)(value.ast, (id, _, parentStack, ___, isLocal) => { if (isLocal) { let path = ""; let isDynamic = false; let helper; let helperArgs; for (let i = 0; i < parentStack.length; i++) { const parent = parentStack[i]; const child = parentStack[i + 1] || id; 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 += `[${rawValue.slice(parent.key.start - 1, parent.key.end - 1)}]`; } else path += `.${parent.key.name}`; } else if (parent.type === "ArrayPattern") { const index = parent.elements.indexOf(child); if (child.type === "RestElement") path += `.slice(${index})`; else path += `[${index}]`; } else if (parent.type === "ObjectPattern" && child.type === "RestElement") { helper = 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) { isDynamic = true; return rawValue.slice(p.key.start - 1, p.key.end - 1); } else return JSON.stringify(p.key.name); }).join(", ") + "]"; } if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern" || parent.type === "ArrowFunctionExpression" && child.left === id)) { isDynamic = true; helper = context.helper("getDefaultValue"); helperArgs = `() => (${rawValue.slice(child.right.start - 1, child.right.end - 1)})`; } } map.set(id.name, { path, dynamic: isDynamic, helper, helperArgs }); } }, true); else if (rawValue) map.set(rawValue, null); } return map; } function buildDestructureIdMap(idToPathMap, baseAccessor, plugins) { const idMap = {}; idToPathMap.forEach((pathInfo, id) => { let path = baseAccessor; if (pathInfo) { path = `${baseAccessor}${pathInfo.path}`; if (pathInfo.helper) { idMap[pathInfo.helper] = null; path = pathInfo.helperArgs ? `${pathInfo.helper}(${path}, ${pathInfo.helperArgs})` : `${pathInfo.helper}(${path})`; } if (pathInfo.dynamic) { const node = idMap[id] = (0, _vue_compiler_dom.createSimpleExpression)(path); node.ast = (0, _babel_parser.parseExpression)(`(${path})`, getParserOptions(plugins)); } else idMap[id] = path; } else idMap[id] = path; }); return idMap; } function matchPatterns(render, keyProp, idMap, context) { const selectorPatterns = []; const keyOnlyBindingPatterns = []; let skippedEffectIndexes; if (keyProp === void 0) return { keyOnlyBindingPatterns, selectorPatterns, skippedEffectIndexes }; const modelElements = new Set(render.operation.filter(isVModelOperation).map((oper) => oper.element)); const lastOrderedProp = /* @__PURE__ */ new Map(); for (let i = 0; i < render.effect.length; i++) { const effect = render.effect[i]; if (effect.once) { for (const operation of effect.operations) if (operation.type === 3) lastOrderedProp.set(operation.element, i); } } for (let index = 0; index < render.effect.length; index++) { const effect = render.effect[index]; if (effect.once || effect.operations.some((operation) => { var _lastOrderedProp$get; return isVModelListener(operation, modelElements) || operation.type === 3 && index < ((_lastOrderedProp$get = lastOrderedProp.get(operation.element)) !== null && _lastOrderedProp$get !== void 0 ? _lastOrderedProp$get : -1); })) continue; const selector = matchSelectorPattern(effect, keyProp.content, idMap, context); if (selector) { selectorPatterns.push(selector); skipEffect(index); continue; } const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content); if (keyOnly) { keyOnlyBindingPatterns.push(keyOnly); skipEffect(index); } } return { keyOnlyBindingPatterns, selectorPatterns, skippedEffectIndexes }; function skipEffect(index) { if (!skippedEffectIndexes) skippedEffectIndexes = /* @__PURE__ */ new Set(); skippedEffectIndexes.add(index); } } function matchKeyOnlyBindingPattern(effect, key) { if (effect.expressions.length === 1) { const { ast, content } = effect.expressions[0]; if (typeof ast === "object" && ast !== null) { if (isKeyOnlyBinding(ast, key, content)) return { effect }; } } } function matchSelectorPattern(effect, key, idMap, context) { if (effect.expressions.length === 1) { const { ast, content } = effect.expressions[0]; if (typeof ast === "object" && ast) { const matcheds = []; (0, estree_walker.walk)(ast, { enter(node) { if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") { const { left, right } = node; for (const [a, b] of [[left, right], [right, left]]) { const aIsKey = content.slice(a.start - 1, a.end - 1) === key; const bIsKey = isKeyOnlyBinding(b, key, content); const bVars = analyzeVariableScopes(b, idMap); if (aIsKey && !bIsKey && !bVars.length) matcheds.push([a, b]); } } } }); if (matcheds.length === 1) { const [key, selector] = matcheds[0]; const content = effect.expressions[0].content; let hasExtraId = false; (0, _vue_compiler_dom.walkIdentifiers)(ast, (id) => { if (id.start !== key.start && id.start !== selector.start) hasExtraId = true; }, false); if (!hasExtraId) { const name = content.slice(selector.start - 1, selector.end - 1); const selectorExpression = (0, _vue_compiler_dom.createSimpleExpression)(name, false, selector.loc); selectorExpression.ast = (0, _babel_parser.parseExpression)(`(${name})`, getParserOptions(context.options.expressionPlugins)); return { effect, selector: selectorExpression }; } } } } } function analyzeVariableScopes(ast, idMap) { let locals = []; const ids = []; (0, _vue_compiler_dom.walkIdentifiers)(ast, (id) => { ids.push(id); }, false); for (const id of ids) { if ((0, _vue_shared.isGloballyAllowed)(id.name)) continue; if (idMap[id.name]) locals.push(id.name); } return locals; } function isKeyOnlyBinding(expr, key, source) { let only = true; (0, estree_walker.walk)(expr, { enter(node) { if (source.slice(node.start - 1, node.end - 1) === key) { this.skip(); return; } if (node.type === "Identifier") only = false; } }); return only; } //#endregion //#region packages/compiler-vapor/src/generators/html.ts function genSetHtml(oper, context) { const { helper } = context; const { value, element } = oper; return [NEWLINE, ...genCall(helper("setHtml"), `n${element}`, genExpression(value, context))]; } //#endregion //#region packages/compiler-vapor/src/generators/if.ts function genIf(oper, context, isNested = false) { const { helper } = context; const { condition, positive, negative, once, slotRoot, index, blockShape } = oper; const [frag, push] = buildCodeFragment(); const flags = genIfFlags(blockShape, once, slotRoot, negative ? index : void 0); const conditionExpr = [ "() => (", ...genExpression(condition, context), ")" ]; let positiveArg = genBlock(positive, context); let negativeArg = false; if (negative) { if (negative.type === 1) negativeArg = genBlock(negative, context); else negativeArg = ["() => ", ...genIf(negative, context, true)]; } if (!isNested) push(NEWLINE, `const n${oper.id} = `); push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, flags)); return frag; } function genIfFlags(blockShape, once, slotRoot, index) { let flags = blockShape; if (slotRoot) flags |= 128; if (once) flags |= 16; else if (index !== void 0) flags |= index + 1 << 8; if (flags === 1) return false; return genFlags(flags, genIfFlagNames(once, slotRoot, index, blockShape)); } function genIfFlagNames(once, slotRoot, index, blockShape) { const names = [`TRUE_${genBlockShapeName(blockShape)}`]; const falseShape = blockShape >> 2; const hasFalseBranch = (falseShape & 3) !== 0; if (hasFalseBranch) names.push(`FALSE_${genBlockShapeName(falseShape)}`); if (blockShape & 32) names.push("TRUE_NO_SCOPE"); if (hasFalseBranch && blockShape & 64) names.push("FALSE_NO_SCOPE"); if (once) names.push("ONCE"); if (slotRoot) names.push("SLOT_ROOT"); if (!once && index !== void 0) names.push(`KEYED_INDEX_${index}`); return names; } function genBlockShapeName(flags) { switch (flags & 3) { case 0: return "EMPTY"; case 1: return "SINGLE_ROOT"; case 2: return "MULTI_ROOT"; } return "UNKNOWN"; } //#endregion //#region packages/compiler-vapor/src/generators/prop.ts const helpers = { setElementText: { name: "setElementText" }, setHtml: { name: "setHtml" }, setClass: { name: "setClass" }, setClassName: { name: "setClassName" }, setStyle: { name: "setStyle" }, setValue: { name: "setValue" }, setAttr: { name: "setAttr", needKey: true }, setProp: { name: "setProp", needKey: true }, setDOMProp: { name: "setDOMProp", needKey: true } }; function genSetProp(oper, context) { const { helper } = context; const { prop: { key, values, modifier }, tag, isSVG } = oper; if (!modifier && (0, _vue_shared.isOn)(key.content)) return genSetListener(oper, context); const resolvedHelper = getRuntimeHelper(tag, isSVG, key.content, modifier); if (key.content === "class" && !resolvedHelper.isSVG && resolvedHelper.name === "setClass") { const className = genSetClassName(oper, context); if (className) return className; } const propValue = genPropValue(values, context); return [NEWLINE, ...genCall([helper(resolvedHelper.name), null], `n${oper.element}`, resolvedHelper.needKey ? genExpression(key, context) : false, propValue, resolvedHelper.isSVG && "true")]; } const optionsModifierRE = /(Once|Passive|Capture)$/; const optionsModifierEventRE = /^on:?(?:Once|Passive|Capture)$/; function genSetListener(oper, context) { const { helper } = context; const { element, effect, prop } = oper; const value = genPropValue(prop.values, context); if (effect) return [NEWLINE, ...genCall(helper("setListener"), `n${element}`, JSON.stringify(prop.key.content), value)]; let name = prop.key.content; const options = []; let m; while ((m = name.match(optionsModifierRE)) && !optionsModifierEventRE.test(name)) { name = name.slice(0, name.length - m[1].length); options.push([`${m[1].toLowerCase()}: true`]); } const event = name[2] === ":" ? name.slice(3) : (0, _vue_shared.hyphenate)(name.slice(2)); return [NEWLINE, ...genCall(helper("on"), `n${element}`, JSON.stringify(event), value, options.length ? genMulti(DELIMITERS_OBJECT, ...options) : void 0)]; } const MAX_CLASS_NAME_ENTRIES = 31; function genSetClassName(oper, context) { const info = resolveClassName(oper.prop.values, context); if (!info) return; const { helper } = context; const flags = genClassFlags(info.entries, context); const classFragments = info.entries.map((entry) => JSON.stringify(!info.prefix && info.entries.length === 1 ? entry.className : ` ${entry.className}`)); const fragments = classFragments.length === 1 ? classFragments[0] : genMulti(DELIMITERS_ARRAY, ...classFragments); return [NEWLINE, ...genCall([helper("setClassName"), "\"\""], `n${oper.element}`, flags, fragments, info.prefix && JSON.stringify(info.prefix), info.suffix && JSON.stringify(info.suffix))]; } function resolveClassName(values, context) { let prefix = ""; let suffix = ""; const entries = []; let sawDynamic = false; let sawSuffix = false; for (const rawValue of values) { const value = context.getExpressionReplacement(rawValue); const staticValue = getLiteralExpressionValue(value, true); if (staticValue != null) { const normalized = (0, _vue_shared.normalizeClass)(staticValue); if (normalized) { if (sawSuffix) suffix = appendClass$1(suffix, normalized); else if (sawDynamic) { sawSuffix = true; suffix = appendClass$1(suffix, normalized); } else prefix = appendClass$1(prefix, normalized); } continue; } const ast = value.ast; if (!ast || sawSuffix) return; sawDynamic = true; if (ast.type === "ObjectExpression") { if (!resolveObjectClassName(value, ast, entries, context)) return; } else if (ast.type === "ConditionalExpression") { if (!resolveConditionalClassName(value, ast, entries, context)) return; } else return; } return entries.length && entries.length <= MAX_CLASS_NAME_ENTRIES ? { prefix, suffix, entries } : void 0; } function resolveObjectClassName(source, ast, entries, context) { for (const prop of ast.properties) { if (prop.type !== "ObjectProperty" || prop.computed) return false; const rawClassName = getObjectPropertyName$1(prop); if (rawClassName == null) return false; const className = (0, _vue_shared.normalizeClass)(rawClassName); if (!className) continue; const value = getBooleanValue(prop.value); entries.push({ className, value, condition: value == null ? createSubExpression(source, prop.value, context) : void 0 }); } return true; } function resolveConditionalClassName(source, ast, entries, context) { const consequent = getStringClassValue(ast.consequent); const alternate = getStringClassValue(ast.alternate); if (consequent && alternate === "") { entries.push({ className: consequent, condition: createSubExpression(source, ast.test, context) }); return true; } else if (alternate && consequent === "") { entries.push({ className: alternate, condition: createSubExpression(source, ast.test, context), negate: true }); return true; } return false; } function genClassFlags(entries, context) { const values = []; entries.forEach((entry, index) => { if (index) values.push(" | "); const bit = 1 << index; if (entry.value != null) { values.push(entry.value ? String(bit) : "0"); return; } values.push("((", ...genExpression(entry.condition, context), ")", entry.negate ? ` ? 0 : ${bit}` : ` ? ${bit} : 0`, ")"); }); return values; } function appendClass$1(base, value) { return base ? value ? `${base} ${value}` : base : value; } function getObjectPropertyName$1(prop) { const key = prop.key; if (key.type === "Identifier") return key.name; else if (key.type === "StringLiteral") return key.value; else if (key.type === "NumericLiteral") return String(key.value); } function getStringClassValue(node) { if (node.type === "StringLiteral") return (0, _vue_shared.normalizeClass)(node.value); else if (node.type === "TemplateLiteral" && node.expressions.length === 0) return (0, _vue_shared.normalizeClass)(node.quasis[0].value.cooked || ""); else if (node.type === "NullLiteral" || node.type === "BooleanLiteral" && !node.value) return ""; } function getBooleanValue(node) { if (node.type === "BooleanLiteral") return node.value; } function createSubExpression(source, node, context) { const start = node.start == null ? 0 : node.start - 1; const end = node.end == null ? source.content.length : node.end - 1; const content = source.content.slice(start, end); const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, { start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start), end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end), source: content }); expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins)); return expression; } function genDynamicProps$1(oper, context) { const { helper } = context; const values = oper.props.map((props) => { if (Array.isArray(props)) return genLiteralObjectProps(props, context); if (props.kind === 1) return genLiteralObjectProps([props], context); const value = genExpression(props.value, context); return props.handler ? genCall(helper("toHandlers"), value, "true") : value; }); return [NEWLINE, ...genCall(helper("setDynamicProps"), `n${oper.element}`, genMulti(DELIMITERS_ARRAY, ...values), genDynamicPropNames$1(oper, context), oper.isSVG && "true")]; } function genDynamicPropNames$1(oper, context) { const { bindingMetadata } = context.options; const names = oper.props.flatMap((props) => Array.isArray(props) ? props.filter(({ key, values, modifier, handler }) => key.isStatic && modifier !== "." && !handler && key.content !== "class" && key.content !== "style" && values.some((v) => !v.isStatic && !isConstantBinding$1(v, bindingMetadata))).map((prop) => getStaticPropKeyName(prop)) : []); if (!names.length) return false; const json = JSON.stringify(names); let id = context.dynamicPropNames.get(json); if (!id) context.dynamicPropNames.set(json, id = context.kName(context.dynamicPropNames.size)); return id; } function genLiteralObjectProps(props, context) { const entries = []; const listeners = createHandlerGroups(entries); for (const prop of props) if (isListenerProp(prop)) listeners.add(getStaticPropKeyName(prop, true), genPropKey(prop, context, true), prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers) : genPropValue(prop.values, context)); else entries.push([ ...genPropKey(prop, context), `: `, ...genPropValue(prop.values, context) ]); listeners.fill(); return genMulti(DELIMITERS_OBJECT, ...entries); } function isListenerProp(prop) { return prop.handler || !prop.modifier && !prop.model && prop.key.isStatic && (0, _vue_shared.isOn)(prop.key.content); } function createHandlerGroups(entries, prefix = "", delimiters = DELIMITERS_ARRAY) { const groups = /* @__PURE__ */ new Map(); return { add(name, keyFrag, handler) { let group = groups.get(name); if (!group) { groups.set(name, group = { keyFrag, handlers: [], index: entries.length }); entries.push([]); } group.handlers.push(handler); }, fill() { for (const { keyFrag, handlers, index } of groups.values()) entries[index] = [ ...keyFrag, ": ", prefix, ...handlers.length > 1 ? genMulti(delimiters, ...handlers) : handlers[0] ]; } }; } function getStaticPropKeyName({ key, modifier, handler, handlerModifiers }, preserveCase = false) { return (handler ? preserveCase && /[A-Z]/.test(key.content) ? `on:${key.content}` : (0, _vue_shared.toHandlerKey)((0, _vue_shared.camelize)(key.content)) : (modifier || "") + key.content) + getHandlerModifierPostfix(handlerModifiers); } function getHandlerModifierPostfix(handlerModifiers) { return handlerModifiers && handlerModifiers.options ? handlerModifiers.options.map(_vue_shared.capitalize).join("") : ""; } function genPropKey(prop, context, preserveCase = false) { const { key: node, modifier, runtimeCamelize, handler, handlerModifiers, model } = prop; const { helper } = context; const handlerModifierPostfix = getHandlerModifierPostfix(handlerModifiers); if (node.isStatic) { const keyName = getStaticPropKeyName(prop, preserveCase); return [[ (0, _vue_compiler_dom.isSimpleIdentifier)(keyName) ? keyName : JSON.stringify(keyName), -2, node.loc ]]; } let key = genExpression(node, context); if (runtimeCamelize) { key.push(" || \"\""); key = genCall(helper("camelize"), key); } else if (modifier) key = [ "(", ...key, " || \"\"", ")" ]; else if (!handler && !model) key = node.ast === null ? [...key, " || \"\""] : [ "(", ...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, isSVG, key, modifier) { const tagName = tag.toUpperCase(); if (modifier) { if (modifier === ".") return getSpecialHelper(key, tagName, isSVG) || helpers.setDOMProp; else return isSVG ? (0, _vue_shared.extend)({ isSVG: true }, helpers.setAttr) : helpers.setAttr; } const helper = getSpecialHelper(key, tagName, isSVG); if (helper) return helper; if (/aria[A-Z]/.test(key)) return helpers.setDOMProp; if (isSVG) return (0, _vue_shared.extend)({ isSVG: true }, helpers.setAttr); if ((0, _vue_shared.shouldSetAsAttr)(tagName, key) || key.includes("-")) return helpers.setAttr; return helpers.setProp; } function getSpecialHelper(keyName, tagName, isSVG) { if (keyName === "value" && (0, _vue_shared.canSetValueDirectly)(tagName)) return helpers.setValue; else if (keyName === "class") return (0, _vue_shared.extend)({ isSVG }, helpers.setClass); else if (keyName === "style") return helpers.setStyle; else if (keyName === "innerHTML") return helpers.setHtml; else if (keyName === "textContent") return helpers.setElementText; } //#endregion //#region packages/compiler-vapor/src/generators/templateRef.ts const setTemplateRefIdent = `_setTemplateRef`; function genSetTemplateRef(oper, context) { const [refValue, refKey] = genRefValue(oper.value, context); if (!oper.effect && !oper.refFor && oper.value.isStatic) return genSetStaticTemplateRef(oper, refValue, refKey, context); context.needsTemplateRefSetter = true; return [NEWLINE, ...genCall(setTemplateRefIdent, `n${oper.element}`, refValue, oper.refFor && "true", refKey)]; } function genSetStaticTemplateRef(oper, refValue, refKey, context) { return [NEWLINE, ...genCall(context.helper("setStaticTemplateRef"), `n${oper.element}`, refValue, oper.refFor && "true", refKey)]; } function genSetTemplateRefBinding(oper, context) { const [refValue, refKey] = genRefValue(oper.value, context); return [NEWLINE, ...genCall([context.helper("setTemplateRefBinding"), "undefined"], `n${oper.element}`, ["() => ", ...refValue], ...oper.refFor || refKey ? [oper.refFor && "true", refKey] : [])]; } function genRefValue(value, context) { if (value && context.options.inline) { const binding = context.options.bindingMetadata[value.content]; if (binding === "setup-let" || binding === "setup-ref" || binding === "setup-maybe-ref") return [[value.content], JSON.stringify(value.content)]; } return [genExpression(value, context)]; } //#endregion //#region packages/compiler-vapor/src/generators/text.ts function genSetText(oper, context) { const { helper } = context; const { element, values, generated } = oper; const texts = combineValues(values, context); return [NEWLINE, ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)]; } function combineValues(values, context) { return values.flatMap((value, i) => { let exp = genExpression(value, context); if (getLiteralExpressionValue(value, true) == null) exp = genCall(context.helper("toDisplayString"), exp); if (i > 0) exp.unshift(" + "); return exp; }); } function genGetTextChild(oper, context) { return [NEWLINE, `const x${oper.parent} = ${context.helper("txt")}(n${oper.parent})`]; } //#endregion //#region packages/compiler-vapor/src/generators/modifier.ts function genDirectiveModifiers(modifiers) { return modifiers.map((value) => `${(0, _vue_compiler_dom.isSimpleIdentifier)(value) ? value : JSON.stringify(value)}: true`).join(", "); } //#endregion //#region packages/compiler-vapor/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 genCall(context.helper(helperMap[modelType]), `n${element}`, [ `() => (`, ...genExpression(exp, context), `)` ], genModelHandler(exp, context), modifiers.length ? `{ ${genDirectiveModifiers(modifiers.map((e) => e.content))} }` : void 0); } function genModelHandler(exp, context) { return [ `${context.options.isTS ? `(_value: any)` : `_value`} => (`, ...genExpression(exp, context, "_value"), ")" ]; } //#endregion //#region packages/compiler-vapor/src/generators/component.ts function genStaticModifierPropKey(name) { const key = (0, _vue_shared.getModifierPropName)(name); return [(0, _vue_compiler_dom.isSimpleIdentifier)(key) ? key : JSON.stringify(key)]; } function genCreateComponent(operation, context) { const { helper } = context; const singleUseAssetComponentNames = context.singleUseAssetComponentNames; const useAssetComponentHelper = operation.asset && !operation.dynamic && context.block === context.ir.block && !!singleUseAssetComponentNames && singleUseAssetComponentNames.has(operation.tag); const maybeSelfReference = useAssetComponentHelper && operation.tag.endsWith("__self"); const tag = genTag(); const { root, props, slots, once, slotRoot } = operation; const isRuntimeDynamicComponent = !!(operation.dynamic && !operation.dynamic.isStatic); const dynamicComponentFlags = isRuntimeDynamicComponent ? genDynamicComponentFlags(root, once, slotRoot, operation.ns) : false; const nsArg = !isRuntimeDynamicComponent && (operation.useCreateElement || operation.asset || !!operation.dynamic) && operation.ns ? String(operation.ns) : false; const slotDeclarations = []; const rawSlots = genRawSlots(slots, context, slotDeclarations); const [ids, handlers] = processInlineHandlers(props, context); const rawProps = context.withId(() => genRawProps(props, context, true), ids); const inlineHandlers = handlers.reduce((acc, { name, value }) => { const handler = genEventHandler(context, [value]); return [ ...acc, `const ${name} = `, ...handler, NEWLINE ]; }, []); return [ NEWLINE, ...inlineHandlers, ...slotDeclarations.length ? genMulti([ "let ", NEWLINE, ", " ], ...slotDeclarations) : [], `const n${operation.id} = `, ...genCall(isRuntimeDynamicComponent ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, isRuntimeDynamicComponent ? dynamicComponentFlags : root ? "true" : false, isRuntimeDynamicComponent ? operation.key && [ "() => (", ...genExpression(operation.key, context), ")" ] : once && "true", useAssetComponentHelper ? maybeSelfReference && "true" : nsArg, useAssetComponentHelper && nsArg) ]; function genTag() { if (operation.useCreateElement) return JSON.stringify(operation.tag); else if (operation.dynamic) { if (operation.dynamic.isStatic) return genCall(helper("resolveDynamicComponent"), genExpression(operation.dynamic, context)); else return [ "() => (", ...genExpression(operation.dynamic, context), ")" ]; } else if (useAssetComponentHelper) { const name = maybeSelfReference ? operation.tag.slice(0, -6) : operation.tag; return JSON.stringify(name); } else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component"); else { const { tag } = operation; const builtInTag = isBuiltInComponent(tag); if (builtInTag) { helper(builtInTag); return `_${builtInTag}`; } return genExpression((0, _vue_shared.extend)((0, _vue_compiler_dom.createSimpleExpression)(tag, false), { ast: null }), context); } } } function genDynamicComponentFlags(root, once, slotRoot, ns) { let flags = 0; const names = []; if (root) { flags |= 1; names.push("SINGLE_ROOT"); } if (once) { flags |= 2; names.push("ONCE"); } if (slotRoot) { flags |= 4; names.push("SLOT_ROOT"); } if (ns === 1) { flags |= 8; names.push("NS_SVG"); } else if (ns === 2) { flags |= 16; names.push("NS_MATHML"); } if (!flags) return false; return genFlags(flags, names); } function getUniqueHandlerName(context, name) { const { seenInlineHandlerNames } = context; name = genVarName(name); const count = seenInlineHandlerNames[name] || 0; seenInlineHandlerNames[name] = count + 1; return count === 0 ? name : `${name}${count}`; } function processInlineHandlers(props, context) { const ids = Object.create(null); const handlers = []; const staticProps = props[0]; if ((0, _vue_shared.isArray)(staticProps)) for (let i = 0; i < staticProps.length; i++) { const prop = staticProps[i]; if (!prop.handler) continue; prop.values.forEach((value, i) => { if (!(0, _vue_compiler_dom.isMemberExpression)(value, context.options)) { const name = getUniqueHandlerName(context, `_on_${prop.key.content.replace(/-/g, "_")}`); handlers.push({ name, value }); ids[name] = null; prop.values[i] = (0, _vue_shared.extend)({ ast: null }, (0, _vue_compiler_dom.createSimpleExpression)(name)); } }); } return [ids, handlers]; } function genRawProps(props, context, directStaticLiteralProps = false) { const staticProps = props[0]; if ((0, _vue_shared.isArray)(staticProps)) { if (!staticProps.length && props.length === 1) return; return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context, directStaticLiteralProps), directStaticLiteralProps); } else if (props.length) return genStaticProps([], context, genDynamicProps(props, context, directStaticLiteralProps), directStaticLiteralProps); } function genStaticProps(props, context, dynamicProps, directStaticLiteralProps = false) { const args = []; const handlerGroups = createHandlerGroups(args, "() => ", DELIMITERS_ARRAY_NEWLINE); for (const prop of props) { if (isListenerProp(prop)) { if (!prop.key.isStatic) { args.push(genProp(prop, context, true)); continue; } const keyName = getStaticPropKeyName(prop); const keyFrag = genPropKey(prop, context); if (!prop.handler) { handlerGroups.add(keyName, keyFrag, [ "(", ...genPropValue(prop.values, context), ")" ]); continue; } if (!!prop.handlerModifiers && (prop.handlerModifiers.keys.length > 0 || prop.handlerModifiers.nonKeys.length > 0) || prop.values.length <= 1) { const handlerExp = genEventHandler(context, prop.values, prop.handlerModifiers, { asComponentProp: true }); handlerGroups.add(keyName, keyFrag, handlerExp); } else for (const value of prop.values) { const handlerExp = genEventHandler(context, [value], prop.handlerModifiers, { asComponentProp: true }); handlerGroups.add(keyName, keyFrag, handlerExp); } continue; } args.push(genProp(prop, context, true, true, directStaticLiteralProps && isDirectStaticLiteralProp(prop, context))); if (prop.model) { if (prop.key.isStatic) { const keyName = `onUpdate:${(0, _vue_shared.camelize)(prop.key.content)}`; const keyFrag = [JSON.stringify(keyName)]; handlerGroups.add(keyName, keyFrag, genModelHandler(prop.values[0], context)); } else { const keyFrag = [ "[\"onUpdate:\" + ", ...genExpression(prop.key, context), "]" ]; args.push([ ...keyFrag, ": () => ", ...genModelHandler(prop.values[0], context) ]); } const { key, modelModifiers } = prop; if (modelModifiers && modelModifiers.length) { const modifiersKey = key.isStatic ? genStaticModifierPropKey(key.content) : [ "[", ...genExpression(key, context), " + \"Modifiers\"]" ]; const modifiersVal = genDirectiveModifiers(modelModifiers); args.push([...modifiersKey, directStaticLiteralProps ? `: { ${modifiersVal} }` : `: () => ({ ${modifiersVal} })`]); } } } handlerGroups.fill(); if (dynamicProps) args.push([`$: `, ...dynamicProps]); return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args); } function genDynamicProps(props, context, directStaticLiteralProps = false) { 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, void 0, directStaticLiteralProps)); continue; } else if (p.kind === 1) { if (p.model) { const entries = [genProp(p, context)]; const updateKey = p.key.isStatic ? [JSON.stringify(`onUpdate:${(0, _vue_shared.camelize)(p.key.content)}`)] : [ "[\"onUpdate:\" + ", ...genExpression(p.key, context), "]" ]; entries.push([ ...updateKey, ": ", ...genModelHandler(p.values[0], context) ]); const { modelModifiers } = p; if (modelModifiers && modelModifiers.length) { const modifiersKey = p.key.isStatic ? genStaticModifierPropKey(p.key.content) : [ "[", ...genExpression(p.key, context), " + \"Modifiers\"]" ]; const modifiersVal = genDirectiveModifiers(modelModifiers); entries.push([...modifiersKey, `: { ${modifiersVal} }`]); } expr = genMulti(DELIMITERS_OBJECT_NEWLINE, ...entries); } else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context, false, false)); } 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, wrapHandler = true, directStaticLiteral = false) { let values = genPropValue(prop.values, context); if (prop.toDisplayString) values = genCall(context.helper("toDisplayString"), values); return [ ...genPropKey(prop, context), ": ", ...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, { asComponentProp: true, extraWrap: wrapHandler }) : isStatic ? directStaticLiteral ? values : [ "() => (", ...values, ")" ] : values ]; } /** * Static literal values are safe to emit directly because reading them cannot * touch reactive state. Keep handlers, v-model values, and dynamic expressions * as getter sources to preserve lazy access and merge semantics. */ function isDirectStaticLiteralProp(prop, context) { return prop.key.isStatic && prop.values.length === 1 && !prop.handler && !prop.model && isDirectConstantValue(prop.values[0], context); } function isDirectConstantValue(value, context) { value = context.getExpressionReplacement(value); if (value.isStatic) return true; const ast = value.ast; if (ast === null) return value.content === "true" || value.content === "false" || value.content === "null" || value.content === "undefined"; if (!ast) return false; return isDirectConstantAst(ast); } function isDirectConstantAst(node) { switch (node.type) { case "StringLiteral": case "NumericLiteral": case "BooleanLiteral": case "NullLiteral": case "BigIntLiteral": return true; case "Identifier": return node.name === "undefined"; case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression)); case "ArrayExpression": return node.elements.every((element) => element === null || element.type !== "SpreadElement" && isDirectConstantAst(element)); case "ObjectExpression": return node.properties.every((prop) => prop.type === "ObjectProperty" && !prop.computed && isDirectConstantAst(prop.value)); } return false; } function isDirectTemplateConstantAst(node) { switch (node.type) { case "StringLiteral": case "NumericLiteral": case "BooleanLiteral": case "NullLiteral": case "BigIntLiteral": return true; case "Identifier": return node.name === "undefined"; case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression)); } return false; } function genRawSlots(slots, context, slotDeclarations) { if (!slots.length) return; slots = [...slots.filter((slot) => !isConditionalOrLoopSlot(slot)), ...slots.filter(isConditionalOrLoopSlot)]; const staticSlots = slots[0]; if (staticSlots.slotType === 0) { const defaultSlot = getSingleDefaultSlot(staticSlots); if (defaultSlot && slots.length === 1) return genSlotBlockWithProps(defaultSlot, context); return genStaticSlots(staticSlots, context, slotDeclarations, slots.length > 1 ? slots.slice(1) : void 0); } else return genStaticSlots({ slotType: 0, slots: {} }, context, slotDeclarations, slots); } function isConditionalOrLoopSlot(slot) { return slot.slotType === 3 || slot.slotType === 2; } function getSingleDefaultSlot({ slots }) { const names = Object.keys(slots); return names.length === 1 && names[0] === "default" ? slots.default : void 0; } function genStaticSlots({ slots }, context, slotDeclarations, dynamicSlots) { const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]); if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context, slotDeclarations)]); return genMulti(DELIMITERS_OBJECT_NEWLINE, ...args); } function genDynamicSlots(slots, context, slotDeclarations) { return genMulti(DELIMITERS_ARRAY_NEWLINE, ...slots.map((slot) => slot.slotType === 0 ? genStaticSlots(slot, context, slotDeclarations) : slot.slotType === 4 ? slot.slots.content : genDynamicSlot(slot, context, slotDeclarations, slot.slotType !== 2))); } function genDynamicSlot(slot, context, slotDeclarations, withFunction = false) { let frag; switch (slot.slotType) { case 1: frag = genBasicDynamicSlot(slot, context, slotDeclarations); break; case 2: frag = genLoopSlot(slot, context); break; case 3: frag = genConditionalSlot(slot, context, slotDeclarations); } if (!withFunction) return frag; return [ "() => (", ...frag, ")" ]; } function genBasicDynamicSlot(slot, context, slotDeclarations) { const { name, fn } = slot; const slotName = context.getUniqueLocalName("s"); slotDeclarations.push(slotName); return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], [ `fn: ${slotName} || (${slotName} = `, ...genSlotBlockWithProps(fn, context, false), ")" ]); } function genLoopSlot(slot, context) { const { name, fn, loop, keyProp } = slot; const { value, key, index, source } = loop; const plugins = context.options.expressionPlugins; const idToPathMap = parseValueDestructure(value, context); const keyToPathMap = parseValueDestructure(key, context); const indexToPathMap = parseValueDestructure(index, context); const [depth, exitScope] = context.enterScope(); const itemVar = `_for_item${depth}`; const idMap = buildDestructureIdMap(idToPathMap, `${itemVar}.value`, plugins); idMap[itemVar] = null; const args = [itemVar]; if (key) { const keyVar = `_for_key${depth}`; args.push(keyVar); Object.assign(idMap, buildDestructureIdMap(keyToPathMap, `${keyVar}.value`, plugins)); idMap[keyVar] = null; } else if (index) args.push("_"); if (index) { const indexVar = `_for_index${depth}`; args.push(indexVar); Object.assign(idMap, buildDestructureIdMap(indexToPathMap, `${indexVar}.value`, plugins)); idMap[indexVar] = null; } const renderSlot = [ ...genMulti([ "(", ")", ", " ], ...args), " => ", ...context.withId(() => genSlotBlockWithProps(fn, context, false), idMap) ]; exitScope(); const rawIdMap = {}; const collect = (map) => map.forEach((_, id) => rawIdMap[id] = null); collect(idToPathMap); collect(keyToPathMap); collect(indexToPathMap); const rawParams = context.withId(() => genAliasParams(value, key, index, context), rawIdMap); const getName = [ ...rawParams, " => (", ...context.withId(() => genExpression(name, context), rawIdMap), ")" ]; const getKey = keyProp && [ ...rawParams, " => (", ...context.withId(() => genExpression(keyProp, context), rawIdMap), ")" ]; return [...genCall(context.helper("createForSlots"), [ "() => (", ...genExpression(source, context), ")" ], renderSlot, getName, getKey)]; } function genConditionalSlot(slot, context, slotDeclarations) { const { condition, positive, negative } = slot; return [ ...genExpression(condition, context), INDENT_START, NEWLINE, "? ", ...genDynamicSlot(positive, context, slotDeclarations), NEWLINE, ": ", ...negative ? genDynamicSlot(negative, context, slotDeclarations) : ["void 0"], INDENT_END ]; } function genSlotBlockWithProps(oper, context, emitNonStableFlag = true) { let propsName; let exitScope; let depth; const { props } = oper; const idToPathMap = props ? parseValueDestructure(props, context) : /* @__PURE__ */ new Map(); if (props) { if (props.ast) { [depth, exitScope] = context.enterScope(); propsName = `_slotProps${depth}`; } else propsName = props.content; } const idMap = idToPathMap.size ? buildDestructureIdMap(idToPathMap, propsName || "", context.options.expressionPlugins) : {}; if (propsName) idMap[propsName] = null; const exitSlotBlock = context.enterSlotBlock(); const hasStableRoot = hasStableSlotRoot(oper, context); if (!hasStableRoot) markSlotRootOperations(oper, context); let blockFn = context.withId(() => genBlock(oper, context, propsName ? [propsName] : []), idMap); if (emitNonStableFlag && !hasStableRoot) blockFn = genCall(context.helper("extend"), blockFn, [`{ _: ${genFlags(1, ["NON_STABLE"])} }`]); exitSlotBlock(); exitScope && exitScope(); return blockFn; } //#endregion //#region packages/compiler-vapor/src/generators/slotOutlet.ts function genSlotOutlet(oper, context) { const { helper } = context; const { id, name, fallback, flags } = oper; const [frag, push] = buildCodeFragment(); let fallbackArg; if (fallback) { if (context.inSlotBlock) markSlotRootOperations(fallback, context); fallbackArg = genBlock(fallback, context); } const createSlot = helper("createSlot"); const rawPropsArg = genRawProps(oper.props, context, true); const nameArg = name.isStatic && name.content === "default" && !rawPropsArg && !fallbackArg && !flags ? void 0 : name.isStatic ? genExpression(name, context) : [ "() => (", ...genExpression(name, context), ")" ]; push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, genSlotFlags(flags))); return frag; } function genSlotFlags(flags) { if (!flags) return; const names = []; if (flags & 1) names.push("NO_SLOTTED"); if (flags & 2) names.push("ONCE"); if (flags & 4) names.push("FORWARDED"); if (flags & 8) names.push("SHARED_FALLBACK"); return genFlags(flags, names); } //#endregion //#region packages/compiler-vapor/src/generators/vShow.ts function genVShow(oper, context) { const { element } = oper; return genCall(context.helper("applyVShow"), `n${element}`, [ `() => (`, ...genExpression(oper.dir.exp, context), `)` ]); } //#endregion //#region packages/compiler-vapor/src/generators/directive.ts function genBuiltinDirective(oper, context) { let call; switch (oper.name) { case "show": call = genVShow(oper, context); break; case "model": call = genVModel(oper, context); break; default: return []; } return [NEWLINE, ...oper.once ? genOnce(call, context) : call]; } /** * user directives via `withVaporDirectives`, emitted at the end of the block * so the element's props, children and v-model are in place first */ function genCustomDirectives(operations, context) { const byElement = /* @__PURE__ */ new Map(); for (const oper of operations) if (oper.type === 13 && !oper.builtin) { const dirs = byElement.get(oper.element); if (dirs) dirs.push(oper); else byElement.set(oper.element, [oper]); } const [frag, push] = buildCodeFragment(); for (const dirs of byElement.values()) push(...genElementDirectives(dirs, context)); return frag; } function genElementDirectives(opers, context) { const { helper } = context; const element = `n${opers[0].element}`; const directiveItems = opers.map(genDirectiveItem); const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems); const call = genCall(helper("withVaporDirectives"), element, directives); return [NEWLINE, ...opers[0].once ? genOnce(call, context) : call]; function genDirectiveItem({ dir, name, asset }) { const directiveVar = asset ? (0, _vue_compiler_dom.toValidAssetId)(name, "directive") : genExpression((0, _vue_shared.extend)((0, _vue_compiler_dom.createSimpleExpression)(name, false), { ast: null }), 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); } } //#endregion //#region packages/compiler-vapor/src/generators/key.ts function genKey(oper, context) { const { id, value, block, slotRoot } = oper; const [frag, push] = buildCodeFragment(); const blockFn = genBlock(block, context); push(NEWLINE, `const n${id} = `, ...genCall(context.helper("createKeyedFragment"), [ `() => (`, ...genExpression(value, context), ")" ], blockFn, slotRoot ? "true" : false)); return frag; } function genSetBlockKey(oper, context) { return [NEWLINE, ...genCall(context.helper("setBlockKey"), `n${oper.element}`, genExpression(oper.value, context))]; } //#endregion //#region packages/compiler-vapor/src/generators/operation.ts function genOperations(opers, context) { const [frag, push] = buildCodeFragment(); for (const operation of opers) push(...genOperationWithInsertionState(operation, context)); return frag; } function genOperationWithInsertionState(oper, context) { const [frag, push] = buildCodeFragment(); if (isBlockOperation(oper) && oper.parent) push(...genInsertionState(oper, context)); push(...genOperation(oper, context)); return frag; } function genOperation(oper, context) { switch (oper.type) { case 2: return genSetBlockKey(oper, context); case 3: return genSetProp(oper, context); case 4: return genDynamicProps$1(oper, context); case 5: return genSetText(oper, context); case 6: return genSetEvent(oper, context); case 7: return genSetDynamicEvents(oper, context); case 8: return genSetHtml(oper, context); case 9: return genSetTemplateRef(oper, context); case 10: return genInsertNode(oper, context); case 14: return genIf(oper, context); case 15: return genFor(oper, context); case 16: return genKey(oper, context); case 11: return genCreateComponent(oper, context); case 12: return genSlotOutlet(oper, context); case 13: return genBuiltinDirective(oper, context); case 17: return genGetTextChild(oper, context); default: throw new Error(`Unhandled operation type in genOperation: ${oper}`); } } function genEffects(effects, context, genExtraFrag) { const [frag, push] = buildCodeFragment(); let start = 0; for (let i = 0; i < effects.length; i++) { const effect = effects[i]; if (effect.once) { push(...genReactiveEffects(effects.slice(start, i), context)); push(...genOperations(effect.operations, context)); start = i + 1; } } push(...genReactiveEffects(effects.slice(start), context, genExtraFrag)); return frag; } function genReactiveEffects(effects, context, genExtraFrag) { const { helper } = context; const expressions = effects.flatMap((effect) => effect.expressions); const [frag, push, unshift] = buildCodeFragment(); const shouldDeclare = genExtraFrag === void 0; let operationsCount = 0; const { ids, frag: declarationFrags, varNames, expressionReplacements } = processExpressions(context, expressions, shouldDeclare); if (shouldDeclare && !declarationFrags.length && !varNames.length) { const effect = effects.length === 1 ? effects[0] : void 0; const operation = effect && effect.operations.length === 1 ? effect.operations[0] : void 0; if (operation && operation.type === 9 && operation.effect && !operation.refFor) return context.withExpressionReplacements(expressionReplacements, () => context.withId(() => genSetTemplateRefBinding(operation, context), ids)); } return context.withExpressionReplacements(expressionReplacements, () => { push(...declarationFrags); for (let i = 0; i < effects.length; i++) { const effect = effects[i]; operationsCount += effect.operations.length; const frags = context.withId(() => genEffect(effect, context), ids); i > 0 && push(NEWLINE); if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";"); push(...frags); } if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) { unshift(`{`, INDENT_START, NEWLINE); push(INDENT_END, NEWLINE, "}"); if (!effects.length) unshift(NEWLINE); } if (effects.length) { unshift(NEWLINE, `${helper("renderEffect")}(() => `); push(`)`); } if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", ")); if (genExtraFrag) push(...context.withId(genExtraFrag, ids)); return frag; }); } function genEffect({ operations }, context) { const [frag, push] = buildCodeFragment(); const operationsExps = genOperations(operations, context); if (operationsExps.filter((frag) => frag === NEWLINE).length > 1) push(...operationsExps); else push(...operationsExps.filter((frag) => frag !== NEWLINE)); return frag; } function genInsertionState(operation, context) { const { parent, anchor, appendIndex } = operation; return [NEWLINE, ...genCall(context.helper("setInsertionState"), `n${parent}`, anchor != null ? `n${anchor}` : appendIndex ? String(appendIndex) : void 0)]; } //#endregion //#region packages/compiler-vapor/src/generators/template.ts function genTemplates(templates, context) { const result = []; templates.forEach(({ content, ns, root, static: isStatic }, i) => { let args = JSON.stringify(content).replace(IMPORT_EXPR_RE, `" + $1 + "`); const flags = (root ? 1 : 0) | (isStatic ? 2 : 0); if (flags || ns) args += `, ${flags}`; if (ns) args += `, ${ns}`; result.push(`const ${context.tName(i)} = ${context.helper("template")}(${args})\n`); }); return result.join(""); } function genSelf(dynamic, context, flushBeforeDynamic) { const [frag, push] = buildCodeFragment(); const { id, template, operation, hasDynamicChild } = dynamic; if (id !== void 0 && template !== void 0) { if (operation && operation.type === 10 && operation.appendIndex !== void 0) push(...genInsertionState(operation, context)); push(NEWLINE, `const n${id} = ${context.tName(template)}()`); } if (operation) push(...genOperationWithInsertionState(operation, context)); if (hasDynamicChild) push(...genChildren(dynamic, context, push, `n${id}`, flushBeforeDynamic)); return frag; } function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flushBeforeDynamic) { const [frag, push] = buildCodeFragment(); const { children } = dynamic; let offset = 0; /** * `reusable` means the previous access target is a p* cursor that can be * reassigned by the next lookup. Referenced n* variables must stay stable. */ let prev; for (const [index, child] of children.entries()) { if (child.flags & 2) offset--; if (child.flags & 4 && child.template != null) { if (child.anchor !== void 0) { const elementIndex = index + offset; const variable = `n${child.anchor}`; pushBlock(NEWLINE, `const ${variable} = `, ...genAccessPath(context, from, elementIndex, prev)); prev = [ variable, elementIndex, false ]; } flushBeforeDynamic && flushBeforeDynamic(child, push); push(...genSelf(child, context, flushBeforeDynamic)); continue; } const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0; const ownsSubtree = child.operation !== void 0; if (id === void 0 && (!child.hasDynamicChild || ownsSubtree)) { flushBeforeDynamic && flushBeforeDynamic(child, push); push(...genSelf(child, context, flushBeforeDynamic)); continue; } const elementIndex = index + offset; const inlinePlaceholder = id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6); const accessPath = genAccessPath(context, from, elementIndex, prev, child.isText); if (inlinePlaceholder) { if (prev && prev[2]) { push(...genChildren(child, context, pushBlock, [ "(", prev[0], " = ", ...accessPath, ")" ], flushBeforeDynamic)); prev = [ prev[0], elementIndex, true ]; continue; } if (!hasAdjacentFollowingAccessChild(children, index, elementIndex, offset)) { push(...genChildren(child, context, pushBlock, accessPath, flushBeforeDynamic)); continue; } } let variable; if (id === void 0 && prev && prev[2]) { variable = prev[0]; pushBlock(NEWLINE, `${variable} = `, ...accessPath); } else { variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`; pushBlock(NEWLINE, id === void 0 ? `let ${variable} = ` : `const ${variable} = `, ...accessPath); } if (id === child.anchor && (!child.hasDynamicChild || ownsSubtree)) { flushBeforeDynamic && flushBeforeDynamic(child, push); push(...genSelf(child, context, flushBeforeDynamic)); } prev = [ variable, elementIndex, id === void 0 ]; if (!ownsSubtree) push(...genChildren(child, context, pushBlock, variable, flushBeforeDynamic)); } return frag; } /** * Build one DOM lookup path while preserving the fast sibling walk: * adjacent nodes use _next(prev), otherwise fall back to _nthChild(parent). */ function genAccessPath({ helper }, from, elementIndex, prev, isText) { const textHint = isText ? "true" : void 0; if (prev) return elementIndex - prev[1] === 1 ? genCall(helper("next"), prev[0], textHint) : genCall(helper("nthChild"), from, String(elementIndex), textHint); if (elementIndex === 0) return genCall(helper("child"), from, textHint); if (elementIndex === 1) { const firstChild = genCall(helper("child"), from); return genCall(helper("next"), firstChild, textHint); } return genCall(helper("nthChild"), from, String(elementIndex), textHint); } /** * Only inline a placeholder when materializing it would not save a parent * lookup. If its child tree needs the parent more than once, keep p* so the * generated code does not duplicate _child/_nthChild work. */ function canInlinePlaceholder(dynamic) { return dynamic.hasDynamicChild === true && countParentAccessUsages(dynamic) === 1; } /** * A following access can reuse the current placeholder cursor only when it is * the next DOM sibling. Gapped siblings need _nthChild(parent, index) instead. * Kept in lockstep with genChildren's traversal rules. */ function hasAdjacentFollowingAccessChild(children, index, elementIndex, offset) { let futureOffset = offset; for (let i = index + 1; i < children.length; i++) { const child = children[i]; if (child.flags & 2) futureOffset--; if (child.flags & 4 && child.anchor === void 0) continue; if (!!(child.flags & 1) || child.hasDynamicChild) return i + futureOffset - elementIndex === 1; } return false; } /** * Mirrors genChildren's traversal closely enough to count how many emitted * access paths would start from this placeholder's parent. This is the guard * that keeps inline placeholders from duplicating parent lookups. */ function countParentAccessUsages(dynamic) { let usages = 0; let offset = 0; let prev; for (const [index, child] of dynamic.children.entries()) { if (child.flags & 2) offset--; if (child.flags & 4 && child.template != null && child.anchor === void 0) continue; const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0; if (id === void 0 && !child.hasDynamicChild) continue; const elementIndex = index + offset; const usesParent = !prev || elementIndex - prev[0] !== 1; if (id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6)) { if (prev && prev[1]) { if (usesParent) usages++; prev = [elementIndex, true]; continue; } if (!hasAdjacentFollowingAccessChild(dynamic.children, index, elementIndex, offset)) { if (usesParent) usages++; continue; } } if (usesParent) usages++; prev = [elementIndex, id === void 0]; } return usages; } //#endregion //#region packages/compiler-vapor/src/generators/block.ts function genBlock(oper, context, args = [], root) { return [ "(", ...args, ") => {", INDENT_START, ...genBlockContent(oper, context, root), INDENT_END, NEWLINE, "}" ]; } function genBlockContent(block, context, root, genEffectsExtraFrag, skippedEffectIndexes) { const [frag, push] = buildCodeFragment(); const { dynamic, effect, operation, returns } = block; const modelOperations = operation.filter(isVModelOperation); const modelElements = new Set(modelOperations.map((oper) => oper.element)); const isModelListener = (oper) => isVModelListener(oper, modelElements); const isDeferred = (oper) => isVModelOperation(oper) || isModelListener(oper); const modelListenerEffects = []; if (modelElements.size) { for (let i = 0; i < effect.length; i++) if (!(skippedEffectIndexes && skippedEffectIndexes.has(i)) && effect[i].operations.every(isModelListener)) modelListenerEffects.push(effect[i]); } const resetBlock = context.enterBlock(block); const singleUseAssetComponentNames = root ? collectSingleUseAssetComponents(block) : void 0; const prevSingleUseAssetComponentNames = context.singleUseAssetComponentNames; if (singleUseAssetComponentNames) context.singleUseAssetComponentNames = singleUseAssetComponentNames; if (root) { for (let name of context.ir.component) { if (singleUseAssetComponentNames && singleUseAssetComponentNames.has(name)) continue; const id = (0, _vue_compiler_dom.toValidAssetId)(name, "component"); const maybeSelfReference = name.endsWith("__self"); if (maybeSelfReference) name = name.slice(0, -6); push(NEWLINE, `const ${id} = `, ...genCall(context.helper("resolveComponent"), JSON.stringify(name), maybeSelfReference ? "true" : void 0)); } genResolveAssets("directive", "resolveDirective"); } let operationIndex = 0; let effectIndex = 0; const flushPendingOperations = (operationEnd, effectEnd, push) => { while (operationIndex < operationEnd) { const oper = operation[operationIndex]; if (!isDeferred(oper)) push(...genOperationWithInsertionState(oper, context)); operationIndex++; } if (effectIndex < effectEnd) { push(...genEffectRange(effectIndex, effectEnd)); effectIndex = effectEnd; } }; const flushBeforeDynamic = (dynamic, push) => { const operation = dynamic.operation; if (operation && isBlockOperation(operation) && operation.operationIndex !== void 0 && operation.effectIndex !== void 0) flushPendingOperations(operation.operationIndex, operation.effectIndex, push); }; for (const child of dynamic.children) { flushBeforeDynamic(child, push); push(...genSelf(child, context, flushBeforeDynamic)); } for (const child of dynamic.children) if (!child.hasDynamicChild) push(...genChildren(child, context, push, `n${child.id}`, flushBeforeDynamic)); if (operationIndex < operation.length) push(...genOperations(operation.slice(operationIndex).filter((oper) => !isDeferred(oper)), context)); if (effectIndex < effect.length) push(...genEffectRange(effectIndex, effect.length, genEffectsExtraFrag)); else if (genEffectsExtraFrag) push(...genEffects([], context, genEffectsExtraFrag)); if (modelOperations.length) { push(...genOperations(modelOperations, context)); push(...genOperations(operation.filter(isModelListener), context)); if (modelListenerEffects.length) push(...genEffects(modelListenerEffects, context)); } push(...genCustomDirectives(operation, context)); push(NEWLINE, `return `); const returnNodes = returns.map((n) => `n${n}`); push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "[]"]); resetBlock(); context.singleUseAssetComponentNames = prevSingleUseAssetComponentNames; return frag; function genEffectRange(start, end, genExtraFrag) { if (!skippedEffectIndexes && !modelListenerEffects.length) return genEffects(effect.slice(start, end), context, genExtraFrag); const effects = []; for (let i = start; i < end; i++) if (!(skippedEffectIndexes && skippedEffectIndexes.has(i)) && !modelListenerEffects.includes(effect[i])) effects.push(effect[i]); if (effects.length || genExtraFrag) return genEffects(effects, context, genExtraFrag); return []; } function genResolveAssets(kind, helper) { for (const name of context.ir[kind]) push(NEWLINE, `const ${(0, _vue_compiler_dom.toValidAssetId)(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name))); } } function isVModelOperation(oper) { return oper.type === 13 && oper.builtin === true && oper.name === "model"; } function isVModelListener(oper, modelElements) { return (oper.type === 6 || oper.type === 7 || oper.type === 4 && oper.listeners || oper.type === 3 && !oper.prop.modifier && (0, _vue_shared.isOn)(oper.prop.key.content)) && modelElements.has(oper.element); } function markSlotRootOperations(block, context, sharedFallback = false) { if (hasStableSlotRoot(block, context)) return; sharedFallback = sharedFallback || hasMultipleDynamicSlotRoots(block); for (let i = 0; i < block.returns.length; i++) { const child = findReturnedDynamic$1(block, block.returns[i]); const operation = child && child.operation; if (!operation) continue; if (operation.type === 14) markSlotRootIf(operation, context, sharedFallback); else if (operation.type === 15) markSlotRootFor(operation, context); else if (operation.type === 16) { operation.slotRoot = true; markSlotRootOperations(operation.block, context, sharedFallback); } else if (operation.type === 11) markSlotRootComponent(operation); else if (operation.type === 12) { operation.flags |= 4; if (sharedFallback) operation.flags |= 8; } } } function markSlotRootIf(operation, context, sharedFallback) { if (!operation.once) operation.slotRoot = true; markSlotRootOperations(operation.positive, context, sharedFallback); const negative = operation.negative; if (!negative) return; if (negative.type === 14) markSlotRootIf(negative, context, sharedFallback); else markSlotRootOperations(negative, context, sharedFallback); } function markSlotRootFor(operation, context) { if (!operation.once) operation.slotRoot = true; markSlotRootOperations(operation.render, context, true); } function hasMultipleDynamicSlotRoots(block) { let count = 0; for (let i = 0; i < block.returns.length; i++) { const child = findReturnedDynamic$1(block, block.returns[i]); if (child && child.operation && ++count > 1) return true; } return false; } function markSlotRootComponent(operation) { if (!operation.once && operation.dynamic && !operation.dynamic.isStatic) operation.slotRoot = true; } function findReturnedDynamic$1(block, id) { for (let i = 0; i < block.dynamic.children.length; i++) { const child = block.dynamic.children[i]; if (child.id === id) return child; } } const commentOnlyTemplateRE = /^(?:)+$/; function hasStableSlotRoot(block, context) { let hasValidRoot = false; for (let i = 0; i < block.returns.length; i++) { const id = block.returns[i]; const child = findReturnedDynamic$1(block, id); const operation = child && child.operation; if (!operation) { if (child && isStableTemplateSlotRoot(child, context)) hasValidRoot = true; continue; } switch (operation.type) { case 11: if (!operation.dynamic || operation.dynamic.isStatic) { hasValidRoot = true; continue; } continue; case 16: if (hasStableSlotRoot(operation.block, context)) { hasValidRoot = true; continue; } continue; default: continue; } } return hasValidRoot; } function isStableTemplateSlotRoot(child, context) { if (child.template == null) return false; const content = context.ir.template.entries[child.template].content; return content !== "" && !commentOnlyTemplateRE.test(content.trim()); } function collectSingleUseAssetComponents(block) { const usageMap = /* @__PURE__ */ new Map(); const seenOperations = /* @__PURE__ */ new Set(); visitBlock(block, true); const names = /* @__PURE__ */ new Set(); for (const [name, usage] of usageMap) if (usage.count === 1 && usage.root) names.add(name); return names; function visitBlock(block, rootCandidate) { visitDynamic(block.dynamic, rootCandidate); for (const operation of block.operation) visitOperation(operation, rootCandidate); for (const effect of block.effect) for (const operation of effect.operations) visitOperation(operation, false); } function visitDynamic(dynamic, rootCandidate) { if (dynamic.operation) visitOperation(dynamic.operation, rootCandidate); for (const child of dynamic.children) visitDynamic(child, rootCandidate); } function visitOperation(operation, rootCandidate) { if (seenOperations.has(operation)) return; seenOperations.add(operation); if (operation.type === 11) { if (operation.asset) { const usage = usageMap.get(operation.tag) || { count: 0, root: false }; usage.count++; if (rootCandidate) usage.root = true; usageMap.set(operation.tag, usage); } visitSlots(operation.slots); return; } switch (operation.type) { case 14: visitBlock(operation.positive, false); if (operation.negative) { if (operation.negative.type === 14) visitOperation(operation.negative, false); else visitBlock(operation.negative, false); } break; case 15: visitBlock(operation.render, false); break; case 16: visitBlock(operation.block, false); break; case 12: if (operation.fallback) visitBlock(operation.fallback, false); } } function visitSlots(slots) { for (const slot of slots) switch (slot.slotType) { case 0: for (const name in slot.slots) visitBlock(slot.slots[name], false); break; case 1: case 2: visitBlock(slot.fn, false); break; case 3: visitSlots([slot.positive]); if (slot.negative) visitSlots([slot.negative]); } } } //#endregion //#region packages/compiler-vapor/src/generate.ts const idWithTrailingDigitsRE = /^([A-Za-z_$][\w$]*)(\d+)$/; const helperNameAliases = { withVaporKeys: "withKeys", withVaporModifiers: "withModifiers" }; var CodegenContext = class { withExpressionReplacements(map, fn) { if (map.size === 0) return fn(); this.expressionReplacements.unshift(map); try { return fn(); } finally { (0, _vue_shared.remove)(this.expressionReplacements, map); } } getExpressionReplacement(node) { for (const map of this.expressionReplacements) { const replacement = map.get(node); if (replacement) return replacement; } return node; } withId(fn, map) { const { identifiers } = this; const ids = Object.keys(map); for (const id of ids) { identifiers[id] || (identifiers[id] = []); identifiers[id].unshift(map[id] || id); } const ret = fn(); ids.forEach((id) => (0, _vue_shared.remove)(identifiers[id], map[id] || id)); return ret; } enterBlock(block) { const parent = this.block; this.block = block; return () => this.block = parent; } enterSlotBlock() { const parent = this.inSlotBlock; this.inSlotBlock = true; return () => this.inSlotBlock = parent; } enterScope() { return [this.scopeLevel++, () => this.scopeLevel--]; } getUniqueLocalName(base, scopeNames = this.generatedLocalNames) { const name = this.findAvailableName(base, scopeNames); scopeNames.add(name); this.generatedLocalNames.add(name); return name; } isNameAvailable(name, reservedNames) { var _this$identifiers$nam; if (this.bindingNames.has(name) || reservedNames.has(name)) return false; if ((_this$identifiers$nam = this.identifiers[name]) === null || _this$identifiers$nam === void 0 ? void 0 : _this$identifiers$nam.length) return false; for (const alias of this.helpers.values()) if (alias === name) return false; return true; } findAvailableName(base, reservedNames) { if (this.isNameAvailable(base, reservedNames)) return base; const map = this.nextIdMap.get(base); let next = 1; while (true) { const id = getNextId(map, next); const name = `${base}${id}`; if (this.isNameAvailable(name, reservedNames)) return name; next = id + 1; } } initNextIdMap() { if (this.bindingNames.size === 0) return; const map = /* @__PURE__ */ new Map(); for (const name of this.bindingNames) { const m = idWithTrailingDigitsRE.exec(name); if (!m) continue; const prefix = m[1]; const num = Number(m[2]); let set = map.get(prefix); if (!set) map.set(prefix, set = /* @__PURE__ */ new Set()); set.add(num); } for (const [prefix, nums] of map) this.nextIdMap.set(prefix, buildNextIdMap(nums)); } tName(i) { let name = this.templateVars.get(i); if (name) return name; const map = this.nextIdMap.get("t"); let lastId = this.lastIdMap.get("t") || -1; for (let j = this.lastTIndex + 1; j <= i; j++) this.templateVars.set(j, name = `t${lastId = getNextId(map, Math.max(j, lastId + 1))}`); this.lastIdMap.set("t", lastId); this.lastTIndex = i; return name; } pName(i) { return this.idName("p", i); } kName(i) { return this.idName("k", i); } idName(prefix, i) { const map = this.nextIdMap.get(prefix); let lastId = this.lastIdMap.get(prefix) || -1; this.lastIdMap.set(prefix, lastId = getNextId(map, Math.max(i, lastId + 1))); return `${prefix}${lastId}`; } constructor(ir, options) { this.ir = ir; this.bindingNames = /* @__PURE__ */ new Set(); this.helpers = /* @__PURE__ */ new Map(); this.needsTemplateRefSetter = false; this.inSlotBlock = false; this.helper = (name) => { if (this.helpers.has(name)) return this.helpers.get(name); const base = `_${helperNameAliases[name] || name}`; const alias = this.findAvailableName(base, this.generatedLocalNames); this.helpers.set(name, alias); return alias; }; this.delegates = /* @__PURE__ */ new Set(); this.dynamicPropNames = /* @__PURE__ */ new Map(); this.identifiers = Object.create(null); this.expressionReplacements = []; this.seenInlineHandlerNames = Object.create(null); this.scopeLevel = 0; this.templateVars = /* @__PURE__ */ new Map(); this.nextIdMap = /* @__PURE__ */ new Map(); this.lastIdMap = /* @__PURE__ */ new Map(); this.generatedLocalNames = /* @__PURE__ */ new Set(); this.lastTIndex = -1; const defaultOptions = { mode: "module", prefixIdentifiers: true, sourceMap: false, filename: `template.vue.html`, scopeId: null, runtimeGlobalName: `Vue`, runtimeModuleName: `vue`, ssrRuntimeModuleName: "vue/server-renderer", ssr: false, isTS: false, inSSR: false, inline: false, bindingMetadata: {}, expressionPlugins: [] }; this.options = (0, _vue_shared.extend)(defaultOptions, options); this.block = ir.block; this.bindingNames = new Set(this.options.bindingMetadata ? Object.keys(this.options.bindingMetadata) : []); this.initNextIdMap(); } }; function generate(ir, options = {}) { const [frag, push] = buildCodeFragment(); const context = new CodegenContext(ir, options); const { inline, bindingMetadata } = options; const functionName = "render"; const args = ["_ctx"]; if (bindingMetadata && !inline) args.push("$props", "$emit", "$attrs", "$slots"); const signature = (options.isTS ? args.map((arg) => `${arg}: any`) : args).join(", "); if (!inline) push(NEWLINE, `export function ${functionName}(${signature}) {`); push(INDENT_START); const templateRefSetterHelper = ir.hasTemplateRef ? context.helper("createTemplateRefSetter") : void 0; const body = genBlockContent(ir.block, context, true); if (context.needsTemplateRefSetter) push(NEWLINE, `const ${setTemplateRefIdent} = ${templateRefSetterHelper}()`); else if (templateRefSetterHelper) context.helpers.delete("createTemplateRefSetter"); push(...body); push(INDENT_END, NEWLINE); if (!inline) push("}"); const delegates = genDelegates(context); const templates = genTemplates(ir.template.entries, context); const preamble = genHelperImports(context) + genAssetImports(context) + templates + genDynamicPropNames(context) + delegates; const newlineCount = [...preamble].filter((c) => c === "\n").length; if (newlineCount && !inline) frag.unshift(...new Array(newlineCount).fill(LF)); let [code, map] = codeFragmentToString(frag, context); if (!inline) code = preamble + code; return { code, ast: ir, preamble, map: map && map.toJSON(), helpers: new Set(Array.from(context.helpers.keys())) }; } function genDynamicPropNames({ dynamicPropNames }) { let code = ""; for (const [json, id] of dynamicPropNames) code += `const ${id} = ${json}\n`; return code; } function genDelegates({ delegates, helper }) { return delegates.size ? genCall(helper("delegateEvents"), ...Array.from(delegates).map((v) => `"${v}"`)).join("") + "\n" : ""; } function genHelperImports({ helpers, options }) { let imports = ""; if (helpers.size) imports += `import { ${Array.from(helpers).map(([h, alias]) => `${h} as ${alias}`).join(", ")} } from '${options.runtimeModuleName}';\n`; return imports; } function genAssetImports({ ir }) { const assetImports = ir.node.imports; let imports = ""; for (const assetImport of assetImports) { const name = assetImport.exp.content; imports += `import ${name} from '${assetImport.path}';\n`; } return imports; } //#endregion //#region packages/compiler-vapor/src/transforms/vBind.ts function normalizeBindShorthand(arg, context) { if (arg.type !== 4 || !arg.isStatic) { context.options.onError((0, _vue_compiler_dom.createCompilerError)(53, arg.loc)); return (0, _vue_compiler_dom.createSimpleExpression)("", true, arg.loc); } const propName = (0, _vue_shared.camelize)(arg.content); const exp = (0, _vue_compiler_dom.createSimpleExpression)(propName, false, arg.loc); exp.ast = null; return exp; } const transformVBind = (dir, node, context) => { const { loc, modifiers } = dir; let { exp } = dir; let arg = dir.arg; const modifiersString = modifiers.map((s) => s.content); if (!exp) exp = normalizeBindShorthand(arg, context); if (!exp.content.trim()) { context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, loc)); exp = (0, _vue_compiler_dom.createSimpleExpression)("", true, loc); } arg = resolveExpression(arg); const excludeNumber = node.tagType === 1 || node.tagType === 2 || !!context.options.isCustomElement(node.tag) || modifiersString.includes("prop") || !arg.isStatic || (0, _vue_shared.isSpecialBooleanAttr)(arg.content) || isCheckboxValueProp(node, arg.content) || !modifiersString.includes("attr") && (isFoldableBooleanAttr(arg.content) || isModelValueProp(node, arg.content)); exp = resolveExpression(exp, excludeNumber); if (arg.isStatic && isReservedProp(arg.content)) return; let camel = false; if (modifiersString.includes("camel")) { if (arg.isStatic) arg = (0, _vue_shared.extend)({}, arg, { content: (0, _vue_shared.camelize)(arg.content) }); else camel = true; } return { key: arg, value: exp, loc, runtimeCamelize: camel, modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : void 0 }; }; //#endregion //#region packages/compiler-vapor/src/transforms/transformKey.ts const dynamicComponentKeys = /* @__PURE__ */ new WeakMap(); const transformKey = (node, context) => { if (node.type !== 1 || context.inVOnce || findDir$5(node, "for") || node.tagType === 3 && findDir$5(node, /^(if|else-if|else|slot)$/, true)) return; if (isComponentTag(node.tag) && findProp$1(node, "is", true, true)) { const prop = findProp$1(node, "key", false, true); if (prop) dynamicComponentKeys.set(node, prop.type === 6 ? (0, _vue_compiler_dom.createSimpleExpression)(prop.value ? prop.value.content : "", true) : prop.exp || normalizeBindShorthand(prop.arg, context)); return; } const dir = findProp$1(node, "key", true, true); if (!dir || dir.type === 6) return; let value; value = dir.exp || normalizeBindShorthand(dir.arg, context); if (isStaticExpression(value, context.options.bindingMetadata)) return; let id = context.reference(); context.dynamic.flags |= 6; context.node = node = wrapTemplate(node, ["key"]); const block = newBlock(node); const exitBlock = context.enterBlock(block); return () => { exitBlock(); context.dynamic.operation = { type: 16, id, ...context.effectBoundary(), value, block }; }; }; //#endregion //#region packages/compiler-vapor/src/transforms/vHtml.ts function ignoreVHtmlChildren(node, context, clear) { if (!node.children.length) return; const dir = (0, _vue_compiler_dom.findDir)(node, "html"); if (!dir) return; context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(55, dir.loc)); if (clear === "node") node.children.length = 0; else context.childrenTemplate.length = 0; } const transformVHtml = (dir, node, context) => { let { exp, loc } = dir; if (!exp) { context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(54, loc)); exp = EMPTY_EXPRESSION; } ignoreVHtmlChildren(node, context, "template"); if (node.tagType === 1) return { key: (0, _vue_compiler_dom.createSimpleExpression)("innerHTML", true, loc), value: exp }; context.registerEffect([exp], { type: 8, element: context.reference(), value: exp }); }; //#endregion //#region packages/compiler-vapor/src/transforms/transformElement.ts const isReservedProp = /*#__PURE__*/ (0, _vue_shared.makeMap)(",key,ref,ref_for,ref_key,"); /** * `true-value` / `false-value` are only read back by `v-model` on a checkbox, * and they are dropped from the ssr output, so a checkbox that only carries * them in the template has nothing left to read from after hydration. A * dynamic `type` can still make the element a checkbox at runtime. */ function isCheckboxValueProp(node, key) { if (node.tag !== "input" || key !== "true-value" && key !== "false-value") return false; const type = findProp$1(node, "type"); return type ? type.type === 7 || type.value.content === "checkbox" : (0, _vue_compiler_dom.hasDynamicKeyVBind)(node); } /** * Props the template string cannot carry, so they have to be applied by a * runtime prop setter instead: * - `innerHTML` / `textContent` are dom properties that set the element's * content; as a content attribute they would only sit on the element and * the content would never be written, so vdom always sets them as a dom * property too, see `shouldSetAsProp` * - `