From ae60a91cc23424493071ad9088782763eb1e8ff7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 4 Jan 2024 15:57:54 +0800 Subject: [PATCH] fix(compiler-sfc): fix sfc template unref rewrite for class instantiation close #6483 close #6491 --- packages/compiler-core/src/babelUtils.ts | 13 ++++++++++++ .../src/transforms/transformExpression.ts | 10 ++++++++-- .../__snapshots__/compileScript.spec.ts.snap | 20 +++++++++++++++++++ .../__tests__/compileScript.spec.ts | 18 +++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index e0e0ef2222b..0a7f48af902 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -146,6 +146,19 @@ export function isInDestructureAssignment( return false } +export function isInNewExpression(parentStack: Node[]): boolean { + let i = parentStack.length + while (i--) { + const p = parentStack[i] + if (p.type === 'NewExpression') { + return true + } else if (p.type !== 'MemberExpression') { + break + } + } + return false +} + export function walkFunctionParams( node: Function, onIdent: (id: Identifier) => void, diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index 093fb4447ff..c7cd1b63d56 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -19,6 +19,7 @@ import { } from '../ast' import { isInDestructureAssignment, + isInNewExpression, isStaticProperty, isStaticPropertyKey, walkIdentifiers, @@ -131,6 +132,11 @@ export function processExpression( // ({ x } = y) const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack) + const isNewExpression = parent && isInNewExpression(parentStack) + const wrapWithUnref = (raw: string) => { + const wrapped = `${context.helperString(UNREF)}(${raw})` + return isNewExpression ? `(${wrapped})` : wrapped + } if ( isConst(type) || @@ -147,7 +153,7 @@ export function processExpression( // that assumes the value to be a ref for more efficiency return isAssignmentLVal || isUpdateArg || isDestructureAssignment ? `${raw}.value` - : `${context.helperString(UNREF)}(${raw})` + : wrapWithUnref(raw) } else if (type === BindingTypes.SETUP_LET) { if (isAssignmentLVal) { // let binding. @@ -190,7 +196,7 @@ export function processExpression( // for now return raw } else { - return `${context.helperString(UNREF)}(${raw})` + return wrapWithUnref(raw) } } else if (type === BindingTypes.PROPS) { // use __props which is generated by compileScript so in ts mode diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap index d63e6ec4d40..6efe6fb92af 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap @@ -1028,6 +1028,26 @@ return (_ctx, _cache) => { }" `; +exports[`SFC compile + + `, + { inlineTemplate: true }, + ) + expect(content).toMatch(`new (_unref(Foo))()`) + expect(content).toMatch(`new (_unref(Foo)).Bar()`) + assertCode(content) + }) }) describe('with TypeScript', () => {