From 23e6e36da28308ced9eb2f24cc2196b11855a76e Mon Sep 17 00:00:00 2001 From: lvjiaxuan <11309921+lvjiaxuan@users.noreply.github.com> Date: Fri, 29 Sep 2023 05:21:46 +0000 Subject: [PATCH 1/2] feat: enhance `fnExpRE` --- .../__tests__/transforms/vOn.spec.ts | 129 ++++++++++++++++++ packages/compiler-core/src/transforms/vOn.ts | 2 +- 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts index 218281ba762..bc2cf9eae6c 100644 --- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts @@ -437,6 +437,135 @@ describe('compiler: transform v-on', () => { }) }) + test('should handle inline arrow function expression wrapped in parentheses', () => { + const { node } = parseWithVOn(`
`) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(foo => bar = foo)' + }) + }) + + test('should handle inline arrow function expression wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '((foo: any): any => bar = foo)' + }) + }) + + test('should handle inline function expression wrapped in parentheses', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(function (foo) { bar = foo })' + }) + }) + + test('should handle inline function expression wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(function (foo: any): any { bar = foo })' + }) + }) + + test('should handle inline async arrow function expression with parameters', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'async foo => await fetch(foo)' + }) + }) + + test('should handle inline async arrow function expression with parameters (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'async (foo: any): Promise => await fetch(foo)' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(async foo => await fetch(foo))' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(async (foo: any): Promise => await fetch(foo))' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: '(async function (foo) {\nawait fetch(foo)\nbar = foo\n})' + }) + }) + + test('should handle inline async arrow function expression with parameters wrapped in parentheses (with Typescript)', () => { + const { node } = parseWithVOn( + `
` + ) + const vnodeCall = node.codegenNode as VNodeCall + expect( + (vnodeCall.props as ObjectExpression).properties[0].value + ).toMatchObject({ + type: NodeTypes.SIMPLE_EXPRESSION, + content: + '(async function (foo: any): Promise {\nawait fetch(foo)\nbar = foo\n}})' + }) + }) + // TODO remove in 3.4 test('case conversion for vnode hooks', () => { const { node } = parseWithVOn(`
`) diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index 3deee202418..863ecf14597 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -17,7 +17,7 @@ import { hasScopeRef, isMemberExpression } from '../utils' import { TO_HANDLER_KEY } from '../runtimeHelpers' const fnExpRE = - /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/ + /(^[\s\(]*((async\s*)?([\w$_]+|\([^)]*?\))\s*(:[^=]+)?=>|(async\s+)?function(?:\s*[\w$_]*)\s*\([^)]*?\)\s*(:[^=]+)?{))[\s\S]+\)*/ export interface VOnDirectiveNode extends DirectiveNode { // v-on without arg is handled directly in ./transformElements.ts due to it affecting From edd183857071030eb808b62fcc68c0b340da687a Mon Sep 17 00:00:00 2001 From: lvjiaxuan <11309921+lvjiaxuan@users.noreply.github.com> Date: Fri, 29 Sep 2023 06:01:05 +0000 Subject: [PATCH 2/2] chore: update `fnExpRE` --- packages/compiler-core/src/transforms/vOn.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index 863ecf14597..2d341c80781 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -17,7 +17,7 @@ import { hasScopeRef, isMemberExpression } from '../utils' import { TO_HANDLER_KEY } from '../runtimeHelpers' const fnExpRE = - /(^[\s\(]*((async\s*)?([\w$_]+|\([^)]*?\))\s*(:[^=]+)?=>|(async\s+)?function(?:\s*[\w$_]*)\s*\([^)]*?\)\s*(:[^=]+)?{))[\s\S]+\)*/ + /(?:^[\s\(]*(?:(?:async\s*)?(?:[\w$_]+|\([^)]*?\))\s*(?::[^=]+)?=>|(?:async\s+)?function(?:\s+[\w$_]+)?\s*\([^)]*?\)\s*(?::[^=]+)?{))[\s\S]+\)*/ export interface VOnDirectiveNode extends DirectiveNode { // v-on without arg is handled directly in ./transformElements.ts due to it affecting