diff --git a/plugins/converter.test.ts b/plugins/converter.test.ts index 85f54cd2..82fe3c9f 100644 --- a/plugins/converter.test.ts +++ b/plugins/converter.test.ts @@ -1,4 +1,4 @@ -import { expect, test, describe, beforeAll, beforeEach } from 'vitest'; +import { expect, test, describe, beforeAll, beforeEach, afterEach } from 'vitest'; import { preprocess } from '@glimmer/syntax'; import { ComplexJSType, convert } from './converter'; @@ -463,17 +463,35 @@ describe.each([ }); }); describe('let condition', () => { + const mathRandom = Math.random; + beforeEach(() => { + Math.random = () => 0.001; + }); + afterEach(() => { + Math.random = mathRandom; + }); test('it works', () => { expect( $t( `{{#let foo "name" as |bar k|}}p{{bar}}{{k}}{{/let}}`, ), ).toEqual( - `$:...(() => {let bar = $:() => $:foo;let k = "name";return [$_text("p"), ${ - flags.IS_GLIMMER_COMPAT_MODE ? '() => bar' : 'bar' - }, ${flags.IS_GLIMMER_COMPAT_MODE ? '() => k' : 'k'}]})()`, + `$:...(() => {let self = this;let Let_bar_6c3gez6 = $:() => $:foo;let Let_k_6c3gez6 = "name";return [$_text("p"), ${ + flags.IS_GLIMMER_COMPAT_MODE ? '() => Let_bar_6c3gez6' : 'Let_bar_6c3gez6' + }, ${flags.IS_GLIMMER_COMPAT_MODE ? '() => Let_k_6c3gez6' : 'Let_k_6c3gez6'}]})()`, ); }); + test('it not override arg assign case', () => { + const result = $t( + `{{#let foo "name" as |bar k|}}
{{/let}}`, + ); + if (flags.IS_GLIMMER_COMPAT_MODE) { + expect(result).toEqual(`$:...(() => {let self = this;let Let_bar_6c3gez6 = $:() => $:foo;let Let_k_6c3gez6 = "name";return [$_c(Div,$_args({bar: () => Let_bar_6c3gez6},{},[[],[['bar', () => $:$__if(Let_bar_6c3gez6,Let_bar_6c3gez6)]],[]]), this)]})()`); + } else { + expect(result).toEqual(`$:...(() => {let self = this;let Let_bar_6c3gez6 = $:() => $:foo;let Let_k_6c3gez6 = "name";return [$_c(Div,{bar: Let_bar_6c3gez6, "$:[$PROPS_SYMBOL]": [[],[['bar', () => $:$__if(Let_bar_6c3gez6,Let_bar_6c3gez6)]],[]]}, this)]})()`); + } + + }) }); describe('each condition', () => { test('it adds unstable child wrapper for simple multi-nodes', () => { diff --git a/plugins/converter.ts b/plugins/converter.ts index f2ee2598..4b87444a 100644 --- a/plugins/converter.ts +++ b/plugins/converter.ts @@ -264,12 +264,17 @@ export function convert(seenNodes: Set, flags: Flags) { key: keyValue, } as HBSControlExpression; } else if (name === 'let') { + const varScopeName = Math.random().toString(36).substring(7); + const namesToReplace: Record = {}; const vars = node.params.map((p, index) => { let isSubExpression = p.type === 'SubExpression'; let isString = p.type === 'StringLiteral'; let isBoolean = p.type === 'BooleanLiteral'; let isNull = p.type === 'NullLiteral'; let isUndefined = p.type === 'UndefinedLiteral'; + let originalName = node.program.blockParams[index]; + let newName = `Let_${originalName}_${varScopeName}`; + namesToReplace[originalName] = `${newName}`; if ( isSubExpression || isString || @@ -277,24 +282,39 @@ export function convert(seenNodes: Set, flags: Flags) { isNull || isUndefined ) { - return `let ${node.program.blockParams[index]} = ${ToJSType( - p, - false, - )};`; + return `let ${newName} = ${ToJSType(p, false)};`; } else { - return `let ${node.program.blockParams[index]} = $:() => ${ToJSType( - p, - )};`; + return `let ${newName} = $:() => ${ToJSType(p)};`; } }); // note, at the moment nested let's works fine if no name overlap, // looks like fix for other case should be on babel level; - const result = `$:...(() => {${vars.join( - '', - )}return [${serializeChildren( - children as unknown as [string | HBSNode | HBSControlExpression], - 'this', // @todo - fix possible context floating here - )}]})()`; + // @todo - likely should be a babel work + function fixChildScopes(str: string) { + // console.log('fixChildScopes', str, JSON.stringify(namesToReplace)); + Object.keys(namesToReplace).forEach((key) => { + /* + allow: {{name}} {{foo name}} name.bar + don't allow: + name: + name= + foo.name + 'name' + "name" + */ + const re = new RegExp(`(? {let self = this;${vars + .join('') + .split('this.') + .join('self.')}return [${fixChildScopes( + serializeChildren( + children as unknown as [string | HBSNode | HBSControlExpression], + 'this', // @todo - fix possible context floating here + ) )}]})()`; return result; }