diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts index 5a77b2eddbc..7614bc0f386 100644 --- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts @@ -431,6 +431,16 @@ describe('compiler: expression transform', () => { }) }) + // #8295 + test('should treat floating point number literals as constant', () => { + const node = parseWithExpressionTransform( + `{{ [1, 2.1] }}` + ) as InterpolationNode + expect(node.content).toMatchObject({ + constType: ConstantTypes.CAN_STRINGIFY + }) + }) + describe('ES Proposals support', () => { test('bigInt', () => { const node = parseWithExpressionTransform( diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index 35fc278ac86..3e75923d0d4 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -45,6 +45,10 @@ import { BindingTypes } from '../options' 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) => { if (node.type === NodeTypes.INTERPOLATION) { node.content = processExpression( @@ -217,7 +221,7 @@ export function processExpression( // fast path if expression is a simple identifier. const rawExp = node.content // bail constant on parens (function invocation) and dot (member access) - const bailConstant = rawExp.indexOf(`(`) > -1 || rawExp.indexOf('.') > 0 + const bailConstant = constantBailRE.test(rawExp) if (isSimpleIdentifier(rawExp)) { const isScopeVarReference = context.identifiers[rawExp]