]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): handle inline comments with undefined bindings (#11217)
authorTycho <jh.leong@outlook.com>
Fri, 28 Jun 2024 01:48:23 +0000 (09:48 +0800)
committerGitHub <noreply@github.com>
Fri, 28 Jun 2024 01:48:23 +0000 (09:48 +0800)
close #11216

packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
packages/compiler-core/src/babelUtils.ts
packages/compiler-core/src/transforms/transformExpression.ts
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/script/definePropsDestructure.ts
packages/global.d.ts

index ffd93d791ca7faed67a380f770c38cc8894548c0..7ca831f0ce8da29b431af861cf6383813af00ff8 100644 (file)
@@ -384,6 +384,17 @@ describe('compiler: expression transform', () => {
     )
   })
 
+  test('should not error', () => {
+    const onError = vi.fn()
+    parseWithExpressionTransform(
+      `<p :id="undefined /* force override the id */"/>`,
+      {
+        onError,
+      },
+    )
+    expect(onError).not.toHaveBeenCalled()
+  })
+
   test('should prefix in assignment', () => {
     const node = parseWithExpressionTransform(
       `{{ x = 1 }}`,
index 7482494e17a614d9bbea742c0cffcbd715c34cd1..67997798864cb7ce1f8eaaaaaa677230454f5691 100644 (file)
@@ -17,7 +17,7 @@ export function walkIdentifiers(
   root: Node,
   onIdentifier: (
     node: Identifier,
-    parent: Node,
+    parent: Node | null,
     parentStack: Node[],
     isReference: boolean,
     isLocal: boolean,
@@ -36,7 +36,7 @@ export function walkIdentifiers(
       : root
 
   walk(root, {
-    enter(node: Node & { scopeIds?: Set<string> }, parent: Node | undefined) {
+    enter(node: Node & { scopeIds?: Set<string> }, parent: Node | null) {
       parent && parentStack.push(parent)
       if (
         parent &&
@@ -47,9 +47,9 @@ export function walkIdentifiers(
       }
       if (node.type === 'Identifier') {
         const isLocal = !!knownIds[node.name]
-        const isRefed = isReferencedIdentifier(node, parent!, parentStack)
+        const isRefed = isReferencedIdentifier(node, parent, parentStack)
         if (includeAll || (isRefed && !isLocal)) {
-          onIdentifier(node, parent!, parentStack, isRefed, isLocal)
+          onIdentifier(node, parent, parentStack, isRefed, isLocal)
         }
       } else if (
         node.type === 'ObjectProperty' &&
@@ -79,7 +79,7 @@ export function walkIdentifiers(
         }
       }
     },
-    leave(node: Node & { scopeIds?: Set<string> }, parent: Node | undefined) {
+    leave(node: Node & { scopeIds?: Set<string> }, parent: Node | null) {
       parent && parentStack.pop()
       if (node !== rootExp && node.scopeIds) {
         for (const id of node.scopeIds) {
index 35aa9a373a4298f5a5f4bbd9a5e6b396b3c3c271..de450491e7ce290315545ff3779afd5a279323c0 100644 (file)
@@ -116,7 +116,11 @@ export function processExpression(
   }
 
   const { inline, bindingMetadata } = context
-  const rewriteIdentifier = (raw: string, parent?: Node, id?: Identifier) => {
+  const rewriteIdentifier = (
+    raw: string,
+    parent?: Node | null,
+    id?: Identifier,
+  ) => {
     const type = hasOwn(bindingMetadata, raw) && bindingMetadata[raw]
     if (inline) {
       // x = y
@@ -313,9 +317,10 @@ export function processExpression(
         // local scope variable (a v-for alias, or a v-slot prop)
         if (
           !(needPrefix && isLocal) &&
-          parent.type !== 'CallExpression' &&
-          parent.type !== 'NewExpression' &&
-          parent.type !== 'MemberExpression'
+          (!parent ||
+            (parent.type !== 'CallExpression' &&
+              parent.type !== 'NewExpression' &&
+              parent.type !== 'MemberExpression'))
         ) {
           ;(node as QualifiedId).isConstant = true
         }
index 8a0aaeaf71717d89c0b55868fd6061a3f69f65e5..2fa2241a7deabfbe4af702d111bc820375637325 100644 (file)
@@ -616,7 +616,7 @@ export function compileScript(
     ) {
       const scope: Statement[][] = [scriptSetupAst.body]
       walk(node, {
-        enter(child: Node, parent: Node | undefined) {
+        enter(child: Node, parent: Node | null) {
           if (isFunctionType(child)) {
             this.skip()
           }
index e4a59aca7d55d9c096497f5a08afbd6929e93f3b..dd54ab85ba94c8b55ae008ac71839ecec849bc35 100644 (file)
@@ -239,7 +239,7 @@ export function transformDestructuredProps(
   const ast = ctx.scriptSetupAst!
   walkScope(ast, true)
   walk(ast, {
-    enter(node: Node, parent?: Node) {
+    enter(node: Node, parent: Node | null) {
       parent && parentStack.push(parent)
 
       // skip type nodes
@@ -294,7 +294,7 @@ export function transformDestructuredProps(
         }
       }
     },
-    leave(node: Node, parent?: Node) {
+    leave(node: Node, parent: Node | null) {
       parent && parentStack.pop()
       if (
         (node.type === 'BlockStatement' && !isFunctionType(parent!)) ||
index 38320b81e0467ceaa82e70e04917fbb13887bd94..1bae0b929fb4beacc79330a0660efc7cd08a1de3 100644 (file)
@@ -38,8 +38,8 @@ declare module 'estree-walker' {
   export function walk<T>(
     root: T,
     options: {
-      enter?: (node: T, parent: T | undefined) => any
-      leave?: (node: T, parent: T | undefined) => any
+      enter?: (node: T, parent: T | null) => any
+      leave?: (node: T, parent: T | null) => any
       exit?: (node: T) => any
     } & ThisType<{ skip: () => void }>,
   )