diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
index 0b68b42d..885bdc01 100644
--- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
@@ -1,8 +1,93 @@
-import { compile } from '../../src'
+import {
+ parse,
+ transform,
+ ExpressionNode,
+ ElementNode,
+ DirectiveNode
+} from '../../src'
+import { transformFor } from '../..//src/transforms/vFor'
+import { transformExpression } from '../../src/transforms/transformExpression'
-test(`should work`, () => {
- const { code } = compile(`
{{ foo }} bar
`, {
- prefixIdentifiers: true
+function parseWithExpressionTransform(template: string) {
+ const ast = parse(template)
+ transform(ast, {
+ prefixIdentifiers: true,
+ nodeTransforms: [transformFor, transformExpression]
})
- expect(code).toContain(`foo`)
+ return ast.children[0]
+}
+
+describe('compiler: expression transform', () => {
+ test('interpolation (root)', () => {
+ const node = parseWithExpressionTransform(`{{ foo }}`) as ExpressionNode
+ expect(node.content).toBe(`_ctx.foo`)
+ })
+
+ test('interpolation (children)', () => {
+ const node = parseWithExpressionTransform(
+ `{{ foo }}
`
+ ) as ElementNode
+ expect((node.children[0] as ExpressionNode).content).toBe(`_ctx.foo`)
+ })
+
+ test('directive value', () => {
+ const node = parseWithExpressionTransform(
+ ``
+ ) as ElementNode
+ expect((node.props[0] as DirectiveNode).arg!.content).toBe(`arg`)
+ expect((node.props[0] as DirectiveNode).exp!.content).toBe(`_ctx.baz`)
+ })
+
+ test('dynamic directive arg', () => {
+ const node = parseWithExpressionTransform(
+ ``
+ ) as ElementNode
+ expect((node.props[0] as DirectiveNode).arg!.content).toBe(`_ctx.arg`)
+ expect((node.props[0] as DirectiveNode).exp!.content).toBe(`_ctx.baz`)
+ })
+
+ test('should prefix complex expressions', () => {
+ const node = parseWithExpressionTransform(
+ `{{ foo(baz + 1, { key: kuz }) }}`
+ ) as ExpressionNode
+ // should parse into compound expression
+ expect(node.children).toMatchObject([
+ { content: `_ctx.foo` },
+ `(`,
+ { content: `_ctx.baz` },
+ ` + 1, { key: `,
+ { content: `_ctx.kuz` },
+ ` })`
+ ])
+ })
+
+ // TODO FIXME
+ test('should not prefix v-for aliases', () => {
+ // const node = parseWithExpressionTransform(`{{ { foo } }}`) as ExpressionNode
+ // expect(node.children).toMatchObject([
+ // `{ foo: `,
+ // { content: `_ctx.foo` },
+ // ` }`
+ // ])
+ })
+
+ test('should prefix id outside of v-for', () => {})
+
+ test('nested v-for', () => {})
+
+ test('should not prefix whitelisted globals', () => {})
+
+ test('should not prefix id of a function declaration', () => {})
+
+ test('should not prefix params of a function expression', () => {
+ // also test object + array destructure
+ })
+
+ test('should not prefix an object property key', () => {})
+
+ test('should prefix a computed object property key', () => {})
+
+ test('should prefix object property shorthand value', () => {})
+
+ test('should not prefix id in a member expression', () => {})
})
diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts
index 0259c3bb..e07a20f7 100644
--- a/packages/compiler-core/src/codegen.ts
+++ b/packages/compiler-core/src/codegen.ts
@@ -294,17 +294,18 @@ function genExpressionAsPropertyKey(
node: ExpressionNode,
context: CodegenContext
) {
- if (node.children) {
- return genCompoundExpression(node, context)
- }
- if (node.isStatic) {
+ const { push } = context
+ const { content, children, isStatic } = node
+ if (children) {
+ push(`[`)
+ genCompoundExpression(node, context)
+ push(`]`)
+ } else if (isStatic) {
// only quote keys if necessary
- const text = /^\d|[^\w]/.test(node.content)
- ? JSON.stringify(node.content)
- : node.content
- context.push(text, node)
+ const text = /^\d|[^\w]/.test(content) ? JSON.stringify(content) : content
+ push(text, node)
} else {
- context.push(`[${node.content}]`, node)
+ push(`[${content}]`, node)
}
}
diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts
index adc9ee1c..55c24b53 100644
--- a/packages/compiler-core/src/transforms/transformExpression.ts
+++ b/packages/compiler-core/src/transforms/transformExpression.ts
@@ -74,11 +74,13 @@ export function processExpression(
walk(ast, {
enter(node, parent) {
if (node.type === 'Identifier') {
- if (ids.indexOf(node) === -1) {
+ if (
+ ids.indexOf(node) === -1 &&
+ !knownIds[node.name] &&
+ shouldPrefix(node, parent)
+ ) {
+ node.name = `_ctx.${node.name}`
ids.push(node)
- if (!knownIds[node.name] && shouldPrefix(node, parent)) {
- node.name = `_ctx.${node.name}`
- }
}
} else if (isFunction(node)) {
node.params.forEach(p =>
@@ -123,11 +125,13 @@ export function processExpression(
})
)
if (i === ids.length - 1 && id.end < full.length - 1) {
- children.push(full.slice(id.end))
+ children.push(full.slice(id.end - 1))
}
})
- node.children = children
+ if (children.length) {
+ node.children = children
+ }
}
const globals = new Set(