Procházet zdrojové kódy

fix(compiler-core): handle inline comments with undefined bindings (#11217)

close #11216
Tycho před 1 rokem
rodič
revize
746352a14d

+ 11 - 0
packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts

@@ -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 }}`,

+ 5 - 5
packages/compiler-core/src/babelUtils.ts

@@ -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) {

+ 9 - 4
packages/compiler-core/src/transforms/transformExpression.ts

@@ -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
         }

+ 1 - 1
packages/compiler-sfc/src/compileScript.ts

@@ -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()
           }

+ 2 - 2
packages/compiler-sfc/src/script/definePropsDestructure.ts

@@ -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!)) ||

+ 2 - 2
packages/global.d.ts

@@ -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 }>,
   )