fix(compiler): should not prefix reserved literals (close #142)

This commit is contained in:
Evan You 2019-10-08 11:25:24 -04:00
parent 174d13acf0
commit b4d375b0b8

View File

@ -25,6 +25,8 @@ import {
} from '../utils' } from '../utils'
import { globalsWhitelist } from '@vue/shared' import { globalsWhitelist } from '@vue/shared'
const literalsWhitelist = new Set([`true`, `false`, `null`, `this`])
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(
@ -78,9 +80,15 @@ export function processExpression(
} }
// fast path if expression is a simple identifier. // fast path if expression is a simple identifier.
if (isSimpleIdentifier(node.content)) { const rawExp = node.content
if (!asParams && !context.identifiers[node.content]) { if (isSimpleIdentifier(rawExp)) {
node.content = `_ctx.${node.content}` if (
!asParams &&
!context.identifiers[rawExp] &&
!globalsWhitelist.has(rawExp) &&
!literalsWhitelist.has(rawExp)
) {
node.content = `_ctx.${rawExp}`
} }
return node return node
} }
@ -88,7 +96,7 @@ export function processExpression(
let ast: any let ast: any
// if the expression is supposed to be used in a function params position // if the expression is supposed to be used in a function params position
// we need to parse it differently. // we need to parse it differently.
const source = `(${node.content})${asParams ? `=>{}` : ``}` const source = `(${rawExp})${asParams ? `=>{}` : ``}`
try { try {
ast = parseJS(source, { ranges: true }) ast = parseJS(source, { ranges: true })
} catch (e) { } catch (e) {
@ -174,7 +182,6 @@ export function processExpression(
// expressions (for identifiers that have been prefixed). In codegen, if // expressions (for identifiers that have been prefixed). In codegen, if
// an ExpressionNode has the `.children` property, it will be used instead of // an ExpressionNode has the `.children` property, it will be used instead of
// `.content`. // `.content`.
const full = node.content
const children: CompoundExpressionNode['children'] = [] const children: CompoundExpressionNode['children'] = []
ids.sort((a, b) => a.start - b.start) ids.sort((a, b) => a.start - b.start)
ids.forEach((id, i) => { ids.forEach((id, i) => {
@ -182,11 +189,11 @@ export function processExpression(
const start = id.start - 1 const start = id.start - 1
const end = id.end - 1 const end = id.end - 1
const last = ids[i - 1] as any const last = ids[i - 1] as any
const leadingText = full.slice(last ? last.end - 1 : 0, start) const leadingText = rawExp.slice(last ? last.end - 1 : 0, start)
if (leadingText.length || id.prefix) { if (leadingText.length || id.prefix) {
children.push(leadingText + (id.prefix || ``)) children.push(leadingText + (id.prefix || ``))
} }
const source = full.slice(start, end) const source = rawExp.slice(start, end)
children.push( children.push(
createSimpleExpression(id.name, false, { createSimpleExpression(id.name, false, {
source, source,
@ -194,8 +201,8 @@ export function processExpression(
end: advancePositionWithClone(node.loc.start, source, end) end: advancePositionWithClone(node.loc.start, source, end)
}) })
) )
if (i === ids.length - 1 && end < full.length) { if (i === ids.length - 1 && end < rawExp.length) {
children.push(full.slice(end)) children.push(rawExp.slice(end))
} }
}) })