From 572e3eedb2cb25af8930f724b2cadf98a16dad1d Mon Sep 17 00:00:00 2001 From: tuchg Date: Fri, 28 Oct 2022 21:11:12 +0800 Subject: [PATCH] fix(reactivity-transform): more edge cases of $$ scenario --- .../reactivityTransform.spec.ts.snap | 26 ++++--- .../__tests__/reactivityTransform.spec.ts | 43 ++++++------ .../src/reactivityTransform.ts | 68 ++++++++++++------- 3 files changed, 82 insertions(+), 55 deletions(-) diff --git a/packages/reactivity-transform/__tests__/__snapshots__/reactivityTransform.spec.ts.snap b/packages/reactivity-transform/__tests__/__snapshots__/reactivityTransform.spec.ts.snap index 7f7313d5da3..95e2466580b 100644 --- a/packages/reactivity-transform/__tests__/__snapshots__/reactivityTransform.spec.ts.snap +++ b/packages/reactivity-transform/__tests__/__snapshots__/reactivityTransform.spec.ts.snap @@ -27,17 +27,21 @@ exports[`$$ 1`] = ` exports[`$$ with some edge cases 1`] = ` "import { ref as _ref } from 'vue' - let a = _ref(1), e = _ref() - () - ;(count++,count) - ((count++,count)) - count = (count++,count) - count = ()=>(count++,count) - const af=()=>((count++,count)) - let c = _ref(a.value, (count++,count)) - let r1 = (count++,count) - let r2 = _ref(af((count++,count))) - let r3 = { a:(count++,count) } + a + console.log(a) + ;(a,b) + ;(a,b) + count = (a++,b) + count = ()=>(a++,b) + let r1 = _ref(a, (a++,b)) + let r2 = { a:(a++,b),b:a } + switch(c){ + case d: + a + ;(h,f) + break + } + ((count++,count,(count,a))) " `; diff --git a/packages/reactivity-transform/__tests__/reactivityTransform.spec.ts b/packages/reactivity-transform/__tests__/reactivityTransform.spec.ts index 7ac93596507..a113fb5a4c7 100644 --- a/packages/reactivity-transform/__tests__/reactivityTransform.spec.ts +++ b/packages/reactivity-transform/__tests__/reactivityTransform.spec.ts @@ -307,26 +307,31 @@ test('$$', () => { test('$$ with some edge cases',()=>{ const { code } = transform(` - let a = $ref(1), e = $ref() - $$() - $$(count++,count) - ($$(count++,count)) - count = $$(count++,count) - count = ()=>$$(count++,count) - const af=()=>($$(count++,count)) - let c = $ref(a, $$(count++,count)) - let r1 = $$(count++,count) - let r2 = $ref(af($$(count++,count))) - let r3 = { a:$$(count++,count) } + $$(a) + console.log($$($$(a))) + $$(a,b) + $$($$((a,b))) + count = $$(a++,b) + count = ()=>$$(a++,b) + let r1 = $ref(a, $$(a++,b)) + let r2 = { a:$$(a++,b),b:$$(a) } + switch(c){ + case d: + $$(a) + $$($$(h,f)) + break + } + ($$(count++,$$(count),$$(count,a))) `) - expect(code).toMatch(`;(count++,count)`) - expect(code).toMatch(`((count++,count))`) - expect(code).toMatch(`count = (count++,count)`) - expect(code).toMatch(`()=>(count++,count)`) - expect(code).toMatch(`()=>((count++,count))`) - expect(code).toMatch(`let r1 = (count++,count)`) - expect(code).toMatch(`let r2 = _ref(af((count++,count)))`) - expect(code).toMatch(`let r3 = { a:(count++,count) }`) + expect(code).toMatch(`((count++,count,(count,a)))`) + expect(code).toMatch(`;(a,b)`) + expect(code).toMatch(`log(a)`) + expect(code).toMatch(`count = (a++,b)`) + expect(code).toMatch(`()=>(a++,b)`) + expect(code).toMatch(`_ref(a, (a++,b))`) + expect(code).toMatch(`{ a:(a++,b),b:a }`) + expect(code).toMatch(`switch(c)`) + expect(code).toMatch(`;(h,f)`) assertCode(code) }) diff --git a/packages/reactivity-transform/src/reactivityTransform.ts b/packages/reactivity-transform/src/reactivityTransform.ts index 04c6dbb4469..0762c0a537a 100644 --- a/packages/reactivity-transform/src/reactivityTransform.ts +++ b/packages/reactivity-transform/src/reactivityTransform.ts @@ -555,35 +555,53 @@ export function transformAST( */ function unwrapMacro(node: CallExpression) { const argsLength = node.arguments.length - s.remove(node.callee.start! + offset, node.callee.end! + offset) - if (!argsLength) { + const bracketStart = node.callee.end! + offset + + s.remove(node.callee.start! + offset, bracketStart) + + if (argsLength === 1) { + const bracketEnd = node.arguments[argsLength - 1].end! + offset + + // remove brackets of macros + s.remove(bracketStart, bracketStart + 1) + s.remove(bracketEnd, bracketEnd + 1) + + // avoid traversal of like `$$(a)` + if(node.arguments[0].type!=="CallExpression"){ + return; + } + } + + // avoid invalid traversal for $ + if (!escapeScope|| node.extra) { return - } else if (argsLength === 1) { - // remove brackets of macro - s.remove(node.callee.end! + offset, node.arguments[0].start! + offset) - s.remove(node.arguments[argsLength - 1].end! + offset, node.end! + offset) - } else { - // handle some edge cases for macro $$ - // resolve nested - let i = parentStack.length - 1 - while (i >= 0) { - const curParent = parentStack[i--] - // see @__tests__:$$ with some edge cases - if ( - curParent.type === 'VariableDeclarator' || - curParent.type === 'AssignmentExpression' || - (curParent.type === 'ExpressionStatement' && - (curParent.expression.extra || - (curParent.expression.type === 'CallExpression' && - curParent.expression.arguments.includes(node)))) - ) { - return - } + } + + // fix some edge cases for macro $$, eg. $$(a,b) + // resolve nested + let i = parentStack.length - 1 + while (i >= 0) { + const curParent = parentStack[i--] + if ( + curParent.type === 'ExpressionStatement' && + isIsolateExpression(curParent.expression, node) + ) { + // split the unwrapped code `()()` to `();()` + s.appendLeft(node.callee.start! + offset, ';') + return } - s.appendLeft(node.callee.start! + offset, ';') } } + function isIsolateExpression(expression: Expression, node: CallExpression) { + return ( + expression.type === 'CallExpression' && + expression.callee.type === 'Identifier' && + expression.callee.name === escapeSymbol && + !expression.arguments.includes(node) + ) + } + // check root scope first walkScope(ast, true) ;(walk as any)(ast, { @@ -657,8 +675,8 @@ export function transformAST( } if (callee === escapeSymbol) { - unwrapMacro(node) escapeScope = node + unwrapMacro(node) } // TODO remove when out of experimental