]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-vapor): support `expressionPlugins` for generate (#91)
authorzhiyuanzmj <32807958+zhiyuanzmj@users.noreply.github.com>
Sat, 13 Jan 2024 10:30:03 +0000 (18:30 +0800)
committerGitHub <noreply@github.com>
Sat, 13 Jan 2024 10:30:03 +0000 (18:30 +0800)
packages/compiler-vapor/__tests__/transforms/vOn.spec.ts
packages/compiler-vapor/src/compile.ts
packages/compiler-vapor/src/generate.ts

index 6fae1713fe18e35e5b2b5e2666cb71f2c5db504c..7705e1e1837f4681a6de235a11d5ac72c590ea90 100644 (file)
@@ -269,25 +269,22 @@ describe('v-on', () => {
     expect(code).contains('_on(n1, "click", $event => _ctx.foo($event))')
   })
 
-  test.fails(
-    'should NOT wrap as function if expression is already function expression (with Typescript)',
-    () => {
-      const { ir, code } = compileWithVOn(
-        `<div @click="(e: any): any => foo(e)"/>`,
-        { expressionPlugins: ['typescript'] },
-      )
-
-      expect(ir.operation).toMatchObject([
-        {
-          type: IRNodeTypes.SET_EVENT,
-          value: { content: '(e: any): any => foo(e)' },
-        },
-      ])
+  test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
+    const { ir, code } = compileWithVOn(
+      `<div @click="(e: any): any => foo(e)"/>`,
+      { expressionPlugins: ['typescript'] },
+    )
 
-      expect(code).matchSnapshot()
-      expect(code).contains('_on(n1, "click", e => _ctx.foo(e))')
-    },
-  )
+    expect(ir.operation).toMatchObject([
+      {
+        type: IRNodeTypes.SET_EVENT,
+        value: { content: '(e: any): any => foo(e)' },
+      },
+    ])
+
+    expect(code).matchSnapshot()
+    expect(code).contains('_on(n1, "click", (e: any): any => _ctx.foo(e))')
+  })
 
   test('should NOT wrap as function if expression is already function expression (with newlines)', () => {
     const { ir, code } = compileWithVOn(
index dd7aad5cf24a6a7f41762d4d44ccd3b1bd04e2f7..6d304ae200b341033720be378f5eb6a11a0fb372 100644 (file)
@@ -61,13 +61,16 @@ export function compile(
   if (!__BROWSER__ && options.isTS) {
     const { expressionPlugins } = options
     if (!expressionPlugins || !expressionPlugins.includes('typescript')) {
-      options.expressionPlugins = [...(expressionPlugins || []), 'typescript']
+      resolvedOptions.expressionPlugins = [
+        ...(expressionPlugins || []),
+        'typescript',
+      ]
     }
   }
 
   const ir = transform(
     ast,
-    extend({}, options, {
+    extend({}, resolvedOptions, {
       nodeTransforms: [
         ...nodeTransforms,
         ...(options.nodeTransforms || []), // user transforms
index 9d916146fe121ae83e8ff40e9e1112efe380a6bc..9b6543e1e25b418ae8c5fe99cb93270dd99fc107 100644 (file)
@@ -1,6 +1,6 @@
 import {
+  type CodegenOptions as BaseCodegenOptions,
   BindingTypes,
-  type CodegenOptions,
   type CodegenResult,
   NewlineType,
   type Position,
@@ -33,6 +33,11 @@ import {
 import { SourceMapGenerator } from 'source-map-js'
 import { camelize, isGloballyAllowed, isString, makeMap } from '@vue/shared'
 import type { Identifier } from '@babel/types'
+import type { ParserPlugin } from '@babel/parser'
+
+interface CodegenOptions extends BaseCodegenOptions {
+  expressionPlugins?: ParserPlugin[]
+}
 
 // TODO: share this with compiler-core
 const fnExpRE =
@@ -94,6 +99,7 @@ function createCodegenContext(
     inSSR = false,
     inline = false,
     bindingMetadata = {},
+    expressionPlugins = [],
   }: CodegenOptions,
 ) {
   const { helpers, vaporHelpers } = ir
@@ -111,6 +117,7 @@ function createCodegenContext(
     isTS,
     inSSR,
     bindingMetadata,
+    expressionPlugins,
     inline,
 
     source: ir.source,
@@ -513,7 +520,7 @@ function genSetEvent(oper: SetEventIRNode, context: CodegenContext) {
 
       ;(keys.length ? pushWithKeys : pushNoop)(() =>
         (nonKeys.length ? pushWithModifiers : pushNoop)(() => {
-          genEventHandler()
+          genEventHandler(context)
         }),
       )
     },
@@ -522,13 +529,10 @@ function genSetEvent(oper: SetEventIRNode, context: CodegenContext) {
       (() => push(`{ ${options.map((v) => `${v}: true`).join(', ')} }`)),
   )
 
-  function genEventHandler() {
+  function genEventHandler(context: CodegenContext) {
     const exp = oper.value
     if (exp && exp.content.trim()) {
-      const isMemberExp = isMemberExpression(exp.content, {
-        // TODO: expression plugins
-        expressionPlugins: [],
-      })
+      const isMemberExp = isMemberExpression(exp.content, context)
       const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content))
       const hasMultipleStatements = exp.content.includes(`;`)