]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): throw error when import macro as alias (#11041)
authorKevin Deng 三咲智子 <sxzz@sxzz.moe>
Fri, 31 May 2024 09:08:54 +0000 (17:08 +0800)
committerGitHub <noreply@github.com>
Fri, 31 May 2024 09:08:54 +0000 (17:08 +0800)
packages/compiler-sfc/src/compileScript.ts

index 31bee3af74df66f4db657a222c5b983f5def2daa..8a0aaeaf71717d89c0b55868fd6061a3f69f65e5 100644 (file)
@@ -49,7 +49,7 @@ import {
 } from './script/defineEmits'
 import { DEFINE_EXPOSE, processDefineExpose } from './script/defineExpose'
 import { DEFINE_OPTIONS, processDefineOptions } from './script/defineOptions'
-import { processDefineSlots } from './script/defineSlots'
+import { DEFINE_SLOTS, processDefineSlots } from './script/defineSlots'
 import { DEFINE_MODEL, processDefineModel } from './script/defineModel'
 import { getImportedName, isCallOf, isLiteralNode } from './script/utils'
 import { analyzeScriptBindings } from './script/analyzeScriptBindings'
@@ -135,6 +135,16 @@ export interface ImportBinding {
   isUsedInTemplate: boolean
 }
 
+const MACROS = [
+  DEFINE_PROPS,
+  DEFINE_EMITS,
+  DEFINE_EXPOSE,
+  DEFINE_OPTIONS,
+  DEFINE_SLOTS,
+  DEFINE_MODEL,
+  WITH_DEFAULTS,
+]
+
 /**
  * Compile `<script setup>`
  * It requires the whole SFC descriptor because we need to handle and merge
@@ -317,15 +327,18 @@ export function compileScript(
         const imported = getImportedName(specifier)
         const source = node.source.value
         const existing = ctx.userImports[local]
-        if (
-          source === 'vue' &&
-          (imported === DEFINE_PROPS ||
-            imported === DEFINE_EMITS ||
-            imported === DEFINE_EXPOSE)
-        ) {
-          warnOnce(
-            `\`${imported}\` is a compiler macro and no longer needs to be imported.`,
-          )
+        if (source === 'vue' && MACROS.includes(imported)) {
+          if (local === imported) {
+            warnOnce(
+              `\`${imported}\` is a compiler macro and no longer needs to be imported.`,
+            )
+          } else {
+            ctx.error(
+              `\`${imported}\` is a compiler macro and cannot be aliased to ` +
+                `a different name.`,
+              specifier,
+            )
+          }
           removeSpecifier(i)
         } else if (existing) {
           if (existing.source === source && existing.imported === imported) {
@@ -1054,13 +1067,16 @@ function walkDeclaration(
     // export const foo = ...
     for (const { id, init: _init } of node.declarations) {
       const init = _init && unwrapTSNode(_init)
-      const isDefineCall = !!(
+      const isConstMacroCall =
         isConst &&
         isCallOf(
           init,
-          c => c === DEFINE_PROPS || c === DEFINE_EMITS || c === WITH_DEFAULTS,
+          c =>
+            c === DEFINE_PROPS ||
+            c === DEFINE_EMITS ||
+            c === WITH_DEFAULTS ||
+            c === DEFINE_SLOTS,
         )
-      )
       if (id.type === 'Identifier') {
         let bindingType
         const userReactiveBinding = userImportAliases['reactive']
@@ -1077,7 +1093,7 @@ function walkDeclaration(
         } else if (
           // if a declaration is a const literal, we can mark it so that
           // the generated render fn code doesn't need to unref() it
-          isDefineCall ||
+          isConstMacroCall ||
           (isConst && canNeverBeRef(init!, userReactiveBinding))
         ) {
           bindingType = isCallOf(init, DEFINE_PROPS)
@@ -1109,9 +1125,9 @@ function walkDeclaration(
           continue
         }
         if (id.type === 'ObjectPattern') {
-          walkObjectPattern(id, bindings, isConst, isDefineCall)
+          walkObjectPattern(id, bindings, isConst, isConstMacroCall)
         } else if (id.type === 'ArrayPattern') {
-          walkArrayPattern(id, bindings, isConst, isDefineCall)
+          walkArrayPattern(id, bindings, isConst, isConstMacroCall)
         }
       }
     }