+++ /dev/null
-describe('compiler: element transform', () => {
- test.todo('should work')
-})
+++ /dev/null
-import { SourceMapConsumer } from 'source-map'
-import { compile } from '../../src'
-
-test(`should work`, async () => {
- const { code, map } = compile(`<div>{{ foo }} bar</div>`, {
- prefixIdentifiers: true
- })
- console.log(code)
- const consumer = await new SourceMapConsumer(map!)
- const pos = consumer.originalPositionFor({
- line: 4,
- column: 31
- })
- console.log(pos)
-})
--- /dev/null
+import {
+ ElementNode,
+ CompilerOptions,
+ parse,
+ transform,
+ ErrorCodes
+} from '../../src'
+import { transformElement } from '../../src/transforms/transformElement'
+import {
+ RESOLVE_COMPONENT,
+ CREATE_VNODE,
+ MERGE_PROPS,
+ RESOLVE_DIRECTIVE,
+ APPLY_DIRECTIVES
+} from '../../src/runtimeConstants'
+import {
+ CallExpression,
+ NodeTypes,
+ createObjectProperty,
+ DirectiveNode,
+ RootNode
+} from '../../src/ast'
+
+function parseWithElementTransform(
+ template: string,
+ options: CompilerOptions = {}
+): {
+ root: RootNode
+ node: CallExpression
+} {
+ const ast = parse(template, options)
+ transform(ast, {
+ nodeTransforms: [transformElement],
+ ...options
+ })
+ const codegenNode = (ast.children[0] as ElementNode)
+ .codegenNode as CallExpression
+ expect(codegenNode.type).toBe(NodeTypes.JS_CALL_EXPRESSION)
+ return {
+ root: ast,
+ node: codegenNode
+ }
+}
+
+function createStaticObjectMatcher(obj: any) {
+ return {
+ type: NodeTypes.JS_OBJECT_EXPRESSION,
+ properties: Object.keys(obj).map(key => ({
+ type: NodeTypes.JS_PROPERTY,
+ key: {
+ type: NodeTypes.EXPRESSION,
+ content: key,
+ isStatic: true
+ },
+ value: {
+ type: NodeTypes.EXPRESSION,
+ content: obj[key],
+ isStatic: true
+ }
+ }))
+ }
+}
+
+describe('compiler: element transform', () => {
+ test('import + resovle component', () => {
+ const { root } = parseWithElementTransform(`<Foo/>`)
+ expect(root.imports).toContain(RESOLVE_COMPONENT)
+ expect(root.statements[0]).toMatch(`${RESOLVE_COMPONENT}("Foo")`)
+ })
+
+ test('static props', () => {
+ const { node } = parseWithElementTransform(`<div id="foo" class="bar" />`)
+ expect(node.callee).toBe(CREATE_VNODE)
+ expect(node.arguments).toMatchObject([
+ `"div"`,
+ createStaticObjectMatcher({
+ id: 'foo',
+ class: 'bar'
+ })
+ ])
+ })
+
+ test('v-bind="obj"', () => {
+ const { root, node } = parseWithElementTransform(`<div v-bind="obj" />`)
+ // single v-bind doesn't need mergeProps
+ expect(root.imports).not.toContain(MERGE_PROPS)
+ expect(node.callee).toBe(CREATE_VNODE)
+ // should directly use `obj` in props position
+ expect(node.arguments[1]).toMatchObject({
+ type: NodeTypes.EXPRESSION,
+ content: `obj`
+ })
+ })
+
+ test('v-bind="obj" after static prop', () => {
+ const { root, node } = parseWithElementTransform(
+ `<div id="foo" v-bind="obj" />`
+ )
+ expect(root.imports).toContain(MERGE_PROPS)
+ expect(node.callee).toBe(CREATE_VNODE)
+ expect(node.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: MERGE_PROPS,
+ arguments: [
+ createStaticObjectMatcher({
+ id: 'foo'
+ }),
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `obj`
+ }
+ ]
+ })
+ })
+
+ test('v-bind="obj" before static prop', () => {
+ const { root, node } = parseWithElementTransform(
+ `<div v-bind="obj" id="foo" />`
+ )
+ expect(root.imports).toContain(MERGE_PROPS)
+ expect(node.callee).toBe(CREATE_VNODE)
+ expect(node.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: MERGE_PROPS,
+ arguments: [
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `obj`
+ },
+ createStaticObjectMatcher({
+ id: 'foo'
+ })
+ ]
+ })
+ })
+
+ test('v-bind="obj" between static props', () => {
+ const { root, node } = parseWithElementTransform(
+ `<div id="foo" v-bind="obj" class="bar" />`
+ )
+ expect(root.imports).toContain(MERGE_PROPS)
+ expect(node.callee).toBe(CREATE_VNODE)
+ expect(node.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: MERGE_PROPS,
+ arguments: [
+ createStaticObjectMatcher({
+ id: 'foo'
+ }),
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `obj`
+ },
+ createStaticObjectMatcher({
+ class: 'bar'
+ })
+ ]
+ })
+ })
+
+ test('error on v-bind with no argument', () => {
+ const onError = jest.fn()
+ parseWithElementTransform(`<div v-bind/>`, { onError })
+ expect(onError.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_V_BIND_NO_EXPRESSION
+ }
+ ])
+ })
+
+ test('directiveTransforms', () => {
+ let _dir: DirectiveNode
+ const { node } = parseWithElementTransform(`<div v-foo:bar="hello" />`, {
+ directiveTransforms: {
+ foo(dir) {
+ _dir = dir
+ return {
+ props: createObjectProperty(dir.arg!, dir.exp!, dir.loc),
+ needRuntime: false
+ }
+ }
+ }
+ })
+ expect(node.callee).toBe(CREATE_VNODE)
+ expect(node.arguments[1]).toMatchObject({
+ type: NodeTypes.JS_OBJECT_EXPRESSION,
+ properties: [
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: _dir!.arg,
+ value: _dir!.exp
+ }
+ ]
+ })
+ })
+
+ test('directiveTransform with needRuntime: true', () => {
+ let _dir: DirectiveNode
+ const { root, node } = parseWithElementTransform(
+ `<div v-foo:bar="hello" />`,
+ {
+ directiveTransforms: {
+ foo(dir) {
+ _dir = dir
+ return {
+ props: [
+ createObjectProperty(dir.arg!, dir.exp!, dir.loc),
+ createObjectProperty(dir.arg!, dir.exp!, dir.loc)
+ ],
+ needRuntime: true
+ }
+ }
+ }
+ }
+ )
+ expect(root.imports).toContain(RESOLVE_DIRECTIVE)
+ expect(root.statements[0]).toMatch(`${RESOLVE_DIRECTIVE}("foo")`)
+
+ expect(node.callee).toBe(APPLY_DIRECTIVES)
+ expect(node.arguments).toMatchObject([
+ {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ callee: CREATE_VNODE,
+ arguments: [
+ `"div"`,
+ {
+ type: NodeTypes.JS_OBJECT_EXPRESSION,
+ properties: [
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: _dir!.arg,
+ value: _dir!.exp
+ },
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: _dir!.arg,
+ value: _dir!.exp
+ }
+ ]
+ }
+ ]
+ },
+ {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ `_directive_foo`,
+ // exp
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `hello`,
+ isStatic: false,
+ isInterpolation: false
+ },
+ // arg
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `bar`,
+ isStatic: true
+ }
+ ]
+ }
+ ]
+ }
+ ])
+ })
+
+ test('runtime directives', () => {
+ const { root, node } = parseWithElementTransform(
+ `<div v-foo v-bar="x" v-baz:[arg].mod.mad="y" />`
+ )
+ expect(root.imports).toContain(RESOLVE_DIRECTIVE)
+ expect(root.statements[0]).toMatch(`${RESOLVE_DIRECTIVE}("foo")`)
+ expect(root.statements[1]).toMatch(`${RESOLVE_DIRECTIVE}("bar")`)
+ expect(root.statements[2]).toMatch(`${RESOLVE_DIRECTIVE}("baz")`)
+
+ expect(node.callee).toBe(APPLY_DIRECTIVES)
+ expect(node.arguments).toMatchObject([
+ {
+ type: NodeTypes.JS_CALL_EXPRESSION
+ },
+ {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [`_directive_foo`]
+ },
+ {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ `_directive_bar`,
+ // exp
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `x`
+ }
+ ]
+ },
+ {
+ type: NodeTypes.JS_ARRAY_EXPRESSION,
+ elements: [
+ `_directive_baz`,
+ // exp
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `y`,
+ isStatic: false,
+ isInterpolation: false
+ },
+ // arg
+ {
+ type: NodeTypes.EXPRESSION,
+ content: `arg`,
+ isStatic: false
+ },
+ // modifiers
+ {
+ type: NodeTypes.JS_OBJECT_EXPRESSION,
+ properties: [
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: {
+ type: NodeTypes.EXPRESSION,
+ content: `mod`,
+ isStatic: true
+ },
+ value: {
+ type: NodeTypes.EXPRESSION,
+ content: `true`,
+ isStatic: false
+ }
+ },
+ {
+ type: NodeTypes.JS_PROPERTY,
+ key: {
+ type: NodeTypes.EXPRESSION,
+ content: `mad`,
+ isStatic: true
+ },
+ value: {
+ type: NodeTypes.EXPRESSION,
+ content: `true`,
+ isStatic: false
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ])
+ })
+
+ test.todo('slot outlets')
+})
--- /dev/null
+import { compile } from '../../src'
+
+test(`should work`, () => {
+ const { code } = compile(`<div>{{ foo }} bar</div>`, {
+ prefixIdentifiers: true
+ })
+ expect(code).toContain(`foo`)
+})
import { ErrorCodes } from '../../src/errors'
import { CompilerOptions } from '../../src'
-function transformWithFor(
+function parseWithForTransform(
template: string,
options: CompilerOptions = {}
): ForNode {
describe('compiler: transform v-for', () => {
test('number expression', () => {
- const forNode = transformWithFor('<span v-for="index in 5" />')
+ const forNode = parseWithForTransform('<span v-for="index in 5" />')
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
expect(forNode.valueAlias!.content).toBe('index')
})
test('value', () => {
- const forNode = transformWithFor('<span v-for="(item) in items" />')
+ const forNode = parseWithForTransform('<span v-for="(item) in items" />')
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
expect(forNode.valueAlias!.content).toBe('item')
})
test('object de-structured value', () => {
- const forNode = transformWithFor(
+ const forNode = parseWithForTransform(
'<span v-for="({ id, value }) in items" />'
)
expect(forNode.keyAlias).toBeUndefined()
})
test('array de-structured value', () => {
- const forNode = transformWithFor(
+ const forNode = parseWithForTransform(
'<span v-for="([ id, value ]) in items" />'
)
expect(forNode.keyAlias).toBeUndefined()
})
test('value and key', () => {
- const forNode = transformWithFor('<span v-for="(item, key) in items" />')
+ const forNode = parseWithForTransform(
+ '<span v-for="(item, key) in items" />'
+ )
expect(forNode.keyAlias).not.toBeUndefined()
expect(forNode.keyAlias!.content).toBe('key')
expect(forNode.objectIndexAlias).toBeUndefined()
})
test('value, key and index', () => {
- const forNode = transformWithFor(
+ const forNode = parseWithForTransform(
'<span v-for="(value, key, index) in items" />'
)
expect(forNode.keyAlias).not.toBeUndefined()
})
test('skipped key', () => {
- const forNode = transformWithFor('<span v-for="(value,,index) in items" />')
+ const forNode = parseWithForTransform(
+ '<span v-for="(value,,index) in items" />'
+ )
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect(forNode.objectIndexAlias!.content).toBe('index')
})
test('skipped value and key', () => {
- const forNode = transformWithFor('<span v-for="(,,index) in items" />')
+ const forNode = parseWithForTransform('<span v-for="(,,index) in items" />')
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect(forNode.objectIndexAlias!.content).toBe('index')
})
test('unbracketed value', () => {
- const forNode = transformWithFor('<span v-for="item in items" />')
+ const forNode = parseWithForTransform('<span v-for="item in items" />')
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).toBeUndefined()
expect(forNode.valueAlias!.content).toBe('item')
})
test('unbracketed value and key', () => {
- const forNode = transformWithFor('<span v-for="item, key in items" />')
+ const forNode = parseWithForTransform('<span v-for="item, key in items" />')
expect(forNode.keyAlias).not.toBeUndefined()
expect(forNode.keyAlias!.content).toBe('key')
expect(forNode.objectIndexAlias).toBeUndefined()
})
test('unbracketed value, key and index', () => {
- const forNode = transformWithFor(
+ const forNode = parseWithForTransform(
'<span v-for="value, key, index in items" />'
)
expect(forNode.keyAlias).not.toBeUndefined()
})
test('unbracketed skipped key', () => {
- const forNode = transformWithFor('<span v-for="value, , index in items" />')
+ const forNode = parseWithForTransform(
+ '<span v-for="value, , index in items" />'
+ )
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect(forNode.objectIndexAlias!.content).toBe('index')
})
test('unbracketed skipped value and key', () => {
- const forNode = transformWithFor('<span v-for=", , index in items" />')
+ const forNode = parseWithForTransform('<span v-for=", , index in items" />')
expect(forNode.keyAlias).toBeUndefined()
expect(forNode.objectIndexAlias).not.toBeUndefined()
expect(forNode.objectIndexAlias!.content).toBe('index')
test('missing expression', () => {
const onError = jest.fn()
- transformWithFor('<span v-for />', { onError })
+ parseWithForTransform('<span v-for />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
test('empty expression', () => {
const onError = jest.fn()
- transformWithFor('<span v-for="" />', { onError })
+ parseWithForTransform('<span v-for="" />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
test('invalid expression', () => {
const onError = jest.fn()
- transformWithFor('<span v-for="items" />', { onError })
+ parseWithForTransform('<span v-for="items" />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
test('missing source', () => {
const onError = jest.fn()
- transformWithFor('<span v-for="item in" />', { onError })
+ parseWithForTransform('<span v-for="item in" />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
test('missing value', () => {
const onError = jest.fn()
- transformWithFor('<span v-for="in items" />', { onError })
+ parseWithForTransform('<span v-for="in items" />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
describe('source location', () => {
test('value & source', () => {
const source = '<span v-for="item in items" />'
- const forNode = transformWithFor(source)
+ const forNode = parseWithForTransform(source)
expect(forNode.valueAlias!.content).toBe('item')
expect(forNode.valueAlias!.loc.start.offset).toBe(
test('bracketed value', () => {
const source = '<span v-for="( item ) in items" />'
- const forNode = transformWithFor(source)
+ const forNode = parseWithForTransform(source)
expect(forNode.valueAlias!.content).toBe('item')
expect(forNode.valueAlias!.loc.start.offset).toBe(
test('de-structured value', () => {
const source = '<span v-for="( { id, key })in items" />'
- const forNode = transformWithFor(source)
+ const forNode = parseWithForTransform(source)
expect(forNode.valueAlias!.content).toBe('{ id, key }')
expect(forNode.valueAlias!.loc.start.offset).toBe(
test('bracketed value, key, index', () => {
const source = '<span v-for="( item, key, index ) in items" />'
- const forNode = transformWithFor(source)
+ const forNode = parseWithForTransform(source)
expect(forNode.valueAlias!.content).toBe('item')
expect(forNode.valueAlias!.loc.start.offset).toBe(
test('skipped key', () => {
const source = '<span v-for="( item,, index ) in items" />'
- const forNode = transformWithFor(source)
+ const forNode = parseWithForTransform(source)
expect(forNode.valueAlias!.content).toBe('item')
expect(forNode.valueAlias!.loc.start.offset).toBe(
import { ErrorCodes } from '../../src/errors'
import { CompilerOptions } from '../../src'
-function transformWithIf(
+function parseWithIfTransform(
template: string,
options: CompilerOptions = {},
returnIndex: number = 0
describe('compiler: transform v-if', () => {
test('basic v-if', () => {
- const node = transformWithIf(`<div v-if="ok"/>`)
+ const node = parseWithIfTransform(`<div v-if="ok"/>`)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(1)
expect(node.branches[0].condition!.content).toBe(`ok`)
})
test('template v-if', () => {
- const node = transformWithIf(
+ const node = parseWithIfTransform(
`<template v-if="ok"><div/>hello<p/></template>`
)
expect(node.type).toBe(NodeTypes.IF)
})
test('v-if + v-else', () => {
- const node = transformWithIf(`<div v-if="ok"/><p v-else/>`)
+ const node = parseWithIfTransform(`<div v-if="ok"/><p v-else/>`)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(2)
})
test('v-if + v-else-if', () => {
- const node = transformWithIf(`<div v-if="ok"/><p v-else-if="orNot"/>`)
+ const node = parseWithIfTransform(`<div v-if="ok"/><p v-else-if="orNot"/>`)
expect(node.type).toBe(NodeTypes.IF)
expect(node.branches.length).toBe(2)
})
test('v-if + v-else-if + v-else', () => {
- const node = transformWithIf(
+ const node = parseWithIfTransform(
`<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`
)
expect(node.type).toBe(NodeTypes.IF)
})
test('comment between branches', () => {
- const node = transformWithIf(`
+ const node = parseWithIfTransform(`
<div v-if="ok"/>
<!--foo-->
<p v-else-if="orNot"/>
test('error on v-else missing adjacent v-if', () => {
const onError = jest.fn()
- const node1 = transformWithIf(`<div v-else/>`, { onError })
+ const node1 = parseWithIfTransform(`<div v-else/>`, { onError })
expect(onError.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
}
])
- const node2 = transformWithIf(`<div/><div v-else/>`, { onError }, 1)
+ const node2 = parseWithIfTransform(`<div/><div v-else/>`, { onError }, 1)
expect(onError.mock.calls[1]).toMatchObject([
{
code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
}
])
- const node3 = transformWithIf(`<div/>foo<div v-else/>`, { onError }, 2)
+ const node3 = parseWithIfTransform(`<div/>foo<div v-else/>`, { onError }, 2)
expect(onError.mock.calls[2]).toMatchObject([
{
code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
test('error on v-else-if missing adjacent v-if', () => {
const onError = jest.fn()
- const node1 = transformWithIf(`<div v-else-if="foo"/>`, { onError })
+ const node1 = parseWithIfTransform(`<div v-else-if="foo"/>`, { onError })
expect(onError.mock.calls[0]).toMatchObject([
{
code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
}
])
- const node2 = transformWithIf(
+ const node2 = parseWithIfTransform(
`<div/><div v-else-if="foo"/>`,
{ onError },
1
}
])
- const node3 = transformWithIf(
+ const node3 = parseWithIfTransform(
`<div/>foo<div v-else-if="foo"/>`,
{ onError },
2
if (!prefixIdentifiers) {
push(`with (this) {`)
indent()
+ } else {
+ push(`const _ctx = this`)
+ newline()
}
push(`return `)
genChildren(ast.children, context, true /* asRoot */)
import { isString } from '@vue/shared'
import { transformIf } from './transforms/vIf'
import { transformFor } from './transforms/vFor'
-import { prepareElementForCodegen } from './transforms/element'
+import { transformElement } from './transforms/transformElement'
import { transformOn } from './transforms/vOn'
import { transformBind } from './transforms/vBind'
-import { expressionTransform } from './transforms/expression'
+import { transformExpression } from './transforms/transformExpression'
import { defaultOnError, createCompilerError, ErrorCodes } from './errors'
export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions
nodeTransforms: [
transformIf,
transformFor,
- ...(prefixIdentifiers ? [expressionTransform] : []),
- prepareElementForCodegen,
+ ...(prefixIdentifiers ? [transformExpression] : []),
+ transformElement,
...(options.nodeTransforms || []) // user transforms
],
directiveTransforms: {
export * from './ast'
// debug
-export { prepareElementForCodegen } from './transforms/element'
+export {
+ transformElement as prepareElementForCodegen
+} from './transforms/transformElement'
export const RENDER_LIST = `renderList`
export const CAPITALIZE = `capitalize`
export const TO_STRING = `toString`
+export const MERGE_PROPS = `mergeProps`
CREATE_VNODE,
APPLY_DIRECTIVES,
RESOLVE_DIRECTIVE,
- RESOLVE_COMPONENT
+ RESOLVE_COMPONENT,
+ MERGE_PROPS
} from '../runtimeConstants'
const toValidId = (str: string): string => str.replace(/[^\w]/g, '')
// generate a JavaScript AST for this element's codegen
-export const prepareElementForCodegen: NodeTransform = (node, context) => {
+export const transformElement: NodeTransform = (node, context) => {
if (node.type === NodeTypes.ELEMENT) {
if (
node.tagType === ElementTypes.ELEMENT ||
} else if (node.tagType === ElementTypes.SLOT) {
// <slot [name="xxx"]/>
// TODO
- } else if (node.tagType === ElementTypes.TEMPLATE) {
- // do nothing
}
+ // node.tagType can also be TEMPLATE, in which case nothing needs to be done
}
}
{ loc, props }: ElementNode,
context: TransformContext
): {
- props: ObjectExpression | CallExpression
+ props: ObjectExpression | CallExpression | ExpressionNode
directives: DirectiveNode[]
} {
let properties: ObjectExpression['properties'] = []
}
}
- let ret: ObjectExpression | CallExpression
+ let ret: ObjectExpression | CallExpression | ExpressionNode
// has v-bind="object", wrap with mergeProps
if (mergeArgs.length) {
mergeArgs.push(createObjectExpression(properties, loc))
}
if (mergeArgs.length > 1) {
- ret = createCallExpression(`mergeProps`, mergeArgs, loc)
+ context.imports.add(MERGE_PROPS)
+ ret = createCallExpression(MERGE_PROPS, mergeArgs, loc)
} else {
// single v-bind with nothing else - no need for a mergeProps call
- ret = createObjectExpression(properties, loc)
+ ret = mergeArgs[0]
}
} else {
ret = createObjectExpression(properties, loc)
import { Node, Function, Identifier } from 'estree'
import { advancePositionWithClone } from '../utils'
-export const expressionTransform: NodeTransform = (node, context) => {
+export const transformExpression: NodeTransform = (node, context) => {
if (node.type === NodeTypes.EXPRESSION && !node.isStatic) {
processExpression(node, context)
} else if (node.type === NodeTypes.ELEMENT) {
import { createCompilerError, ErrorCodes } from '../errors'
import { getInnerRange } from '../utils'
import { RENDER_LIST } from '../runtimeConstants'
-import { processExpression } from './expression'
+import { processExpression } from './transformExpression'
const forAliasRE = /([\s\S]*?)(?:(?<=\))|\s+)(?:in|of)\s+([\s\S]*)/
const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/
IfBranchNode
} from '../ast'
import { createCompilerError, ErrorCodes } from '../errors'
-import { processExpression } from './expression'
+import { processExpression } from './transformExpression'
export const transformIf = createStructuralDirectiveTransform(
/^(if|else|else-if)$/,