UNPKG

@vue-jsx-vapor/compiler

Version:
1,360 lines (1,340 loc) 98.4 kB
//#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion const __babel_parser = __toESM(require("@babel/parser")); const __vue_shared = __toESM(require("@vue/shared")); const __vue_compiler_dom = __toESM(require("@vue/compiler-dom")); const ast_kit = __toESM(require("ast-kit")); const __babel_types = __toESM(require("@babel/types")); const source_map_js = __toESM(require("source-map-js")); //#region src/ir/component.ts let IRDynamicPropsKind = /* @__PURE__ */ function(IRDynamicPropsKind$1) { IRDynamicPropsKind$1[IRDynamicPropsKind$1["EXPRESSION"] = 0] = "EXPRESSION"; IRDynamicPropsKind$1[IRDynamicPropsKind$1["ATTRIBUTE"] = 1] = "ATTRIBUTE"; return IRDynamicPropsKind$1; }({}); let IRSlotType = /* @__PURE__ */ function(IRSlotType$1) { IRSlotType$1[IRSlotType$1["STATIC"] = 0] = "STATIC"; IRSlotType$1[IRSlotType$1["DYNAMIC"] = 1] = "DYNAMIC"; IRSlotType$1[IRSlotType$1["LOOP"] = 2] = "LOOP"; IRSlotType$1[IRSlotType$1["CONDITIONAL"] = 3] = "CONDITIONAL"; IRSlotType$1[IRSlotType$1["EXPRESSION"] = 4] = "EXPRESSION"; return IRSlotType$1; }({}); //#endregion //#region src/ir/index.ts let IRNodeTypes = /* @__PURE__ */ function(IRNodeTypes$1) { IRNodeTypes$1[IRNodeTypes$1["ROOT"] = 0] = "ROOT"; IRNodeTypes$1[IRNodeTypes$1["BLOCK"] = 1] = "BLOCK"; IRNodeTypes$1[IRNodeTypes$1["SET_PROP"] = 2] = "SET_PROP"; IRNodeTypes$1[IRNodeTypes$1["SET_DYNAMIC_PROPS"] = 3] = "SET_DYNAMIC_PROPS"; IRNodeTypes$1[IRNodeTypes$1["SET_TEXT"] = 4] = "SET_TEXT"; IRNodeTypes$1[IRNodeTypes$1["SET_EVENT"] = 5] = "SET_EVENT"; IRNodeTypes$1[IRNodeTypes$1["SET_DYNAMIC_EVENTS"] = 6] = "SET_DYNAMIC_EVENTS"; IRNodeTypes$1[IRNodeTypes$1["SET_HTML"] = 7] = "SET_HTML"; IRNodeTypes$1[IRNodeTypes$1["SET_TEMPLATE_REF"] = 8] = "SET_TEMPLATE_REF"; IRNodeTypes$1[IRNodeTypes$1["INSERT_NODE"] = 9] = "INSERT_NODE"; IRNodeTypes$1[IRNodeTypes$1["PREPEND_NODE"] = 10] = "PREPEND_NODE"; IRNodeTypes$1[IRNodeTypes$1["CREATE_COMPONENT_NODE"] = 11] = "CREATE_COMPONENT_NODE"; IRNodeTypes$1[IRNodeTypes$1["SLOT_OUTLET_NODE"] = 12] = "SLOT_OUTLET_NODE"; IRNodeTypes$1[IRNodeTypes$1["DIRECTIVE"] = 13] = "DIRECTIVE"; IRNodeTypes$1[IRNodeTypes$1["DECLARE_OLD_REF"] = 14] = "DECLARE_OLD_REF"; IRNodeTypes$1[IRNodeTypes$1["IF"] = 15] = "IF"; IRNodeTypes$1[IRNodeTypes$1["FOR"] = 16] = "FOR"; IRNodeTypes$1[IRNodeTypes$1["GET_TEXT_CHILD"] = 17] = "GET_TEXT_CHILD"; IRNodeTypes$1[IRNodeTypes$1["CREATE_NODES"] = 18] = "CREATE_NODES"; IRNodeTypes$1[IRNodeTypes$1["SET_NODES"] = 19] = "SET_NODES"; return IRNodeTypes$1; }({}); let DynamicFlag = /* @__PURE__ */ function(DynamicFlag$1) { DynamicFlag$1[DynamicFlag$1["NONE"] = 0] = "NONE"; /** * This node is referenced and needs to be saved as a variable. */ DynamicFlag$1[DynamicFlag$1["REFERENCED"] = 1] = "REFERENCED"; /** * This node is not generated from template, but is generated dynamically. */ DynamicFlag$1[DynamicFlag$1["NON_TEMPLATE"] = 2] = "NON_TEMPLATE"; /** * This node needs to be inserted back into the template. */ DynamicFlag$1[DynamicFlag$1["INSERT"] = 4] = "INSERT"; return DynamicFlag$1; }({}); function isBlockOperation(op) { const type = op.type; return type === IRNodeTypes.CREATE_COMPONENT_NODE || type === IRNodeTypes.SLOT_OUTLET_NODE || type === IRNodeTypes.IF || type === IRNodeTypes.FOR; } //#endregion //#region src/transforms/utils.ts function newDynamic() { return { flags: DynamicFlag.REFERENCED, children: [] }; } function newBlock(node) { return { type: 1, node, dynamic: newDynamic(), effect: [], operation: [], returns: [], tempId: 0 }; } function createBranch(node, context, isVFor) { context.node = node = wrapFragment(node); const branch = newBlock(node); const exitBlock = context.enterBlock(branch, isVFor); context.reference(); return [branch, exitBlock]; } function wrapFragment(node) { if (node.type === "JSXFragment" || isTemplate(node)) return node; return (0, __babel_types.jsxFragment)((0, __babel_types.jsxOpeningFragment)(), (0, __babel_types.jsxClosingFragment)(), [node.type === "JSXElement" ? node : (0, __babel_types.jsxExpressionContainer)(node)]); } const EMPTY_EXPRESSION = (0, __vue_compiler_dom.createSimpleExpression)("", true); const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node); //#endregion //#region src/utils.ts function propToExpression(prop, context) { return prop.type === "JSXAttribute" && prop.value?.type === "JSXExpressionContainer" ? resolveExpression(prop.value.expression, context) : EMPTY_EXPRESSION; } function isConstantExpression(exp) { return (0, __vue_compiler_dom.isLiteralWhitelisted)(exp.content) || (0, __vue_shared.isGloballyAllowed)(exp.content) || getLiteralExpressionValue(exp) !== null; } function getLiteralExpressionValue(exp) { if (exp.ast) { if ([ "StringLiteral", "NumericLiteral", "BigIntLiteral" ].includes(exp.ast.type)) return exp.ast.value; else if (exp.ast.type === "TemplateLiteral" && exp.ast.expressions.length === 0) return exp.ast.quasis[0].value.cooked; } return exp.isStatic ? exp.content : null; } const isConstant = (node) => { if (!node) return false; if (node.type === "Identifier") return node.name === "undefined" || (0, __vue_shared.isGloballyAllowed)(node.name); return (0, __vue_compiler_dom.isConstantNode)(node, {}); }; const EMPTY_TEXT_REGEX = /^[\t\v\f \u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*[\n\r]\s*$/; const START_EMPTY_TEXT_REGEX = /^\s*[\n\r]/; const END_EMPTY_TEXT_REGEX = /[\n\r]\s*$/; function resolveJSXText(node) { if (EMPTY_TEXT_REGEX.test(String(node.extra?.raw))) return ""; let value = node.value; if (START_EMPTY_TEXT_REGEX.test(value)) value = value.trimStart(); if (END_EMPTY_TEXT_REGEX.test(value)) value = value.trimEnd(); return value; } function isEmptyText(node) { return node.type === "JSXText" && EMPTY_TEXT_REGEX.test(String(node.extra?.raw)) || node.type === "JSXExpressionContainer" && node.expression.type === "JSXEmptyExpression"; } function resolveSimpleExpressionNode(exp) { if (!exp.isStatic) { const value = getLiteralExpressionValue(exp); if (value !== null) return (0, __vue_compiler_dom.createSimpleExpression)(String(value), true, exp.loc); } return exp; } function resolveExpression(node, context, effect = false) { if (!node) return (0, __vue_compiler_dom.createSimpleExpression)("", true); node = (0, __vue_compiler_dom.unwrapTSNode)(node.type === "JSXExpressionContainer" ? node.expression : node); const isStatic = node.type === "StringLiteral" || node.type === "JSXText" || node.type === "JSXIdentifier"; let source = node.type === "JSXEmptyExpression" ? "" : node.type === "JSXIdentifier" ? node.name : node.type === "StringLiteral" ? node.value : node.type === "JSXText" ? resolveJSXText(node) : node.type === "Identifier" ? node.name : context.ir.source.slice(node.start, node.end); const location = node.loc; if (source && !isStatic && effect && !isConstant(node)) { source = `() => (${source})`; node._offset = 7; } return resolveSimpleExpression(source, isStatic, location, isStatic ? void 0 : node); } function resolveSimpleExpression(source, isStatic, location, ast) { const result = (0, __vue_compiler_dom.createSimpleExpression)(source, isStatic, resolveLocation(location, source)); result.ast = ast ?? null; return result; } function resolveLocation(location, context) { return location ? { start: { line: location.start.line, column: location.start.column + 1, offset: location.start.index }, end: { line: location.end.line, column: location.end.column + 1, offset: location.end.index }, source: (0, __vue_shared.isString)(context) ? context : context.ir.source.slice(location.start.index, location.end.index) } : { start: { line: 1, column: 1, offset: 0 }, end: { line: 1, column: 1, offset: 0 }, source: "" }; } const namespaceRE = /^(?:\$([\w-]+)\$)?([\w-]+)?/; function resolveDirective(node, context, withFn = false) { const { value, name } = node; let nameString = name.type === "JSXNamespacedName" ? name.namespace.name : name.type === "JSXIdentifier" ? name.name : ""; const isDirective = nameString.startsWith("v-"); let modifiers = []; let isStatic = true; let argString = name.type === "JSXNamespacedName" ? name.name.name : ""; if (name.type !== "JSXNamespacedName" && !argString) [nameString, ...modifiers] = nameString.split("_"); else { const result = argString.match(namespaceRE); if (result) { let modifierString = ""; [, argString, modifierString] = result; if (argString) { argString = argString.replaceAll("_", "."); isStatic = false; if (modifierString && modifierString.startsWith("_")) modifiers = modifierString.slice(1).split("_"); } else if (modifierString) [argString, ...modifiers] = modifierString.split("_"); } } const arg = isDirective ? argString && name.type === "JSXNamespacedName" ? resolveSimpleExpression(argString, isStatic, name.name.loc) : void 0 : resolveSimpleExpression(nameString, true, name.loc); const exp = value ? withFn && value.type === "JSXExpressionContainer" ? resolveExpressionWithFn(value.expression, context) : resolveExpression(value, context) : void 0; return { type: __vue_compiler_dom.NodeTypes.DIRECTIVE, name: isDirective ? nameString.slice(2) : "bind", rawName: getText(name, context), exp, arg, loc: resolveLocation(node.loc, context), modifiers: modifiers.map((modifier) => (0, __vue_compiler_dom.createSimpleExpression)(modifier)) }; } function resolveExpressionWithFn(node, context) { const text = getText(node, context); return node.type === "Identifier" ? resolveSimpleExpression(text, false, node.loc) : resolveSimpleExpression(text, false, node.loc, (0, __babel_parser.parseExpression)(`(${text})=>{}`, { plugins: context.options.expressionPlugins })); } function isJSXComponent(node) { if (node.type !== "JSXElement") return false; const { openingElement } = node; if (openingElement.name.type === "JSXIdentifier") { const name = openingElement.name.name; return !(0, __vue_shared.isHTMLTag)(name) && !(0, __vue_shared.isSVGTag)(name); } else return openingElement.name.type === "JSXMemberExpression"; } function findProp(expression, key) { if (expression?.type === "JSXElement") for (const attr of expression.openingElement.attributes) { const name = attr.type === "JSXAttribute" && (attr.name.type === "JSXIdentifier" ? attr.name.name : attr.name.type === "JSXNamespacedName" ? attr.name.namespace.name : "").split("_")[0]; if (name && ((0, __vue_shared.isString)(key) ? name === key : key.test(name))) return attr; } } function getText(node, content) { return content.ir.source.slice(node.start, node.end); } function isTemplate(node) { if (node.type === "JSXElement" && node.openingElement.name.type === "JSXIdentifier") return node.openingElement.name.name === "template"; } //#endregion //#region src/generators/utils.ts const NEWLINE = Symbol(`newline`); const INDENT_START = Symbol(`indent start`); const INDENT_END = Symbol(`indent end`); function buildCodeFragment(...frag) { const push = frag.push.bind(frag); const unshift = frag.unshift.bind(frag); return [ frag, push, unshift ]; } function genMulti([left, right, seg, placeholder], ...frags) { if (placeholder) { while (frags.length > 0 && !frags.at(-1)) frags.pop(); frags = frags.map((frag$1) => frag$1 || placeholder); } else frags = frags.filter(Boolean); const frag = []; push(left); for (const [i, fn] of frags.entries()) { push(fn); if (i < frags.length - 1) push(seg); } push(right); return frag; function push(fn) { if (!(0, __vue_shared.isArray)(fn)) fn = [fn]; frag.push(...fn); } } const DELIMITERS_ARRAY = [ "[", "]", ", " ]; const DELIMITERS_ARRAY_NEWLINE = [ [ "[", INDENT_START, NEWLINE ], [ INDENT_END, NEWLINE, "]" ], [", ", NEWLINE] ]; const DELIMITERS_OBJECT = [ "{ ", " }", ", " ]; const DELIMITERS_OBJECT_NEWLINE = [ [ "{", INDENT_START, NEWLINE ], [ INDENT_END, NEWLINE, "}" ], [", ", NEWLINE] ]; function genCall(name, ...frags) { const hasPlaceholder = (0, __vue_shared.isArray)(name); const fnName = hasPlaceholder ? name[0] : name; const placeholder = hasPlaceholder ? name[1] : "null"; return [fnName, ...genMulti([ "(", ")", ", ", placeholder ], ...frags)]; } function codeFragmentToString(code, context) { const { options: { filename, sourceMap } } = context; let map; if (sourceMap) { map = new source_map_js.SourceMapGenerator(); map.setSourceContent(filename, context.ir.source); map._sources.add(filename); } let codegen = ""; const pos = { line: 1, column: 1, offset: 0 }; let indentLevel = 0; for (let frag of code) { if (!frag) continue; if (frag === NEWLINE) frag = [`\n${` `.repeat(indentLevel)}`, __vue_compiler_dom.NewlineType.Start]; else if (frag === INDENT_START) { indentLevel++; continue; } else if (frag === INDENT_END) { indentLevel--; continue; } if ((0, __vue_shared.isString)(frag)) frag = [frag]; let [code$1, newlineIndex = __vue_compiler_dom.NewlineType.None, loc, name] = frag; codegen += code$1; if (map) { if (loc) addMapping(loc.start, name); if (newlineIndex === __vue_compiler_dom.NewlineType.Unknown) (0, __vue_compiler_dom.advancePositionWithMutation)(pos, code$1); else { pos.offset += code$1.length; if (newlineIndex === __vue_compiler_dom.NewlineType.None) pos.column += code$1.length; else { if (newlineIndex === __vue_compiler_dom.NewlineType.End) newlineIndex = code$1.length - 1; pos.line++; pos.column = code$1.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 }); } } //#endregion //#region src/generators/expression.ts function genExpression(node, context, assignment) { const { content, ast, isStatic, loc } = node; if (isStatic) return [[ JSON.stringify(content), __vue_compiler_dom.NewlineType.None, loc ]]; if (!node.content.trim() || ast === false || isConstantExpression(node)) return [[ content, __vue_compiler_dom.NewlineType.None, loc ], assignment && ` = ${assignment}`]; if (ast === null) return genIdentifier(content, context, loc, assignment); const ids = []; const parentStackMap = /* @__PURE__ */ new Map(); const parentStack = []; (0, ast_kit.walkIdentifiers)(ast, (id) => { ids.push(id); parentStackMap.set(id, parentStack.slice()); }, false, parentStack); let hasMemberExpression = false; if (ids.length) { const [frag, push] = buildCodeFragment(); const isTSNode = ast && __vue_compiler_dom.TS_NODE_TYPES.includes(ast.type); const offset = (ast?.start ? ast.start - 1 : 0) - (ast._offset || 0); ids.sort((a, b) => a.start - b.start).forEach((id, i) => { const start = id.start - 1 - offset; const end = id.end - 1 - offset; const last = ids[i - 1]; if (!isTSNode || i !== 0) { const leadingText = content.slice(last ? last.end - 1 - offset : 0, start); if (leadingText.length) push([leadingText, __vue_compiler_dom.NewlineType.Unknown]); } const source = content.slice(start, end); const parentStack$1 = parentStackMap.get(id); const parent = parentStack$1.at(-1); hasMemberExpression ||= !!parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression"); push(...genIdentifier(source, context, { start: (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, parent)); if (i === ids.length - 1 && end < content.length && !isTSNode) push([content.slice(end), __vue_compiler_dom.NewlineType.Unknown]); }); if (assignment && hasMemberExpression) push(` = ${assignment}`); return frag; } else return [[ content, __vue_compiler_dom.NewlineType.Unknown, loc ]]; } function genIdentifier(raw, context, loc, assignment, parent) { const { identifiers } = context; const name = raw; const idMap = identifiers[raw]; if (idMap && idMap.length) { const replacement = idMap[0]; if ((0, __vue_shared.isString)(replacement)) if (parent && parent.type === "ObjectProperty" && parent.shorthand) return [[ `${name}: ${replacement}`, __vue_compiler_dom.NewlineType.None, loc ]]; else return [[ replacement, __vue_compiler_dom.NewlineType.None, loc ]]; else return genExpression(replacement, context, assignment); } let prefix; if ((0, __vue_compiler_dom.isStaticProperty)(parent) && parent.shorthand) prefix = `${raw}: `; raw = withAssignment(raw); return [prefix, [ raw, __vue_compiler_dom.NewlineType.None, loc, name ]]; function withAssignment(s) { return assignment ? `${s} = ${assignment}` : s; } } //#endregion //#region src/generators/vModel.ts const helperMap = { text: "applyTextModel", radio: "applyRadioModel", checkbox: "applyCheckboxModel", select: "applySelectModel", dynamic: "applyDynamicModel" }; function genVModel(oper, context) { const { modelType, element, dir: { exp, modifiers } } = oper; return [NEWLINE, ...genCall(context.helper(helperMap[modelType]), `n${element}`, [ `() => (`, ...genExpression(exp, context), `)` ], genModelHandler(exp, context), modifiers.length ? `{ ${modifiers.map((e) => `${e.content}: true`).join(",")} }` : void 0)]; } function genModelHandler(exp, context) { return [ `${context.options.isTS ? `(_value: any)` : `_value`} => (`, ...genExpression(exp, context, "_value"), ")" ]; } //#endregion //#region src/generators/vShow.ts function genVShow(oper, context) { return [NEWLINE, ...genCall(context.helper("applyVShow"), `n${oper.element}`, [ `() => (`, ...genExpression(oper.dir.exp, context), `)` ])]; } //#endregion //#region src/generators/directive.ts function genBuiltinDirective(oper, context) { switch (oper.name) { case "show": return genVShow(oper, context); case "model": return genVModel(oper, context); default: return []; } } /** * user directives via `withVaporDirectives` * TODO the compiler side is implemented but no runtime support yet * it was removed due to perf issues */ function genDirectivesForElement(id, context) { const dirs = filterCustomDirectives(id, context.block.operation); return dirs.length ? genCustomDirectives(dirs, context) : []; } function genCustomDirectives(opers, context) { const { helper } = context; const element = `n${opers[0].element}`; const directiveItems = opers.map(genDirectiveItem); const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems); return [NEWLINE, ...genCall(helper("withVaporDirectives"), element, directives)]; function genDirectiveItem({ dir, name, asset }) { const directiveVar = asset ? (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); } } function genDirectiveModifiers(modifiers) { return modifiers.map((value) => `${(0, __vue_compiler_dom.isSimpleIdentifier)(value) ? value : JSON.stringify(value)}: true`).join(", "); } function filterCustomDirectives(id, operations) { return operations.filter((oper) => oper.type === IRNodeTypes.DIRECTIVE && oper.element === id && !oper.builtin); } //#endregion //#region src/generators/event.ts function genSetEvent(oper, context) { const { helper } = context; const { element, key, keyOverride, value, modifiers, delegate, effect } = oper; const name = genName(); const handler = genEventHandler(context, value, modifiers); const eventOptions = genEventOptions(); if (delegate) { context.delegates.add(key.content); if (!context.block.operation.some(isSameDelegateEvent)) return [ NEWLINE, `n${element}.$evt${key.content} = `, ...handler ]; } return [NEWLINE, ...genCall(helper(delegate ? "delegate" : "on"), `n${element}`, name, handler, eventOptions)]; function genName() { const expr = genExpression(key, context); if (keyOverride) { const find = JSON.stringify(keyOverride[0]); const replacement = JSON.stringify(keyOverride[1]); const wrapped = [ "(", ...expr, ")" ]; return [ ...wrapped, ` === ${find} ? ${replacement} : `, ...wrapped ]; } else return genExpression(key, context); } function genEventOptions() { const { options } = modifiers; if (!options.length && !effect) return; return genMulti(DELIMITERS_OBJECT_NEWLINE, effect && ["effect: true"], ...options.map((option) => [`${option}: true`])); } function isSameDelegateEvent(op) { if (op.type === IRNodeTypes.SET_EVENT && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true; } } function genSetDynamicEvents(oper, context) { const { helper } = context; return [NEWLINE, ...genCall(helper("setDynamicEvents"), `n${oper.element}`, genExpression(oper.event, context))]; } function genEventHandler(context, value, modifiers = { nonKeys: [], keys: [] }, extraWrap = false) { let handlerExp = [`() => {}`]; if (value && value.content.trim()) if ((0, __vue_compiler_dom.isMemberExpression)(value, context.options)) { handlerExp = genExpression(value, context); if (!extraWrap) handlerExp = [ `e => `, ...handlerExp, `(e)` ]; } else if ((0, __vue_compiler_dom.isFnExpression)(value, context.options)) handlerExp = 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); handlerExp = [ referencesEvent ? "$event => " : "() => ", hasMultipleStatements ? "{" : "(", ...expr, hasMultipleStatements ? "}" : ")" ]; } const { keys, nonKeys } = modifiers; if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys); if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys); if (extraWrap) handlerExp.unshift(`() => `); return handlerExp; } function genWithModifiers(context, handler, nonKeys) { return genCall(context.helper("withModifiers"), handler, JSON.stringify(nonKeys)); } function genWithKeys(context, handler, keys) { return genCall(context.helper("withKeys"), handler, JSON.stringify(keys)); } //#endregion //#region src/generators/prop.ts const helpers = { setText: { name: "setText" }, setHtml: { name: "setHtml" }, setClass: { name: "setClass" }, setStyle: { name: "setStyle" }, setValue: { name: "setValue" }, setAttr: { name: "setAttr", needKey: true }, setProp: { name: "setProp", needKey: true }, setDOMProp: { name: "setDOMProp", needKey: true }, setDynamicProps: { name: "setDynamicProps" } }; function genSetProp(oper, context) { const { helper } = context; const { prop: { key, values, modifier }, tag } = oper; const resolvedHelper = getRuntimeHelper(tag, key.content, modifier); const propValue = genPropValue(values, context); return [NEWLINE, ...genCall([helper(resolvedHelper.name), null], `n${oper.element}`, resolvedHelper.needKey ? genExpression(key, context) : false, propValue)]; } function genDynamicProps(oper, context) { const { helper } = context; const values = oper.props.map((props) => Array.isArray(props) ? genLiteralObjectProps(props, context) : props.kind === IRDynamicPropsKind.ATTRIBUTE ? genLiteralObjectProps([props], context) : genExpression(props.value, context)); return [NEWLINE, ...genCall(helper("setDynamicProps"), `n${oper.element}`, genMulti(DELIMITERS_ARRAY, ...values), oper.root && "true")]; } function genLiteralObjectProps(props, context) { return genMulti(DELIMITERS_OBJECT, ...props.map((prop) => [ ...genPropKey(prop, context), `: `, ...genPropValue(prop.values, context) ])); } function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModifiers }, context) { const { helper } = context; const handlerModifierPostfix = handlerModifiers && handlerModifiers.options ? handlerModifiers.options.map(__vue_shared.capitalize).join("") : ""; if (node.isStatic) { const keyName = (handler ? (0, __vue_shared.toHandlerKey)(node.content) : node.content) + handlerModifierPostfix; return [[ (0, __vue_compiler_dom.isSimpleIdentifier)(keyName) ? keyName : JSON.stringify(keyName), __vue_compiler_dom.NewlineType.None, node.loc ]]; } let key = genExpression(node, context); if (runtimeCamelize) key = genCall(helper("camelize"), key); if (handler) key = genCall(helper("toHandlerKey"), key); return [ "[", modifier && `${JSON.stringify(modifier)} + `, ...key, handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : void 0, "]" ]; } function genPropValue(values, context) { if (values.length === 1) return genExpression(values[0], context); return genMulti(DELIMITERS_ARRAY, ...values.map((expr) => genExpression(expr, context))); } function getRuntimeHelper(tag, key, modifier) { const tagName = tag.toUpperCase(); if (modifier) if (modifier === ".") return getSpecialHelper(key, tagName) || helpers.setDOMProp; else return helpers.setAttr; const helper = getSpecialHelper(key, tagName); if (helper) return helper; if (/aria[A-Z]/.test(key)) return helpers.setDOMProp; if ((0, __vue_shared.isSVGTag)(tag)) return helpers.setAttr; if ((0, __vue_shared.shouldSetAsAttr)(tagName, key) || key.includes("-")) return helpers.setAttr; return helpers.setProp; } function getSpecialHelper(keyName, tagName) { if (keyName === "value" && (0, __vue_shared.canSetValueDirectly)(tagName)) return helpers.setValue; else if (keyName === "class") return helpers.setClass; else if (keyName === "style") return helpers.setStyle; else if (keyName === "innerHTML") return helpers.setHtml; else if (keyName === "textContent") return helpers.setText; } //#endregion //#region src/generators/component.ts function genCreateComponent(operation, context) { const { helper } = context; const tag = genTag(); const { root, props, slots, once } = operation; const rawProps = genRawProps(props, context); const rawSlots = genRawSlots(slots, context); return [ NEWLINE, `const n${operation.id} = `, ...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"), ...genDirectivesForElement(operation.id, context) ]; function genTag() { if (operation.dynamic) if (operation.dynamic.isStatic) return genCall(helper("resolveDynamicComponent"), genExpression(operation.dynamic, context)); else return [ "() => (", ...genExpression(operation.dynamic, context), ")" ]; else if (operation.asset) return (0, __vue_compiler_dom.toValidAssetId)(operation.tag, "component"); else return genExpression((0, __vue_shared.extend)((0, __vue_compiler_dom.createSimpleExpression)(operation.tag, false), { ast: null }), context); } } function genRawProps(props, context) { const staticProps = props[0]; if ((0, __vue_shared.isArray)(staticProps)) { if (!staticProps.length && props.length === 1) return; return genStaticProps(staticProps, context, genDynamicProps$1(props.slice(1), context)); } else if (props.length) return genStaticProps([], context, genDynamicProps$1(props, context)); } function genStaticProps(props, context, dynamicProps) { const args = props.map((prop) => genProp(prop, context, true)); if (dynamicProps) args.push([`$: `, ...dynamicProps]); return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args); } function genDynamicProps$1(props, context) { const { helper } = context; const frags = []; for (const p of props) { let expr; if ((0, __vue_shared.isArray)(p)) { if (p.length) frags.push(genStaticProps(p, context)); continue; } else if (p.kind === IRDynamicPropsKind.ATTRIBUTE) expr = genMulti(DELIMITERS_OBJECT, genProp(p, context)); else { expr = genExpression(p.value, context); if (p.handler) expr = genCall(helper("toHandlers"), expr); } frags.push([ "() => (", ...expr, ")" ]); } if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags); } function genProp(prop, context, isStatic) { const values = genPropValue(prop.values, context); return [ ...genPropKey(prop, context), ": ", ...prop.handler ? genEventHandler(context, prop.values[0], prop.handlerModifiers, true) : isStatic ? [ "() => (", ...values, ")" ] : values, ...prop.model ? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)] : [] ]; } function genModelEvent(prop, context) { const name = prop.key.isStatic ? [JSON.stringify(`onUpdate:${(0, __vue_shared.camelize)(prop.key.content)}`)] : [ "[\"onUpdate:\" + ", ...genExpression(prop.key, context), "]" ]; const handler = genModelHandler(prop.values[0], context); return [ ",", NEWLINE, ...name, ": () => ", ...handler ]; } function genModelModifiers(prop, context) { const { key, modelModifiers } = prop; if (!modelModifiers || !modelModifiers.length) return []; const modifiersKey = key.isStatic ? [`${key.content}Modifiers`] : [ "[", ...genExpression(key, context), " + \"Modifiers\"]" ]; const modifiersVal = genDirectiveModifiers(modelModifiers); return [ ",", NEWLINE, ...modifiersKey, `: () => ({ ${modifiersVal} })` ]; } function genRawSlots(slots, context) { if (!slots.length) return; const staticSlots = slots[0]; if (staticSlots.slotType === IRSlotType.STATIC) return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0); else return genStaticSlots({ slotType: IRSlotType.STATIC, slots: {} }, context, slots); } function genStaticSlots({ slots }, context, dynamicSlots) { const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]); if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]); return genMulti(DELIMITERS_OBJECT_NEWLINE, ...args); } function genDynamicSlots(slots, context) { return genMulti(DELIMITERS_ARRAY_NEWLINE, ...slots.map((slot) => slot.slotType === IRSlotType.STATIC ? genStaticSlots(slot, context) : slot.slotType === IRSlotType.EXPRESSION ? slot.slots.content : genDynamicSlot(slot, context, true))); } function genDynamicSlot(slot, context, withFunction = false) { let frag; switch (slot.slotType) { case IRSlotType.DYNAMIC: frag = genBasicDynamicSlot(slot, context); break; case IRSlotType.LOOP: frag = genLoopSlot(slot, context); break; case IRSlotType.CONDITIONAL: frag = genConditionalSlot(slot, context); break; } return withFunction ? [ "() => (", ...frag, ")" ] : frag; } function genBasicDynamicSlot(slot, context) { const { name, fn } = slot; return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]); } function genLoopSlot(slot, context) { const { name, fn, loop } = slot; const { value, key, index, source } = loop; const rawValue = value && value.content; const rawKey = key && key.content; const rawIndex = index && index.content; const idMap = {}; if (rawValue) idMap[rawValue] = rawValue; if (rawKey) idMap[rawKey] = rawKey; if (rawIndex) idMap[rawIndex] = rawIndex; const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context), idMap)]); return [...genCall(context.helper("createForSlots"), genExpression(source, context), [ ...genMulti([ "(", ")", ", " ], rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0, rawKey ? rawKey : rawIndex ? "__" : void 0, rawIndex), " => (", ...slotExpr, ")" ])]; } function genConditionalSlot(slot, context) { const { condition, positive, negative } = slot; return [ ...genExpression(condition, context), INDENT_START, NEWLINE, "? ", ...genDynamicSlot(positive, context), NEWLINE, ": ", ...negative ? [...genDynamicSlot(negative, context)] : ["void 0"], INDENT_END ]; } function genSlotBlockWithProps(oper, context) { let isDestructureAssignment = false; let rawProps; let propsName; let exitScope; let depth; const { props } = oper; const idsOfProps = /* @__PURE__ */ new Set(); if (props) { rawProps = props.content; if (isDestructureAssignment = !!props.ast) { [depth, exitScope] = context.enterScope(); propsName = `_slotProps${depth}`; (0, ast_kit.walkIdentifiers)(props.ast, (id, _, __, ___, isLocal) => { if (isLocal) idsOfProps.add(id.name); }, true); } else idsOfProps.add(propsName = rawProps); } const idMap = {}; idsOfProps.forEach((id) => idMap[id] = isDestructureAssignment ? `${propsName}[${JSON.stringify(id)}]` : null); const blockFn = context.withId(() => genBlock(oper, context, [propsName]), idMap); exitScope && exitScope(); return blockFn; } //#endregion //#region src/generators/dom.ts function genInsertNode({ parent, elements, anchor }, { helper }) { let element = elements.map((el) => `n${el}`).join(", "); if (elements.length > 1) element = `[${element}]`; return [NEWLINE, ...genCall(helper("insert"), element, `n${parent}`, anchor === void 0 ? void 0 : `n${anchor}`)]; } function genPrependNode(oper, { helper }) { return [NEWLINE, ...genCall(helper("prepend"), `n${oper.parent}`, ...oper.elements.map((el) => `n${el}`))]; } //#endregion //#region src/generators/for.ts /** * Flags to optimize vapor `createFor` runtime behavior, shared between the * compiler and the runtime */ let VaporVForFlags = /* @__PURE__ */ function(VaporVForFlags$1) { /** * v-for is the only child of a parent container, so it can take the fast * path with textContent = '' when the whole list is emptied */ VaporVForFlags$1[VaporVForFlags$1["FAST_REMOVE"] = 1] = "FAST_REMOVE"; /** * v-for used on component - we can skip creating child scopes for each block * because the component itself already has a scope. */ VaporVForFlags$1[VaporVForFlags$1["IS_COMPONENT"] = 2] = "IS_COMPONENT"; /** * v-for inside v-ince */ VaporVForFlags$1[VaporVForFlags$1["ONCE"] = 4] = "ONCE"; return VaporVForFlags$1; }({}); function genFor(oper, context) { const { helper } = context; const { source, value, key, index, render, keyProp, once, id, component, onlyChild } = oper; let rawValue = null; const rawKey = key && key.content; const rawIndex = index && index.content; const sourceExpr = [ "() => (", ...genExpression(source, context), ")" ]; const idToPathMap = parseValueDestructure(); const [depth, exitScope] = context.enterScope(); const idMap = {}; const itemVar = `_for_item${depth}`; idMap[itemVar] = null; idToPathMap.forEach((pathInfo, id$1) => { let path = `${itemVar}.value${pathInfo ? pathInfo.path : ""}`; if (pathInfo) { if (pathInfo.helper) { idMap[pathInfo.helper] = null; path = `${pathInfo.helper}(${path}, ${pathInfo.helperArgs})`; } if (pathInfo.dynamic) { const node = idMap[id$1] = (0, __vue_compiler_dom.createSimpleExpression)(path); const plugins = context.options.expressionPlugins; node.ast = (0, __babel_parser.parseExpression)(`(${path})`, { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] }); } else idMap[id$1] = path; } else idMap[id$1] = path; }); const args = [itemVar]; if (rawKey) { const keyVar = `_for_key${depth}`; args.push(`, ${keyVar}`); idMap[rawKey] = `${keyVar}.value`; idMap[keyVar] = null; } if (rawIndex) { const indexVar = `_for_index${depth}`; args.push(`, ${indexVar}`); idMap[rawIndex] = `${indexVar}.value`; idMap[indexVar] = null; } const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap); const selectorDeclarations = []; const selectorSetup = []; for (const [i, { selector }] of selectorPatterns.entries()) { const selectorName = `_selector${id}_${i}`; selectorDeclarations.push(`let ${selectorName}`, NEWLINE); if (i === 0) selectorSetup.push(`({ createSelector }) => {`, INDENT_START); selectorSetup.push(NEWLINE, `${selectorName} = `, ...genCall(`createSelector`, [`() => `, ...genExpression(selector, context)])); if (i === selectorPatterns.length - 1) selectorSetup.push(INDENT_END, NEWLINE, "}"); } const blockFn = context.withId(() => { const frag = []; frag.push("(", ...args, ") => {", INDENT_START); if (selectorPatterns.length || keyOnlyBindingPatterns.length) frag.push(...genBlockContent(render, context, false, () => { const patternFrag = []; for (const [i, { effect }] of selectorPatterns.entries()) { patternFrag.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START); for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context)); patternFrag.push(INDENT_END, NEWLINE, `})`); } for (const { effect } of keyOnlyBindingPatterns) for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context)); return patternFrag; })); else frag.push(...genBlockContent(render, context)); frag.push(INDENT_END, NEWLINE, "}"); return frag; }, idMap); exitScope(); let flags = 0; if (onlyChild) flags |= VaporVForFlags.FAST_REMOVE; if (component) flags |= VaporVForFlags.IS_COMPONENT; if (once) flags |= VaporVForFlags.ONCE; return [ NEWLINE, ...selectorDeclarations, `const n${id} = `, ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0, selectorSetup.length ? selectorSetup : void 0) ]; function parseValueDestructure() { const map = /* @__PURE__ */ new Map(); if (value) { rawValue = value && value.content; if (value.ast) (0, __vue_compiler_dom.walkIdentifiers)(value.ast, (id$1, _, parentStack, ___, isLocal) => { if (isLocal) { let path = ""; let isDynamic = false; let helper$1; let helperArgs; for (let i = 0; i < parentStack.length; i++) { const parent = parentStack[i]; const child = parentStack[i + 1] || id$1; if (parent.type === "ObjectProperty" && parent.value === child) if (parent.key.type === "StringLiteral") path += `[${JSON.stringify(parent.key.value)}]`; else if (parent.computed) { isDynamic = true; path += `[${value.content.slice(parent.key.start - 1, parent.key.end - 1)}]`; } else path += `.${parent.key.name}`; else if (parent.type === "ArrayPattern") { const index$1 = parent.elements.indexOf(child); if (child.type === "RestElement") path += `.slice(${index$1})`; else path += `[${index$1}]`; } else if (parent.type === "ObjectPattern" && child.type === "RestElement") { helper$1 = context.helper("getRestElement"); helperArgs = `[${parent.properties.filter((p) => p.type === "ObjectProperty").map((p) => { if (p.key.type === "StringLiteral") return JSON.stringify(p.key.value); else if (p.computed) { isDynamic = true; return value.content.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")) { isDynamic = true; helper$1 = context.helper("getDefaultValue"); helperArgs = value.content.slice(child.right.start - 1, child.right.end - 1); } } map.set(id$1.name, { path, dynamic: isDynamic, helper: helper$1, helperArgs }); } }, true); else map.set(rawValue, null); } return map; } function genCallback(expr) { if (!expr) return false; const res = context.withId(() => genExpression(expr, context), genSimpleIdMap()); return [ ...genMulti([ "(", ")", ", " ], rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0, rawKey ? rawKey : rawIndex ? "__" : void 0, rawIndex), " => (", ...res, ")" ]; } function genSimpleIdMap() { const idMap$1 = {}; if (rawKey) idMap$1[rawKey] = null; if (rawIndex) idMap$1[rawIndex] = null; idToPathMap.forEach((_, id$1) => idMap$1[id$1] = null); return idMap$1; } } function matchPatterns(render, keyProp, idMap) { const selectorPatterns = []; const keyOnlyBindingPatterns = []; render.effect = render.effect.filter((effect) => { if (keyProp !== void 0) { const selector = matchSelectorPattern(effect, keyProp.ast, idMap); if (selector) { selectorPatterns.push(selector); return false; } const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast); if (keyOnly) { keyOnlyBindingPatterns.push(keyOnly); return false; } } return true; }); return { keyOnlyBindingPatterns, selectorPatterns }; } function matchKeyOnlyBindingPattern(effect, keyAst) { if (effect.expressions.length === 1) { const ast = effect.expressions[0].ast; if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, keyAst)) return { effect }; } } function matchSelectorPattern(effect, keyAst, idMap) { if (effect.expressions.length === 1) { const ast = effect.expressions[0].ast; const offset = effect.expressions[0].loc.start.offset; if (typeof ast === "object" && ast) { const matcheds = []; (0, ast_kit.walkAST)(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 = isKeyOnlyBinding(a, keyAst); const bIsKey = isKeyOnlyBinding(b, keyAst); const bVars = analyzeVariableScopes(b, idMap); if (aIsKey && !bIsKey && !bVars.locals.length) matcheds.push([a, b]); } } } }); if (matcheds.length === 1) { const [key, selector] = matcheds[0]; const content$1 = effect.expressions[0].content; let hasExtraId = false; const parentStackMap = /* @__PURE__ */ new Map(); const parentStack = []; (0, __vue_compiler_dom.walkIdentifiers)(ast, (id) => { if (id.start !== key.start && id.start !== selector.start) hasExtraId = true; parentStackMap.set(id, parentStack.slice()); }, false, parentStack); if (!hasExtraId) { const name = content$1.slice(selector.start - offset, selector.end - offset); return { effect, selector: { content: name, ast: (0, __vue_shared.extend)({}, selector, { start: 1, end: name.length + 1 }), loc: selector.loc, isStatic: false } }; } } } const content = effect.expressions[0].content; if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && isConstant(ast.consequent) && isConstant(ast.alternate)) { const left = ast.test.left; const right = ast.test.right; for (const [a, b] of [[left, right], [right, left]]) { const aIsKey = isKeyOnlyBinding(a, keyAst); const bIsKey = isKeyOnlyBinding(b, keyAst); const bVars = analyzeVariableScopes(b, idMap); if (aIsKey && !bIsKey && !bVars.locals.length) return { effect, selector: { content: content.slice(b.start - offset, b.end - offset), ast: b, loc: b.loc, isStatic: false } }; } } } } function analyzeVariableScopes(ast, idMap) { const globals = []; const locals = []; const ids = []; const parentStackMap = /* @__PURE__ */ new Map(); const parentStack = []; (0, __vue_compiler_dom.walkIdentifiers)(ast, (id) => { ids.push(id); parentStackMap.set(id, parentStack.slice()); }, false, parentStack); for (const id of ids) { if ((0, __vue_shared.isGloballyAllowed)(id.name)) continue; if (idMap[id.name]) locals.push(id.name); else globals.push(id.name); } return { globals, locals }; } function isKeyOnlyBinding(expr, keyAst) { let only = true; (0, ast_kit.walkAST)(expr, { enter(node) { if ((0, __babel_types.isNodesEquivalent)(node, keyAst)) { this.skip(); return; } if (node.type === "Identifier") only = false; } }); return only; } //#endregion //#region 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 src/generators/if.ts function genIf(oper, context, isNested = false) { const { helper } = context; const { condition, positive, negative, once } = oper; const [frag, push] = buildCodeFragment(); const conditionExpr = [ "() => (", ...genExpression(condition, context), ")" ]; const positiveArg = genBlock(positive, context); let negativeArg = false; if (negative) if (negative.type === IRNodeTypes.BLOCK) 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, once && "true")); return frag; } //#endregion //#region src/generators/templateRef.ts const setTemplateRefIdent = `_setTemplateRef`; function genSetTemplateRef(oper, context) { return [ NEWLINE, oper.effect && `r${oper.element} = `, ...genCall(setTemplateRefIdent, `n${oper.element}`, genExpression(oper.value, context), oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : void 0, oper.refFor && "true") ]; } function genDeclareOldRef(oper) { return [NEWLINE, `let r${oper.id}`]; } //#endregion //#region src/generators/text.ts function genSetText(oper, context) { const { helper } = context; const { element, values, generated } = oper; const texts = combineValues(values, context, true); return [NEWLINE, ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)]; } function genGetTextChild(oper, context) { return [NEWLINE, `const x${oper.parent} = ${context.helper("child")}(n${oper.parent})`]; } function genSetNodes(oper, context) { const { helper } = context; const { element, values, generated } = oper; return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context))]; } function genCreateNodes(oper, context) { const { helper } = context; const { id, values } = oper; return [ NEWLINE, `const n${id} = `, ...genCall(helper("createNodes"), values && combineValues(values, context)) ]; } function combineValues(values, context, setText) { return values.flatMap((value, i) => { let exp = genExpression(value, context); if (setText && getLiteralExpressionValue(value) == null) exp = genCall(context.helper("toDisplayString"), exp); if (i > 0) exp.unshift(setText ? " + " : ", "); return exp; }); } //#endregion //#region 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 IRNodeTypes.SET_PROP: return genSetProp(oper, context); case IRNodeTypes.SET_DYNAMIC_PROPS: return genDynamicProps(oper, context); case IRNodeTypes.SET_TEXT: return genSetText(oper, context); case IRNodeTypes.SET_EVENT: return genSetEvent(oper, context); case IRNodeTypes.SET_DYNAMIC_EVENTS: return genSetDynamicEvents(oper, context); case IRNodeTypes.SET_HTML: return genSetHtml(oper, context); case IRNodeTypes.SET_TEMPLATE_REF: return genSetTemplateRef(oper, context); case IRNodeTypes.INSERT_NODE: return genInsertNode(oper, context); case IRNodeTypes.PREPEND_NODE: return genPrependNode(oper, context); case IRNodeTypes.IF: return genIf(oper, context); case IRNodeTypes.FOR: return genFor(oper, context); case IRNodeTypes.CREATE_COMPONENT_NO