From 583b6259870211c32efee0bb4a60b342799d80f7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 21 May 2022 00:09:15 +0800 Subject: [PATCH] fix(compiler-sfc): fix usage detection for types in v-for/v-slot expressions fix #5959 --- .../__snapshots__/compileScript.spec.ts.snap | 2 +- .../__tests__/compileScript.spec.ts | 4 +++- packages/compiler-sfc/src/compileScript.ts | 20 +++++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap index bef06904a50..e8026dc129c 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap @@ -722,7 +722,7 @@ return { props, a, emit } exports[`SFC compile @@ -454,6 +454,8 @@ defineExpose({ foo: 123 }) {{ a as Foo }} {{ b() }} {{ Baz }} + {{ data }} +
`) expect(content).toMatch(`return { a, b, Baz }`) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 74c89e88d47..ca82dc909bd 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -65,7 +65,7 @@ const WITH_DEFAULTS = 'withDefaults' const DEFAULT_VAR = `__default__` const isBuiltInDir = makeMap( - `once,memo,if,else,else-if,slot,text,html,on,bind,model,show,cloak,is` + `once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is` ) export interface SFCScriptCompileOptions { @@ -2103,7 +2103,8 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { } if (prop.exp) { code += `,${processExp( - (prop.exp as SimpleExpressionNode).content + (prop.exp as SimpleExpressionNode).content, + prop.name )}` } } @@ -2122,8 +2123,19 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { return code } -function processExp(exp: string) { - if (/ as \w|<.*>/.test(exp)) { +const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/ + +function processExp(exp: string, dir?: string): string { + if (/ as\s+\w|<.*>|:/.test(exp)) { + if (dir === 'slot') { + exp = `(${exp})=>{}` + } else if (dir === 'for') { + const inMatch = exp.match(forAliasRE) + if (inMatch) { + const [, LHS, RHS] = inMatch + return processExp(`(${LHS})=>{}`) + processExp(RHS) + } + } let ret = '' // has potential type cast or generic arguments that uses types const ast = parseExpression(exp, { plugins: ['typescript'] })