]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: reuse check logic
authordaiwei <daiwei521@126.com>
Thu, 23 Jan 2025 00:59:20 +0000 (08:59 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 23 Jan 2025 00:59:20 +0000 (08:59 +0800)
packages/compiler-core/src/index.ts
packages/compiler-core/src/transforms/vSkip.ts
packages/compiler-ssr/src/index.ts
packages/compiler-ssr/src/transforms/ssrVSkip.ts

index 29e5f681300aadc918134985832e0c55ff31f925..0ad4f070ebb49a1a8c19dfeb0f0e4725f6d65010 100644 (file)
@@ -48,6 +48,7 @@ export { transformBind } from './transforms/vBind'
 export { noopDirectiveTransform } from './transforms/noopDirectiveTransform'
 export { processIf } from './transforms/vIf'
 export { processFor, createForLoopParams } from './transforms/vFor'
+export { processSkip } from './transforms/vSkip'
 export {
   transformExpression,
   processExpression,
index 2e5d7a42f0db646dcb31f422c444e597837f4cb7..91a44480f78919616c10012931e7fb16ee1fec35 100644 (file)
@@ -1,15 +1,19 @@
 import {
+  type DirectiveNode,
+  type ElementNode,
   ElementTypes,
   type IfBranchNode,
   NodeTypes,
   type SimpleExpressionNode,
   type SlotsExpression,
+  type SourceLocation,
   type TemplateChildNode,
   createConditionalExpression,
   createSimpleExpression,
 } from '../ast'
 import {
   type NodeTransform,
+  type TransformContext,
   createStructuralDirectiveTransform,
 } from '../transform'
 import {
@@ -27,82 +31,91 @@ import { validateBrowserExpression } from '../validateExpression'
 export const transformSkip: NodeTransform = createStructuralDirectiveTransform(
   'skip',
   (node, dir, context) => {
-    const loc = dir.exp ? dir.exp.loc : node.loc
-    if (isTemplateNode(node) || isSlotOutlet(node)) {
-      context.onError(createCompilerError(ErrorCodes.X_V_SKIP_ON_TEMPLATE, loc))
-      return
-    }
-
-    if (findDir(node, 'for')) {
-      context.onWarn(createCompilerError(ErrorCodes.X_V_SKIP_WITH_V_FOR, loc))
-    }
-
-    if (!dir.exp || !(dir.exp as SimpleExpressionNode).content.trim()) {
-      context.onError(
-        createCompilerError(ErrorCodes.X_V_SKIP_NO_EXPRESSION, loc),
-      )
-      dir.exp = createSimpleExpression(`true`, false, loc)
-    }
-
-    if (!__BROWSER__ && context.prefixIdentifiers && dir.exp) {
-      dir.exp = processExpression(dir.exp as SimpleExpressionNode, context)
-    }
-
-    if (__DEV__ && __BROWSER__ && dir.exp) {
-      validateBrowserExpression(dir.exp as SimpleExpressionNode, context)
-    }
-
-    return () => {
-      let children: TemplateChildNode[] = []
-      // for components, extract default slot without props
-      // if not found, throw an error
-      if (node.tagType === ElementTypes.COMPONENT) {
-        const codegenNode = node.codegenNode!
-        if (codegenNode.type === NodeTypes.VNODE_CALL) {
-          const genChildren = codegenNode.children! as SlotsExpression
-          if (genChildren.type === NodeTypes.JS_OBJECT_EXPRESSION) {
-            const prop = genChildren.properties.find(
-              p =>
-                p.type === NodeTypes.JS_PROPERTY &&
-                p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
-                p.key.content === 'default' &&
-                p.value.params === undefined,
-            )
-            if (prop) {
-              children = prop.value.returns as TemplateChildNode[]
-            } else {
-              context.onError(
-                createCompilerError(ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT, loc),
+    return processSkip(node, dir, context, loc => {
+      return () => {
+        let children: TemplateChildNode[] = []
+        // for components, extract default slot without props
+        // if not found, throw an error
+        if (node.tagType === ElementTypes.COMPONENT) {
+          const codegenNode = node.codegenNode!
+          if (codegenNode.type === NodeTypes.VNODE_CALL) {
+            const genChildren = codegenNode.children! as SlotsExpression
+            if (genChildren.type === NodeTypes.JS_OBJECT_EXPRESSION) {
+              const prop = genChildren.properties.find(
+                p =>
+                  p.type === NodeTypes.JS_PROPERTY &&
+                  p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
+                  p.key.content === 'default' &&
+                  p.value.params === undefined,
               )
+              if (prop) {
+                children = prop.value.returns as TemplateChildNode[]
+              } else {
+                context.onError(
+                  createCompilerError(ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT, loc),
+                )
+              }
             }
           }
         }
-      }
-      // for plain elements, take all children
-      else {
-        children = node.children
-      }
-      const consequent: IfBranchNode = {
-        type: NodeTypes.IF_BRANCH,
-        loc: node.loc,
-        condition: undefined,
-        children,
-        userKey: findProp(node, `key`),
-      }
+        // for plain elements, take all children
+        else {
+          children = node.children
+        }
+        const consequent: IfBranchNode = {
+          type: NodeTypes.IF_BRANCH,
+          loc: node.loc,
+          condition: undefined,
+          children,
+          userKey: findProp(node, `key`),
+        }
 
-      const alternate: IfBranchNode = {
-        type: NodeTypes.IF_BRANCH,
-        loc: node.loc,
-        condition: undefined,
-        children: [node],
-        userKey: findProp(node, `key`),
-      }
+        const alternate: IfBranchNode = {
+          type: NodeTypes.IF_BRANCH,
+          loc: node.loc,
+          condition: undefined,
+          children: [node],
+          userKey: findProp(node, `key`),
+        }
 
-      node.codegenNode = createConditionalExpression(
-        dir.exp!,
-        createCodegenNodeForBranch(consequent, 0, context),
-        createCodegenNodeForBranch(alternate, 1, context),
-      )
-    }
+        node.codegenNode = createConditionalExpression(
+          dir.exp!,
+          createCodegenNodeForBranch(consequent, 0, context),
+          createCodegenNodeForBranch(alternate, 1, context),
+        )
+      }
+    })
   },
 )
+
+export function processSkip(
+  node: ElementNode,
+  dir: DirectiveNode,
+  context: TransformContext,
+  processCodegen?: (loc: SourceLocation) => () => void,
+): (() => void) | undefined {
+  const loc = dir.exp ? dir.exp.loc : node.loc
+  if (isTemplateNode(node) || isSlotOutlet(node)) {
+    context.onError(createCompilerError(ErrorCodes.X_V_SKIP_ON_TEMPLATE, loc))
+    return
+  }
+
+  if (findDir(node, 'for')) {
+    context.onError(createCompilerError(ErrorCodes.X_V_SKIP_WITH_V_FOR, loc))
+  }
+
+  if (!dir.exp || !(dir.exp as SimpleExpressionNode).content.trim()) {
+    context.onError(createCompilerError(ErrorCodes.X_V_SKIP_NO_EXPRESSION, loc))
+    dir.exp = createSimpleExpression(`true`, false, loc)
+  }
+
+  if (!__BROWSER__ && context.prefixIdentifiers && dir.exp) {
+    dir.exp = processExpression(dir.exp as SimpleExpressionNode, context)
+  }
+
+  if (__DEV__ && __BROWSER__ && dir.exp) {
+    validateBrowserExpression(dir.exp as SimpleExpressionNode, context)
+  }
+
+  if (processCodegen) return processCodegen(loc)
+}
index f8a686555e8b32e6b941cda69f348af0c0a7dfd6..03bc0bb231e8254d361917c3e50a9e9b7d03b248 100644 (file)
@@ -27,6 +27,7 @@ import { ssrTransformModel } from './transforms/ssrVModel'
 import { ssrTransformShow } from './transforms/ssrVShow'
 import { ssrInjectFallthroughAttrs } from './transforms/ssrInjectFallthroughAttrs'
 import { ssrInjectCssVars } from './transforms/ssrInjectCssVars'
+import { ssrTransformSkip } from './transforms/ssrVSkip'
 
 export function compile(
   source: string | RootNode,
@@ -56,6 +57,7 @@ export function compile(
     hoistStatic: false,
     nodeTransforms: [
       ssrTransformIf,
+      ssrTransformSkip,
       ssrTransformFor,
       trackVForSlotScopes,
       transformExpression,
index 1780a189d10300ad3fdf38ca382fa8a0e37c46fe..a28e517caf4f93cf9b22544327d25ad1d60c6c47 100644 (file)
@@ -1,29 +1,25 @@
 import {
   type ComponentNode,
   type DirectiveNode,
-  ErrorCodes,
   type IfBranchNode,
+  type NodeTransform,
   NodeTypes,
   type PlainElementNode,
-  type SimpleExpressionNode,
-  createCompilerError,
   createIfStatement,
-  createSimpleExpression,
+  createStructuralDirectiveTransform,
+  processSkip,
 } from '@vue/compiler-core'
 import { processIfBranch } from './ssrVIf'
 import type { SSRTransformContext } from '../ssrCodegenTransform'
 
+export const ssrTransformSkip: NodeTransform =
+  createStructuralDirectiveTransform('skip', processSkip)
+
 export function ssrProcessSkip(
   node: PlainElementNode | ComponentNode,
   dir: DirectiveNode,
   context: SSRTransformContext,
 ): void {
-  if (!dir.exp || !(dir.exp as SimpleExpressionNode).content.trim()) {
-    const loc = dir.exp ? dir.exp.loc : node.loc
-    context.onError(createCompilerError(ErrorCodes.X_V_SKIP_NO_EXPRESSION, loc))
-    dir.exp = createSimpleExpression(`true`, false, loc)
-  }
-
   node.props = node.props.filter(x => x.name !== 'skip')
   const consequent: IfBranchNode = {
     type: NodeTypes.IF_BRANCH,