fix(compiler-core): remove unnecessary constant bail check

member expressions and call expressions can only happen when there are identifiers

close #10807
This commit is contained in:
Evan You 2024-04-29 12:21:24 +08:00
parent 9c2de6244c
commit 09b4df809e
No known key found for this signature in database
GPG Key ID: B9D421896CA450FB
3 changed files with 15 additions and 10 deletions

View File

@ -421,6 +421,16 @@ describe('compiler: expression transform', () => {
}) })
}) })
// #10807
test('should not bail constant on strings w/ ()', () => {
const node = parseWithExpressionTransform(
`{{ { foo: 'ok()' } }}`,
) as InterpolationNode
expect(node.content).toMatchObject({
constType: ConstantTypes.CAN_STRINGIFY,
})
})
describe('ES Proposals support', () => { describe('ES Proposals support', () => {
test('bigInt', () => { test('bigInt', () => {
const node = parseWithExpressionTransform( const node = parseWithExpressionTransform(

View File

@ -10,6 +10,9 @@ import type {
} from '@babel/types' } from '@babel/types'
import { walk } from 'estree-walker' import { walk } from 'estree-walker'
/**
* Return value indicates whether the AST walked can be a constant
*/
export function walkIdentifiers( export function walkIdentifiers(
root: Node, root: Node,
onIdentifier: ( onIdentifier: (

View File

@ -46,10 +46,6 @@ import { BindingTypes } from '../options'
const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this') const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this')
// a heuristic safeguard to bail constant expressions on presence of
// likely function invocation and member access
const constantBailRE = /\w\s*\(|\.[^\d]/
export const transformExpression: NodeTransform = (node, context) => { export const transformExpression: NodeTransform = (node, context) => {
if (node.type === NodeTypes.INTERPOLATION) { if (node.type === NodeTypes.INTERPOLATION) {
node.content = processExpression( node.content = processExpression(
@ -226,8 +222,6 @@ export function processExpression(
// fast path if expression is a simple identifier. // fast path if expression is a simple identifier.
const rawExp = node.content const rawExp = node.content
// bail constant on parens (function invocation) and dot (member access)
const bailConstant = constantBailRE.test(rawExp)
let ast = node.ast let ast = node.ast
@ -317,7 +311,7 @@ export function processExpression(
} else { } else {
// The identifier is considered constant unless it's pointing to a // The identifier is considered constant unless it's pointing to a
// local scope variable (a v-for alias, or a v-slot prop) // local scope variable (a v-for alias, or a v-slot prop)
if (!(needPrefix && isLocal) && !bailConstant) { if (!(needPrefix && isLocal)) {
;(node as QualifiedId).isConstant = true ;(node as QualifiedId).isConstant = true
} }
// also generate sub-expressions for other identifiers for better // also generate sub-expressions for other identifiers for better
@ -371,9 +365,7 @@ export function processExpression(
ret.ast = ast ret.ast = ast
} else { } else {
ret = node ret = node
ret.constType = bailConstant ret.constType = ConstantTypes.CAN_STRINGIFY
? ConstantTypes.NOT_CONSTANT
: ConstantTypes.CAN_STRINGIFY
} }
ret.identifiers = Object.keys(knownIds) ret.identifiers = Object.keys(knownIds)
return ret return ret