From: Evan You Date: Wed, 12 Feb 2025 03:57:16 +0000 (+0800) Subject: refactor: adjust isConstantNode X-Git-Tag: v3.6.0-alpha.1~16^2~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=63cf2ee3f144ac51e8f9e3280548b76289e5dcfa;p=thirdparty%2Fvuejs%2Fcore.git refactor: adjust isConstantNode --- diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index f81f269157..ccf123f7bb 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -12,6 +12,7 @@ import type { Program, } from '@babel/types' import { walk } from 'estree-walker' +import { type BindingMetadata, BindingTypes } from './options' /** * Return value indicates whether the AST walked can be a constant @@ -543,34 +544,31 @@ export function isStaticNode(node: Node): boolean { case 'BooleanLiteral': case 'NullLiteral': case 'BigIntLiteral': + case 'RegExpLiteral': return true } return false } -export function isConstantNode( - node: Node, - onIdentifier: (name: string) => boolean, -): boolean { +export function isConstantNode(node: Node, bindings: BindingMetadata): boolean { if (isStaticNode(node)) return true node = unwrapTSNode(node) switch (node.type) { case 'Identifier': - return onIdentifier(node.name) - case 'RegExpLiteral': - return true + const type = bindings[node.name] + return type === BindingTypes.LITERAL_CONST case 'ObjectExpression': return node.properties.every(prop => { // { bar() {} } object methods are not considered static nodes if (prop.type === 'ObjectMethod') return false // { ...{ foo: 1 } } if (prop.type === 'SpreadElement') - return isConstantNode(prop.argument, onIdentifier) + return isConstantNode(prop.argument, bindings) // { foo: 1 } return ( - (!prop.computed || isConstantNode(prop.key, onIdentifier)) && - isConstantNode(prop.value, onIdentifier) + (!prop.computed || isConstantNode(prop.key, bindings)) && + isConstantNode(prop.value, bindings) ) }) case 'ArrayExpression': @@ -579,9 +577,9 @@ export function isConstantNode( if (element === null) return true // [1, ...[2, 3]] if (element.type === 'SpreadElement') - return isConstantNode(element.argument, onIdentifier) + return isConstantNode(element.argument, bindings) // [1, 2] - return isConstantNode(element, onIdentifier) + return isConstantNode(element, bindings) }) } return false diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap index 302e240ca5..15da71ff4f 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap @@ -23,7 +23,7 @@ export function render(_ctx) { const n2 = t0() _setTemplateRef(n2, "foo", void 0, true) return n2 - }) + }, null, null, true) return n0 }" `; diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index bf619b17dc..76563899d2 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -143,7 +143,9 @@ export class TransformContext { if ( this.inVOnce || expressions.length === 0 || - isStaticExpression(this.root, expressions) + expressions.every(e => + isStaticExpression(e, this.root.options.bindingMetadata), + ) ) { return this.registerOperation(...operations) } diff --git a/packages/compiler-vapor/src/transforms/transformText.ts b/packages/compiler-vapor/src/transforms/transformText.ts index 852cfd463e..12f072818d 100644 --- a/packages/compiler-vapor/src/transforms/transformText.ts +++ b/packages/compiler-vapor/src/transforms/transformText.ts @@ -59,7 +59,9 @@ function processTextLike(context: TransformContext) { const nonConstantExps = values.filter(v => !isConstantExpression(v)) const isStatic = !nonConstantExps.length || - isStaticExpression(context, nonConstantExps) || + nonConstantExps.every(e => + isStaticExpression(e, context.options.bindingMetadata), + ) || context.inVOnce context.registerOperation({ diff --git a/packages/compiler-vapor/src/transforms/vFor.ts b/packages/compiler-vapor/src/transforms/vFor.ts index 83bda63067..69480672a9 100644 --- a/packages/compiler-vapor/src/transforms/vFor.ts +++ b/packages/compiler-vapor/src/transforms/vFor.ts @@ -16,7 +16,7 @@ import { IRNodeTypes, type VaporDirectiveNode, } from '../ir' -import { findProp, propToExpression } from '../utils' +import { findProp, isStaticExpression, propToExpression } from '../utils' import { newBlock, wrapTemplate } from './utils' export const transformVFor: NodeTransform = createStructuralDirectiveTransform( @@ -76,7 +76,12 @@ export function processFor( index: index as SimpleExpressionNode | undefined, keyProp: keyProperty, render, - once: context.inVOnce, + once: + context.inVOnce || + isStaticExpression( + source as SimpleExpressionNode, + context.options.bindingMetadata, + ), component: isComponent, onlyChild: !!isOnlyChild, }) diff --git a/packages/compiler-vapor/src/transforms/vIf.ts b/packages/compiler-vapor/src/transforms/vIf.ts index f59abe9e2f..8fad9c3146 100644 --- a/packages/compiler-vapor/src/transforms/vIf.ts +++ b/packages/compiler-vapor/src/transforms/vIf.ts @@ -18,6 +18,7 @@ import { import { extend } from '@vue/shared' import { newBlock, wrapTemplate } from './utils' import { getSiblingIf } from './transformComment' +import { isStaticExpression } from '../utils' export const transformVIf: NodeTransform = createStructuralDirectiveTransform( ['if', 'else', 'else-if'], @@ -50,7 +51,9 @@ export function processIf( id, condition: dir.exp!, positive: branch, - once: context.inVOnce, + once: + context.inVOnce || + isStaticExpression(dir.exp!, context.options.bindingMetadata), }) } } else { diff --git a/packages/compiler-vapor/src/utils.ts b/packages/compiler-vapor/src/utils.ts index b20bd3ef16..728281914f 100644 --- a/packages/compiler-vapor/src/utils.ts +++ b/packages/compiler-vapor/src/utils.ts @@ -2,6 +2,7 @@ import type { BigIntLiteral, NumericLiteral, StringLiteral } from '@babel/types' import { isGloballyAllowed } from '@vue/shared' import { type AttributeNode, + type BindingMetadata, BindingTypes, type ElementNode, NodeTypes, @@ -14,7 +15,6 @@ import { } from '@vue/compiler-dom' import type { VaporDirectiveNode } from './ir' import { EMPTY_EXPRESSION } from './transforms/utils' -import type { TransformContext } from './transform' export const findProp = _findProp as ( node: ElementNode, @@ -49,21 +49,16 @@ export function isConstantExpression(exp: SimpleExpressionNode): boolean { } export function isStaticExpression( - context: TransformContext, - expressions: SimpleExpressionNode[], + node: SimpleExpressionNode, + bindings: BindingMetadata, ): boolean { - const { - options: { bindingMetadata }, - } = context - const isLiteralConst = (name: string) => - bindingMetadata[name] === BindingTypes.LITERAL_CONST - return expressions.every(node => { - if (node.ast) { - return isConstantNode(node.ast, isLiteralConst) - } else if (node.ast === null) { - return isLiteralConst(node.content) - } - }) + if (node.ast) { + return isConstantNode(node.ast, bindings) + } else if (node.ast === null) { + const type = bindings[node.content] + return type === BindingTypes.LITERAL_CONST + } + return false } export function resolveExpression(