]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: cache constant check result on transform context
authorEvan You <yyx990803@gmail.com>
Thu, 3 Dec 2020 16:10:40 +0000 (11:10 -0500)
committerEvan You <yyx990803@gmail.com>
Thu, 3 Dec 2020 16:10:40 +0000 (11:10 -0500)
also fix edge case for missed createVNode import on static svg nodes

packages/compiler-core/src/transform.ts
packages/compiler-core/src/transforms/hoistStatic.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-core/src/transforms/transformText.ts

index 474f491595c2fbeef3522416e4a9af6ac68b53f4..2a23efcb52eed373cd3f475007463b3603e5861a 100644 (file)
@@ -111,6 +111,7 @@ export interface TransformContext
   removeIdentifiers(exp: ExpressionNode | string): void
   hoist(exp: JSChildNode): SimpleExpressionNode
   cache<T extends JSChildNode>(exp: T, isVNode?: boolean): CacheExpression | T
+  constantCache: Map<TemplateChildNode, ConstantTypes>
 }
 
 export function createTransformContext(
@@ -163,6 +164,7 @@ export function createTransformContext(
     directives: new Set(),
     hoists: [],
     imports: new Set(),
+    constantCache: new Map(),
     temps: 0,
     cached: 0,
     identifiers: Object.create(null),
index 1c066d7b8ebeb1d3bb66c0d0cf6c95886426ab0e..004a1e5a1166990020eacd210032bb905117ce73 100644 (file)
@@ -14,12 +14,12 @@ import {
 import { TransformContext } from '../transform'
 import { PatchFlags, isString, isSymbol } from '@vue/shared'
 import { isSlotOutlet } from '../utils'
+import { CREATE_VNODE } from '../runtimeHelpers'
 
 export function hoistStatic(root: RootNode, context: TransformContext) {
   walk(
     root,
     context,
-    new Map(),
     // Root node is unfortunately non-hoistable due to potential parent
     // fallthrough attributes.
     isSingleElementRoot(root, root.children[0])
@@ -41,7 +41,6 @@ export function isSingleElementRoot(
 function walk(
   node: ParentNode,
   context: TransformContext,
-  resultCache: Map<TemplateChildNode, ConstantTypes>,
   doNotHoistNode: boolean = false
 ) {
   let hasHoistedNode = false
@@ -65,7 +64,7 @@ function walk(
     ) {
       const constantType = doNotHoistNode
         ? ConstantTypes.NOT_CONSTANT
-        : getConstantType(child, resultCache)
+        : getConstantType(child, context)
       if (constantType > ConstantTypes.NOT_CONSTANT) {
         if (constantType < ConstantTypes.CAN_STRINGIFY) {
           canStringify = false
@@ -87,7 +86,7 @@ function walk(
             (!flag ||
               flag === PatchFlags.NEED_PATCH ||
               flag === PatchFlags.TEXT) &&
-            getGeneratedPropsConstantType(child, resultCache) >=
+            getGeneratedPropsConstantType(child, context) >=
               ConstantTypes.CAN_HOIST
           ) {
             const props = getNodeProps(child)
@@ -98,7 +97,7 @@ function walk(
         }
       }
     } else if (child.type === NodeTypes.TEXT_CALL) {
-      const contentType = getConstantType(child.content, resultCache)
+      const contentType = getConstantType(child.content, context)
       if (contentType > 0) {
         if (contentType < ConstantTypes.CAN_STRINGIFY) {
           canStringify = false
@@ -112,17 +111,16 @@ function walk(
 
     // walk further
     if (child.type === NodeTypes.ELEMENT) {
-      walk(child, context, resultCache)
+      walk(child, context)
     } else if (child.type === NodeTypes.FOR) {
       // Do not hoist v-for single child because it has to be a block
-      walk(child, context, resultCache, child.children.length === 1)
+      walk(child, context, child.children.length === 1)
     } else if (child.type === NodeTypes.IF) {
       for (let i = 0; i < child.branches.length; i++) {
         // Do not hoist v-if single child because it has to be a block
         walk(
           child.branches[i],
           context,
-          resultCache,
           child.branches[i].children.length === 1
         )
       }
@@ -136,14 +134,15 @@ function walk(
 
 export function getConstantType(
   node: TemplateChildNode | SimpleExpressionNode,
-  resultCache: Map<TemplateChildNode, ConstantTypes> = new Map()
+  context: TransformContext
 ): ConstantTypes {
+  const { constantCache } = context
   switch (node.type) {
     case NodeTypes.ELEMENT:
       if (node.tagType !== ElementTypes.ELEMENT) {
         return ConstantTypes.NOT_CONSTANT
       }
-      const cached = resultCache.get(node)
+      const cached = constantCache.get(node)
       if (cached !== undefined) {
         return cached
       }
@@ -161,12 +160,9 @@ export function getConstantType(
         // non-hoistable expressions that refers to scope variables, e.g. compiler
         // injected keys or cached event handlers. Therefore we need to always
         // check the codegenNode's props to be sure.
-        const generatedPropsType = getGeneratedPropsConstantType(
-          node,
-          resultCache
-        )
+        const generatedPropsType = getGeneratedPropsConstantType(node, context)
         if (generatedPropsType === ConstantTypes.NOT_CONSTANT) {
-          resultCache.set(node, ConstantTypes.NOT_CONSTANT)
+          constantCache.set(node, ConstantTypes.NOT_CONSTANT)
           return ConstantTypes.NOT_CONSTANT
         }
         if (generatedPropsType < returnType) {
@@ -175,9 +171,9 @@ export function getConstantType(
 
         // 2. its children.
         for (let i = 0; i < node.children.length; i++) {
-          const childType = getConstantType(node.children[i], resultCache)
+          const childType = getConstantType(node.children[i], context)
           if (childType === ConstantTypes.NOT_CONSTANT) {
-            resultCache.set(node, ConstantTypes.NOT_CONSTANT)
+            constantCache.set(node, ConstantTypes.NOT_CONSTANT)
             return ConstantTypes.NOT_CONSTANT
           }
           if (childType < returnType) {
@@ -193,9 +189,9 @@ export function getConstantType(
           for (let i = 0; i < node.props.length; i++) {
             const p = node.props[i]
             if (p.type === NodeTypes.DIRECTIVE && p.name === 'bind' && p.exp) {
-              const expType = getConstantType(p.exp, resultCache)
+              const expType = getConstantType(p.exp, context)
               if (expType === ConstantTypes.NOT_CONSTANT) {
-                resultCache.set(node, ConstantTypes.NOT_CONSTANT)
+                constantCache.set(node, ConstantTypes.NOT_CONSTANT)
                 return ConstantTypes.NOT_CONSTANT
               }
               if (expType < returnType) {
@@ -210,12 +206,13 @@ export function getConstantType(
         // nested updates.
         if (codegenNode.isBlock) {
           codegenNode.isBlock = false
+          context.helper(CREATE_VNODE)
         }
 
-        resultCache.set(node, returnType)
+        constantCache.set(node, returnType)
         return returnType
       } else {
-        resultCache.set(node, ConstantTypes.NOT_CONSTANT)
+        constantCache.set(node, ConstantTypes.NOT_CONSTANT)
         return ConstantTypes.NOT_CONSTANT
       }
     case NodeTypes.TEXT:
@@ -227,7 +224,7 @@ export function getConstantType(
       return ConstantTypes.NOT_CONSTANT
     case NodeTypes.INTERPOLATION:
     case NodeTypes.TEXT_CALL:
-      return getConstantType(node.content, resultCache)
+      return getConstantType(node.content, context)
     case NodeTypes.SIMPLE_EXPRESSION:
       return node.constType
     case NodeTypes.COMPOUND_EXPRESSION:
@@ -237,7 +234,7 @@ export function getConstantType(
         if (isString(child) || isSymbol(child)) {
           continue
         }
-        const childType = getConstantType(child, resultCache)
+        const childType = getConstantType(child, context)
         if (childType === ConstantTypes.NOT_CONSTANT) {
           return ConstantTypes.NOT_CONSTANT
         } else if (childType < returnType) {
@@ -256,7 +253,7 @@ export function getConstantType(
 
 function getGeneratedPropsConstantType(
   node: PlainElementNode,
-  resultCache: Map<TemplateChildNode, ConstantTypes>
+  context: TransformContext
 ): ConstantTypes {
   let returnType = ConstantTypes.CAN_STRINGIFY
   const props = getNodeProps(node)
@@ -264,7 +261,7 @@ function getGeneratedPropsConstantType(
     const { properties } = props
     for (let i = 0; i < properties.length; i++) {
       const { key, value } = properties[i]
-      const keyType = getConstantType(key, resultCache)
+      const keyType = getConstantType(key, context)
       if (keyType === ConstantTypes.NOT_CONSTANT) {
         return keyType
       }
@@ -274,7 +271,7 @@ function getGeneratedPropsConstantType(
       if (value.type !== NodeTypes.SIMPLE_EXPRESSION) {
         return ConstantTypes.NOT_CONSTANT
       }
-      const valueType = getConstantType(value, resultCache)
+      const valueType = getConstantType(value, context)
       if (valueType === ConstantTypes.NOT_CONSTANT) {
         return valueType
       }
index 53b148b42bbd20b118f8b08ffb4c52b5c7520dfd..0283d3eec5eb3e900f40b073d088fba0f9641ede 100644 (file)
@@ -168,7 +168,7 @@ export const transformElement: NodeTransform = (node, context) => {
           type === NodeTypes.COMPOUND_EXPRESSION
         if (
           hasDynamicTextChild &&
-          getConstantType(child) === ConstantTypes.NOT_CONSTANT
+          getConstantType(child, context) === ConstantTypes.NOT_CONSTANT
         ) {
           patchFlag |= PatchFlags.TEXT
         }
@@ -373,7 +373,7 @@ export function buildProps(
         value.type === NodeTypes.JS_CACHE_EXPRESSION ||
         ((value.type === NodeTypes.SIMPLE_EXPRESSION ||
           value.type === NodeTypes.COMPOUND_EXPRESSION) &&
-          getConstantType(value) > 0)
+          getConstantType(value, context) > 0)
       ) {
         // skip if the prop is a cached handler or has constant value
         return
index 0c672f9cc8c8faece7748dc27403e670f7e011ea..3576e0e2cbff351469aea0c9d6391a4fda6c2292 100644 (file)
@@ -82,7 +82,7 @@ export const transformText: NodeTransform = (node, context) => {
           // mark dynamic text with flag so it gets patched inside a block
           if (
             !context.ssr &&
-            getConstantType(child) === ConstantTypes.NOT_CONSTANT
+            getConstantType(child, context) === ConstantTypes.NOT_CONSTANT
           ) {
             callArgs.push(
               PatchFlags.TEXT +