From 5b0dce94cfe442757a137855b43d50c2d7a9c454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 25 Nov 2021 14:50:40 +0100 Subject: [PATCH] [REF] code_generator: move generating code to CodeTarget Before this commit, we had two places with code that generate a function code. Now, all this code is moved in a method 'generateCode' on CodeTarget. --- src/compiler/code_generator.ts | 123 ++++++------ .../__snapshots__/t_foreach.test.ts.snap | 3 +- .../__snapshots__/error_handling.test.ts.snap | 18 +- .../__snapshots__/refs.test.ts.snap | 5 +- .../__snapshots__/slots.test.ts.snap | 175 +++++++++--------- .../__snapshots__/t_set.test.ts.snap | 5 +- tests/misc/__snapshots__/memo.test.ts.snap | 6 +- tests/misc/__snapshots__/portal.test.ts.snap | 40 ++-- 8 files changed, 180 insertions(+), 195 deletions(-) diff --git a/src/compiler/code_generator.ts b/src/compiler/code_generator.ts index 48582725..e3e2052c 100644 --- a/src/compiler/code_generator.ts +++ b/src/compiler/code_generator.ts @@ -142,6 +142,8 @@ class CodeTarget { code: string[] = []; hasRoot = false; hasCache = false; + hasRef: boolean = false; + shouldProtectScope: boolean = false; constructor(name: string) { this.name = name; @@ -155,6 +157,30 @@ class CodeTarget { this.code.splice(idx, 0, prefix + line); } } + + generateCode(): string { + let result: string[] = []; + result.push(`function ${this.name}(ctx, node, key = "") {`); + if (this.hasRef) { + result.push(` const refs = ctx.__owl__.refs;`); + } + if (this.shouldProtectScope) { + result.push(` ctx = Object.create(ctx);`); + result.push(` ctx[isBoundary] = 1`); + } + if (this.hasCache) { + result.push(` let cache = ctx.cache || {};`); + result.push(` let nextCache = ctx.cache = {};`); + } + for (let line of this.code) { + result.push(line); + } + if (!this.hasRoot) { + result.push(`return text('');`); + } + result.push(`}`); + return result.join("\n "); + } } const TRANSLATABLE_ATTRS = ["label", "title", "placeholder", "alt"]; @@ -164,13 +190,10 @@ export class CodeGenerator { blocks: BlockDescription[] = []; nextId = 1; nextBlockId = 1; - shouldProtectScope: boolean = false; - shouldDefineAssign: boolean = false; hasSafeContext: boolean; - hasRef: boolean = false; isDebug: boolean = false; - functions: CodeTarget[] = []; - target = new CodeTarget("main"); + targets: CodeTarget[] = []; + target = new CodeTarget("template"); templateName: string; dev: boolean; translateFn: (s: string) => string; @@ -201,67 +224,45 @@ export class CodeGenerator { tKeyExpr: null, }); - let mainCode = this.target.code; - this.target.code = []; - this.target.indentLevel = 0; // define blocks and utility functions - this.addLine(`let { text, createBlock, list, multi, html, toggler, component } = bdom;`); - this.addLine( - `let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;` - ); - if (this.shouldDefineAssign) { - this.addLine(`let assign = Object.assign;`); - } + let mainCode = [ + ` let { text, createBlock, list, multi, html, toggler, component } = bdom;`, + `let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;`, + ]; for (let { id, template } of this.staticCalls) { - this.addLine(`const ${id} = getTemplate(${template});`); + mainCode.push(`const ${id} = getTemplate(${template});`); } // define all blocks if (this.blocks.length) { - this.addLine(``); + mainCode.push(``); for (let block of this.blocks) { if (block.dom) { let xmlString = block.asXmlString(); if (block.dynamicTagName) { xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`); xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`); - this.addLine(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`); + mainCode.push(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`); } else { - this.addLine(`let ${block.blockName} = createBlock(\`${xmlString}\`);`); + mainCode.push(`let ${block.blockName} = createBlock(\`${xmlString}\`);`); } } } } - // define all slots - for (let fn of this.functions) { - this.generateFunctions(fn); + // define all slots/defaultcontent function + if (this.targets.length) { + for (let fn of this.targets) { + mainCode.push(""); + mainCode = mainCode.concat(fn.generateCode()); + } } - // // generate main code - this.target.indentLevel = 0; - this.addLine(``); - this.addLine(`return function template(ctx, node, key = "") {`); - if (this.hasRef) { - this.addLine(` const refs = ctx.__owl__.refs;`); - } - if (this.shouldProtectScope) { - this.addLine(` ctx = Object.create(ctx);`); - this.addLine(` ctx[isBoundary] = 1`); - } - if (this.target.hasCache) { - this.addLine(` let cache = ctx.cache || {};`); - this.addLine(` let nextCache = ctx.cache = {};`); - } - for (let line of mainCode) { - this.addLine(line); - } - if (!this.target.hasRoot) { - throw new Error("missing root block"); - } - this.addLine("}"); - const code = this.target.code.join("\n"); + // generate main code + mainCode.push(""); + mainCode = mainCode.concat("return " + this.target.generateCode()); + const code = mainCode.join("\n "); if (this.isDebug) { const msg = `[Owl Debug]\n${code}`; @@ -331,18 +332,6 @@ export class CodeGenerator { } } - generateFunctions(fn: CodeTarget) { - this.addLine(""); - this.addLine(`function ${fn.name}(ctx, node, key) {`); - if (fn.hasCache) { - this.addLine(`let cache = ctx.cache || {};`); - this.addLine(`let nextCache = ctx.cache = {};`); - } - for (let line of fn.code) { - this.addLine(line); - } - this.addLine(`}`); - } /** * Captures variables that are used inside of an expression. This is useful * because in compiled code, almost all variables are accessed through the ctx @@ -544,7 +533,7 @@ export class CodeGenerator { // t-ref if (ast.ref) { - this.hasRef = true; + this.target.hasRef = true; const isDynamic = INTERP_REGEXP.test(ast.ref); if (isDynamic) { const str = ast.ref.replace( @@ -778,7 +767,6 @@ export class CodeGenerator { let id: string; if (ast.memo) { this.target.hasCache = true; - this.shouldDefineAssign = true; id = this.generateId(); this.addLine(`let memo${id} = ${compileExpr(ast.memo)}`); this.addLine(`let vnode${id} = cache[key${this.target.loopLevel}];`); @@ -799,7 +787,9 @@ export class CodeGenerator { this.compileAST(ast.body, subCtx); if (ast.memo) { this.addLine( - `nextCache[key${this.target.loopLevel}] = assign(${c}[${loopVar}], {memo: memo${id!}});` + `nextCache[key${ + this.target.loopLevel + }] = Object.assign(${c}[${loopVar}], {memo: memo${id!}});` ); } this.target.indentLevel--; @@ -928,7 +918,7 @@ export class CodeGenerator { } compileTSet(ast: ASTTSet, ctx: Context) { - this.shouldProtectScope = true; + this.target.shouldProtectScope = true; const expr = ast.value ? compileExpr(ast.value || "") : "null"; if (ast.body) { const subCtx: Context = createContext(ctx); @@ -987,7 +977,7 @@ export class CodeGenerator { for (let slotName in ast.slots) { let name = this.generateId("slot"); const slot = new CodeTarget(name); - this.functions.push(slot); + this.targets.push(slot); this.target = slot; const subCtx: Context = createContext(ctx); this.compileAST(ast.slots[slotName].content, subCtx); @@ -1002,12 +992,7 @@ export class CodeGenerator { } } const slotInfo = `{${params.join(", ")}}`; - if (this.hasRef) { - slot.code.unshift(` const refs = ctx.__owl__.refs`); - slotStr.push(`'${slotName}': ${slotInfo}`); - } else { - slotStr.push(`'${slotName}': ${slotInfo}`); - } + slotStr.push(`'${slotName}': ${slotInfo}`); } this.target = initialTarget; slotDef = `{${slotStr.join(", ")}}`; @@ -1095,7 +1080,7 @@ export class CodeGenerator { if (ast.defaultContent) { let name = this.generateId("defaultContent"); const slot = new CodeTarget(name); - this.functions.push(slot); + this.targets.push(slot); const initialTarget = this.target; const subCtx: Context = createContext(ctx); this.target = slot; diff --git a/tests/compiler/__snapshots__/t_foreach.test.ts.snap b/tests/compiler/__snapshots__/t_foreach.test.ts.snap index 6e838873..a1190625 100644 --- a/tests/compiler/__snapshots__/t_foreach.test.ts.snap +++ b/tests/compiler/__snapshots__/t_foreach.test.ts.snap @@ -493,7 +493,6 @@ exports[`t-foreach with t-memo 1`] = ` ) { let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - let assign = Object.assign; let block1 = createBlock(\`
\`); let block3 = createBlock(\`

\`); @@ -518,7 +517,7 @@ exports[`t-foreach with t-memo 1`] = ` let d1 = ctx['item'].x; let d2 = ctx['item'].y; c_block2[i1] = withKey(block3([d1, d2]), key1); - nextCache[key1] = assign(c_block2[i1], {memo: memo1}); + nextCache[key1] = Object.assign(c_block2[i1], {memo: memo1}); } let b2 = list(c_block2); return block1([], [b2]); diff --git a/tests/components/__snapshots__/error_handling.test.ts.snap b/tests/components/__snapshots__/error_handling.test.ts.snap index 478a6cb2..f5b3123d 100644 --- a/tests/components/__snapshots__/error_handling.test.ts.snap +++ b/tests/components/__snapshots__/error_handling.test.ts.snap @@ -120,7 +120,7 @@ exports[`can catch errors can catch an error in a component render function 3`] let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {flag: ctx['state'].flag}, key + \`__2\`, node, ctx); } @@ -221,7 +221,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3 = component(\`ClassicCompoent\`, {}, key + \`__2\`, node, ctx); let b4 = component(\`ErrorComponent\`, {}, key + \`__3\`, node, ctx); return multi([b3, b4]); @@ -242,7 +242,7 @@ exports[`can catch errors can catch an error in the constructor call of a compon let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); } @@ -296,7 +296,7 @@ exports[`can catch errors can catch an error in the initial call of a component let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); } @@ -350,7 +350,7 @@ exports[`can catch errors can catch an error in the initial call of a component let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); } @@ -406,7 +406,7 @@ exports[`can catch errors can catch an error in the mounted call 3`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); } @@ -460,7 +460,7 @@ exports[`can catch errors can catch an error in the willPatch call 3`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {message: ctx['state'].message}, key + \`__2\`, node, ctx); } @@ -514,7 +514,7 @@ exports[`can catch errors can catch an error in the willStart call 3`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`ErrorComponent\`, {}, key + \`__2\`, node, ctx); } @@ -581,7 +581,7 @@ exports[`can catch errors can catch an error origination from a child's willStar let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3 = component(\`ClassicCompoent\`, {}, key + \`__2\`, node, ctx); let b4 = component(\`ErrorComponent\`, {}, key + \`__3\`, node, ctx); return multi([b3, b4]); diff --git a/tests/components/__snapshots__/refs.test.ts.snap b/tests/components/__snapshots__/refs.test.ts.snap index bfebc361..f7b60bf2 100644 --- a/tests/components/__snapshots__/refs.test.ts.snap +++ b/tests/components/__snapshots__/refs.test.ts.snap @@ -40,15 +40,14 @@ exports[`refs refs are properly bound in slots 2`] = ` let block1 = createBlock(\`
\`); let block2 = createBlock(\`\`); - function slot2(ctx, node, key) { - const refs = ctx.__owl__.refs + function slot2(ctx, node, key = \\"\\") { + const refs = ctx.__owl__.refs; let d2 = [ctx['doSomething'], ctx]; let d3 = (el) => refs[\`myButton\`] = el; return block2([d2, d3]); } return function template(ctx, node, key = \\"\\") { - const refs = ctx.__owl__.refs; let d1 = ctx['state'].val; const ctx1 = capture(ctx); let b3 = component(\`Dialog\`, {slots: {'footer': {__render: slot2, __ctx: ctx1}}}, key + \`__3\`, node, ctx); diff --git a/tests/components/__snapshots__/slots.test.ts.snap b/tests/components/__snapshots__/slots.test.ts.snap index 53175919..1fac21c3 100644 --- a/tests/components/__snapshots__/slots.test.ts.snap +++ b/tests/components/__snapshots__/slots.test.ts.snap @@ -8,7 +8,7 @@ exports[`slots can define a default content 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\`default content\`); } @@ -60,11 +60,11 @@ exports[`slots can define and call slots 2`] = ` let block2 = createBlock(\`header\`); let block3 = createBlock(\`footer\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return block2(); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { return block3(); } @@ -104,11 +104,11 @@ exports[`slots can define and call slots with params 2`] = ` let block2 = createBlock(\`header\`); let block3 = createBlock(\`footer\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return block2(); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { return block3(); } @@ -140,8 +140,8 @@ exports[`slots can render node with t-ref and Component in same slot 2`] = ` let block2 = createBlock(\`
\`); - function slot1(ctx, node, key) { - const refs = ctx.__owl__.refs + function slot1(ctx, node, key = \\"\\") { + const refs = ctx.__owl__.refs; let d1 = (el) => refs[\`div\`] = el; let b2 = block2([d1]); let b3 = component(\`Child\`, {}, key + \`__2\`, node, ctx); @@ -149,7 +149,6 @@ exports[`slots can render node with t-ref and Component in same slot 2`] = ` } return function template(ctx, node, key = \\"\\") { - const refs = ctx.__owl__.refs; return component(\`Child\`, {slots: {'default': {__render: slot1, __ctx: ctx}}}, key + \`__3\`, node, ctx); } }" @@ -185,7 +184,7 @@ exports[`slots can use component in default-content of t-slot 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return component(\`GrandChild\`, {}, key + \`__2\`, node, ctx); } @@ -226,7 +225,7 @@ exports[`slots can use t-call in default-content of t-slot 2`] = ` let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; const callTemplate_3 = getTemplate(\`__template__9\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return callTemplate_3.call(this, ctx, node, key + \`__2\`); } @@ -268,7 +267,7 @@ exports[`slots content is the default slot (variation) 2`] = ` let block1 = createBlock(\`sts rocks\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block1(); } @@ -302,7 +301,7 @@ exports[`slots content is the default slot 2`] = ` let block1 = createBlock(\`
\`); let block2 = createBlock(\`sts rocks\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -321,7 +320,7 @@ exports[`slots default content is not rendered if named slot is provided 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\`default content\`); } @@ -340,7 +339,7 @@ exports[`slots default content is not rendered if named slot is provided 2`] = ` let block1 = createBlock(\`
\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return text(\`hey\`); } @@ -360,7 +359,7 @@ exports[`slots default content is not rendered if slot is provided 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\`default content\`); } @@ -379,7 +378,7 @@ exports[`slots default content is not rendered if slot is provided 2`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`hey\`); } @@ -398,11 +397,11 @@ exports[`slots default slot next to named slot, with default content 1`] = ` let block1 = createBlock(\`
\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\` Default content \`); } - function defaultContent2(ctx, node, key) { + function defaultContent2(ctx, node, key = \\"\\") { return text(\` Default footer \`); } @@ -422,7 +421,7 @@ exports[`slots default slot next to named slot, with default content 2`] = ` let block1 = createBlock(\`
\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return text(\` Overridden footer \`); } @@ -452,7 +451,7 @@ exports[`slots default slot work with text nodes (variation) 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`sts rocks\`); } @@ -485,7 +484,7 @@ exports[`slots default slot work with text nodes 2`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`sts rocks\`); } @@ -524,13 +523,13 @@ exports[`slots dynamic t-slot call 2`] = ` let block4 = createBlock(\`content\`); let block5 = createBlock(\`

slot2

\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let b3 = block3(); let b4 = block4(); return multi([b3, b4]); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { return block5(); } @@ -550,7 +549,7 @@ exports[`slots dynamic t-slot call with default 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\` owl \`); } @@ -573,13 +572,13 @@ exports[`slots dynamic t-slot call with default 2`] = ` let block4 = createBlock(\`content\`); let block5 = createBlock(\`

slot2

\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let b3 = block3(); let b4 = block4(); return multi([b3, b4]); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { return block5(); } @@ -611,7 +610,7 @@ exports[`slots fun: two calls to the same slot 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`some text\`); } @@ -677,7 +676,7 @@ exports[`slots multiple roots are allowed in a default slot 2`] = ` let block3 = createBlock(\`sts\`); let block4 = createBlock(\`rocks\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3 = block3(); let b4 = block4(); return multi([b3, b4]); @@ -715,7 +714,7 @@ exports[`slots multiple roots are allowed in a named slot 2`] = ` let block3 = createBlock(\`sts\`); let block4 = createBlock(\`rocks\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let b3 = block3(); let b4 = block4(); return multi([b3, b4]); @@ -766,11 +765,11 @@ exports[`slots multiple slots containing components 3`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return component(\`C\`, {val: 1}, key + \`__3\`, node, ctx); } - function slot4(ctx, node, key) { + function slot4(ctx, node, key = \\"\\") { return component(\`C\`, {val: 2}, key + \`__5\`, node, ctx); } @@ -807,17 +806,17 @@ exports[`slots named slot inside slot 2`] = ` let block2 = createBlock(\`

A

\`); let block3 = createBlock(\`

B

\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let d1 = ctx['value']; return block2([d1]); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { const ctx4 = capture(ctx); return component(\`Child\`, {slots: {'brol': {__render: slot5, __ctx: ctx4}}}, key + \`__6\`, node, ctx); } - function slot5(ctx, node, key) { + function slot5(ctx, node, key = \\"\\") { let d2 = ctx['value']; return block3([d2]); } @@ -856,17 +855,17 @@ exports[`slots named slot inside slot, part 3 2`] = ` let block2 = createBlock(\`

A

\`); let block3 = createBlock(\`

B

\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let d1 = ctx['value']; return block2([d1]); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { const ctx4 = capture(ctx); return component(\`Child\`, {slots: {'brol': {__render: slot5, __ctx: ctx4}}}, key + \`__6\`, node, ctx); } - function slot5(ctx, node, key) { + function slot5(ctx, node, key = \\"\\") { let d2 = ctx['value']; return block3([d2]); } @@ -887,7 +886,7 @@ exports[`slots named slots can define a default content 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\`default content\`); } @@ -921,11 +920,11 @@ exports[`slots named slots inside slot, again 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { return text(\`default1\`); } - function defaultContent2(ctx, node, key) { + function defaultContent2(ctx, node, key = \\"\\") { return text(\`default2\`); } @@ -948,17 +947,17 @@ exports[`slots named slots inside slot, again 2`] = ` let block2 = createBlock(\`

A

\`); let block3 = createBlock(\`

B

\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let d1 = ctx['value']; return block2([d1]); } - function slot3(ctx, node, key) { + function slot3(ctx, node, key = \\"\\") { const ctx4 = capture(ctx); return component(\`Child\`, {slots: {'brol2': {__render: slot5, __ctx: ctx4}}}, key + \`__6\`, node, ctx); } - function slot5(ctx, node, key) { + function slot5(ctx, node, key = \\"\\") { let d2 = ctx['value']; return block3([d2]); } @@ -1023,11 +1022,11 @@ exports[`slots nested slots in same template 4`] = ` let block1 = createBlock(\`\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child2\`, {slots: {'default': {__render: slot2, __ctx: ctx}}}, key + \`__4\`, node, ctx); } - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return component(\`Child3\`, {}, key + \`__3\`, node, ctx); } @@ -1074,7 +1073,7 @@ exports[`slots nested slots: evaluation context and parented relationship 3`] = let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return callSlot(ctx, node, key, 'default', false, {}); } @@ -1090,7 +1089,7 @@ exports[`slots nested slots: evaluation context and parented relationship 4`] = let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Slot\`, {val: ctx['state'].val}, key + \`__2\`, node, ctx); } @@ -1148,7 +1147,7 @@ exports[`slots simple default slot 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`some text\`); } @@ -1179,7 +1178,7 @@ exports[`slots simple default slot with params 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let b2,b3; if (ctx['slotScope'].bool) { b2 = text(\`some text\`); @@ -1217,7 +1216,7 @@ exports[`slots simple default slot with params 4`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b2,b3; if (ctx['slotScope'].bool) { b2 = text(\`some text\`); @@ -1251,7 +1250,7 @@ exports[`slots simple default slot, variation 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`some text\`); } @@ -1299,7 +1298,7 @@ exports[`slots slot and (inline) t-call 3`] = ` let block1 = createBlock(\`
\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return callTemplate_4.call(this, ctx, node, key + \`__3\`); } @@ -1349,7 +1348,7 @@ exports[`slots slot and t-call 3`] = ` let block1 = createBlock(\`
\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return callTemplate_4.call(this, ctx, node, key + \`__3\`); } @@ -1384,7 +1383,7 @@ exports[`slots slot and t-esc 2`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text('toph'); } @@ -1433,7 +1432,7 @@ exports[`slots slot are properly rendered if inner props are changed 3`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`SomeComponent\`, {val: ctx['state'].val}, key + \`__2\`, node, ctx); } @@ -1469,15 +1468,15 @@ exports[`slots slot content is bound to caller (variation) 2`] = ` let block1 = createBlock(\`\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { + ctx = Object.create(ctx); + ctx[isBoundary] = 1 setContextValue(ctx, \\"var\\", 1); let d1 = [()=>this.inc(), ctx]; return block1([d1]); } return function template(ctx, node, key = \\"\\") { - ctx = Object.create(ctx); - ctx[isBoundary] = 1 const ctx1 = capture(ctx); return component(\`Child\`, {slots: {'default': {__render: slot2, __ctx: ctx1}}}, key + \`__3\`, node, ctx); } @@ -1507,7 +1506,7 @@ exports[`slots slot content is bound to caller 2`] = ` let block1 = createBlock(\`\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let d1 = [ctx['inc'], ctx]; return block1([d1]); } @@ -1550,7 +1549,7 @@ exports[`slots slot preserves properly parented relationship 3`] = ` let block1 = createBlock(\`
\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`GrandChild\`, {}, key + \`__2\`, node, ctx); } @@ -1606,7 +1605,7 @@ exports[`slots slot preserves properly parented relationship, even through t-cal let block1 = createBlock(\`
\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return callTemplate_4.call(this, ctx, node, key + \`__3\`); } @@ -1639,7 +1638,7 @@ exports[`slots slots and wrapper components 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(\`hey\`); } @@ -1657,7 +1656,9 @@ exports[`slots slots are properly bound to correct component 1`] = ` let block1 = createBlock(\`\`); - function defaultContent1(ctx, node, key) { + function defaultContent1(ctx, node, key = \\"\\") { + ctx = Object.create(ctx); + ctx[isBoundary] = 1 setContextValue(ctx, \\"var\\", 1); let d1 = [()=>this.increment(), ctx]; let d2 = ctx['state'].value; @@ -1665,8 +1666,6 @@ exports[`slots slots are properly bound to correct component 1`] = ` } return function template(ctx, node, key = \\"\\") { - ctx = Object.create(ctx); - ctx[isBoundary] = 1 return callSlot(ctx, node, key, 'default', false, {}, defaultContent1); } }" @@ -1708,7 +1707,7 @@ exports[`slots slots are rendered with proper context 2`] = ` let block1 = createBlock(\`
\`); let block2 = createBlock(\`\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let d2 = [ctx['doSomething'], ctx]; return block2([d2]); } @@ -1747,7 +1746,7 @@ exports[`slots slots are rendered with proper context, part 2 2`] = ` let block1 = createBlock(\`
\`); let block3 = createBlock(\`
  • \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let b5 = text(\`User \`); let b6 = text(ctx['user'].name); return multi([b5, b6]); @@ -1794,7 +1793,7 @@ exports[`slots slots are rendered with proper context, part 3 2`] = ` let block1 = createBlock(\`
    \`); let block3 = createBlock(\`
  • \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return text(ctx['userdescr']); } @@ -1841,7 +1840,7 @@ exports[`slots slots are rendered with proper context, part 4 2`] = ` let block1 = createBlock(\`
    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return text(ctx['userdescr']); } @@ -1879,7 +1878,7 @@ exports[`slots slots in slots, with vars 2`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return callSlot(ctx, node, key, 'default', false, {}); } @@ -1899,7 +1898,7 @@ exports[`slots slots in slots, with vars 3`] = ` let block1 = createBlock(\`
    \`); let block2 = createBlock(\`

    hey

    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let d1 = ctx['test']; return block2([d1]); } @@ -1939,7 +1938,7 @@ exports[`slots slots in t-foreach and re-rendering 2`] = ` let block1 = createBlock(\`
    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return text(ctx['n_index']); } @@ -1985,7 +1984,7 @@ exports[`slots slots in t-foreach in t-foreach 2`] = ` let block5 = createBlock(\`\`); let block7 = createBlock(\`
  • \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { let d2 = ctx['node1'].value; return block7([d2]); } @@ -2041,7 +2040,7 @@ exports[`slots slots in t-foreach with t-set and re-rendering 2`] = ` let block1 = createBlock(\`
    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return text(ctx['dummy']); } @@ -2087,7 +2086,7 @@ exports[`slots t-debug on a t-set-slot (defining a slot) 2`] = ` let block1 = createBlock(\`
    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { debugger; return text(\`abc\`); } @@ -2123,14 +2122,14 @@ exports[`slots t-set t-value in a slot 2`] = ` let block1 = createBlock(\`
    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { + ctx = Object.create(ctx); + ctx[isBoundary] = 1 setContextValue(ctx, \\"rainbow\\", 'dash'); return text(ctx['rainbow']); } return function template(ctx, node, key = \\"\\") { - ctx = Object.create(ctx); - ctx[isBoundary] = 1 const ctx1 = capture(ctx); let b3 = component(\`Dialog\`, {slots: {'default': {__render: slot2, __ctx: ctx1}}}, key + \`__3\`, node, ctx); return block1([], [b3]); @@ -2160,7 +2159,9 @@ exports[`slots t-slot in recursive templates 2`] = ` let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; const callTemplate_4 = getTemplate(\`_test_recursive_template\`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { + ctx = Object.create(ctx); + ctx[isBoundary] = 1 let b2 = text(ctx['name']); ctx = Object.create(ctx); const [k_block3, v_block3, l_block3, c_block3] = prepareList(ctx['items']); @@ -2190,8 +2191,6 @@ exports[`slots t-slot in recursive templates 2`] = ` } return function template(ctx, node, key = \\"\\") { - ctx = Object.create(ctx); - ctx[isBoundary] = 1 const ctx1 = capture(ctx); return component(\`Wrapper\`, {slots: {'default': {__render: slot2, __ctx: ctx1}}}, key + \`__5\`, node, ctx); } @@ -2250,11 +2249,11 @@ exports[`slots t-slot nested within another slot 4`] = ` let block1 = createBlock(\`\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Portal\`, {slots: {'default': {__render: slot2, __ctx: ctx}}}, key + \`__3\`, node, ctx); } - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return callSlot(ctx, node, key, 'default', false, {}); } @@ -2273,7 +2272,7 @@ exports[`slots t-slot nested within another slot 5`] = ` let block1 = createBlock(\`\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child3\`, {}, key + \`__2\`, node, ctx); } @@ -2304,7 +2303,7 @@ exports[`slots t-slot scope context 2`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let d1 = [ctx['onClick'], ctx]; let b2 = callSlot(ctx, node, key, 'default', false, {}); return block1([d1], [b2]); @@ -2324,7 +2323,7 @@ exports[`slots t-slot scope context 3`] = ` let block1 = createBlock(\`\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block1(); } @@ -2386,7 +2385,7 @@ exports[`slots t-slot within dynamic t-call 4`] = ` let block1 = createBlock(\`
    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { const template4 = (ctx['tcallTemplate']); return call(this, template4, ctx, node, key + \`__3\`); } @@ -2434,7 +2433,7 @@ exports[`slots template can just return a slot 3`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {value: ctx['state'].value}, key + \`__2\`, node, ctx); } diff --git a/tests/components/__snapshots__/t_set.test.ts.snap b/tests/components/__snapshots__/t_set.test.ts.snap index 9fc3837d..44402854 100644 --- a/tests/components/__snapshots__/t_set.test.ts.snap +++ b/tests/components/__snapshots__/t_set.test.ts.snap @@ -27,8 +27,11 @@ exports[`t-set slot setted value (with t-set) not accessible with t-esc 2`] = ` let block1 = createBlock(\`

    \`); - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { + ctx = Object.create(ctx); + ctx[isBoundary] = 1 setContextValue(ctx, \\"iter\\", 'inCall'); + return text(''); } return function template(ctx, node, key = \\"\\") { diff --git a/tests/misc/__snapshots__/memo.test.ts.snap b/tests/misc/__snapshots__/memo.test.ts.snap index 6dc1ca23..51a1cdf1 100644 --- a/tests/misc/__snapshots__/memo.test.ts.snap +++ b/tests/misc/__snapshots__/memo.test.ts.snap @@ -18,7 +18,7 @@ exports[`Memo if no prop change, prevent renderings from above 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b6 = text(ctx['state'].a); let b7 = text(ctx['state'].b); let b8 = text(ctx['state'].c); @@ -53,7 +53,7 @@ exports[`Memo if no props, prevent renderings from above 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot2(ctx, node, key) { + function slot2(ctx, node, key = \\"\\") { return component(\`Child\`, {value: ctx['state'].value}, key + \`__3\`, node, ctx); } @@ -71,7 +71,7 @@ exports[`Memo if no props, prevent renderings from above (work with simple html) let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text(ctx['state'].value); } diff --git a/tests/misc/__snapshots__/portal.test.ts.snap b/tests/misc/__snapshots__/portal.test.ts.snap index af0572f4..4642c4e5 100644 --- a/tests/misc/__snapshots__/portal.test.ts.snap +++ b/tests/misc/__snapshots__/portal.test.ts.snap @@ -21,7 +21,7 @@ exports[`Portal Portal composed with t-slot 2`] = ` let { text, createBlock, list, multi, html, toggler, component } = bdom; let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers; - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return callSlot(ctx, node, key, 'default', false, {}); } @@ -39,7 +39,7 @@ exports[`Portal Portal composed with t-slot 3`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child2\`, {customHandler: ctx['_handled']}, key + \`__2\`, node, ctx); } @@ -59,7 +59,7 @@ exports[`Portal basic use of portal 1`] = ` let block1 = createBlock(\`
    1
    \`); let block2 = createBlock(\`

    2

    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -93,7 +93,7 @@ exports[`Portal conditional use of Portal (with sub Component) 2`] = ` let block2 = createBlock(\`1\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {val: ctx['state'].val}, key + \`__2\`, node, ctx); } @@ -117,7 +117,7 @@ exports[`Portal conditional use of Portal 1`] = ` let block2 = createBlock(\`1\`); let block3 = createBlock(\`

    2

    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block3(); } @@ -155,7 +155,7 @@ exports[`Portal lifecycle hooks of portal sub component are properly called 2`] let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {val: ctx['state'].val}, key + \`__2\`, node, ctx); } @@ -178,7 +178,7 @@ exports[`Portal portal could have dynamically no content 1`] = ` let block1 = createBlock(\`
    \`); let block3 = createBlock(\`\`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3; if (ctx['state'].val) { let d1 = ctx['state'].val; @@ -217,7 +217,7 @@ exports[`Portal portal destroys on crash 2`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {error: ctx['state'].error}, key + \`__2\`, node, ctx); } @@ -251,7 +251,7 @@ exports[`Portal portal with child and props 2`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {val: ctx['state'].val}, key + \`__2\`, node, ctx); } @@ -272,7 +272,7 @@ exports[`Portal portal with dynamic body 1`] = ` let block3 = createBlock(\`\`); let block4 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3,b4; if (ctx['state'].val) { let d1 = ctx['state'].val; @@ -300,7 +300,7 @@ exports[`Portal portal with many children 1`] = ` let block3 = createBlock(\`
    1
    \`); let block4 = createBlock(\`

    2

    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3 = block3(); let b4 = block4(); return multi([b3, b4]); @@ -321,7 +321,7 @@ exports[`Portal portal with no content 1`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { let b3; if (false) { b3 = text('ABC'); @@ -344,7 +344,7 @@ exports[`Portal portal with only text as content 1`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return text('only text'); } @@ -364,7 +364,7 @@ exports[`Portal portal with target not in dom 1`] = ` let block1 = createBlock(\`
    \`); let block2 = createBlock(\`
    2
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -397,7 +397,7 @@ exports[`Portal portal's parent's env is not polluted 2`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {}, key + \`__2\`, node, ctx); } @@ -417,7 +417,7 @@ exports[`Portal with target in template (after portal) 1`] = ` let block1 = createBlock(\`
    1
    \`); let block2 = createBlock(\`

    2

    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -437,7 +437,7 @@ exports[`Portal with target in template (before portal) 1`] = ` let block1 = createBlock(\`
    1
    \`); let block2 = createBlock(\`

    2

    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -457,7 +457,7 @@ exports[`Portal: Props validation target is mandatory 1`] = ` let block1 = createBlock(\`
    \`); let block2 = createBlock(\`
    2
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -477,7 +477,7 @@ exports[`Portal: Props validation target is not list 1`] = ` let block1 = createBlock(\`
    \`); let block2 = createBlock(\`
    2
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return block2(); } @@ -511,7 +511,7 @@ exports[`Portal: UI/UX focus is kept across re-renders 2`] = ` let block1 = createBlock(\`
    \`); - function slot1(ctx, node, key) { + function slot1(ctx, node, key = \\"\\") { return component(\`Child\`, {val: ctx['state'].val}, key + \`__2\`, node, ctx); }