From: Evan You Date: Tue, 24 Sep 2019 00:45:40 +0000 (-0400) Subject: test: test transformElements X-Git-Tag: v3.0.0-alpha.0~713 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dcf476436034b3a8208274b3a70f5269e3c92e0d;p=thirdparty%2Fvuejs%2Fcore.git test: test transformElements --- diff --git a/packages/compiler-core/__tests__/transforms/element.spec.ts b/packages/compiler-core/__tests__/transforms/element.spec.ts deleted file mode 100644 index 410765602d..0000000000 --- a/packages/compiler-core/__tests__/transforms/element.spec.ts +++ /dev/null @@ -1,3 +0,0 @@ -describe('compiler: element transform', () => { - test.todo('should work') -}) diff --git a/packages/compiler-core/__tests__/transforms/expression.spec.ts b/packages/compiler-core/__tests__/transforms/expression.spec.ts deleted file mode 100644 index 9fe4e49030..0000000000 --- a/packages/compiler-core/__tests__/transforms/expression.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { SourceMapConsumer } from 'source-map' -import { compile } from '../../src' - -test(`should work`, async () => { - const { code, map } = compile(`
{{ foo }} bar
`, { - prefixIdentifiers: true - }) - console.log(code) - const consumer = await new SourceMapConsumer(map!) - const pos = consumer.originalPositionFor({ - line: 4, - column: 31 - }) - console.log(pos) -}) diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts new file mode 100644 index 0000000000..95a55227da --- /dev/null +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -0,0 +1,359 @@ +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(``) + expect(root.imports).toContain(RESOLVE_COMPONENT) + expect(root.statements[0]).toMatch(`${RESOLVE_COMPONENT}("Foo")`) + }) + + test('static props', () => { + const { node } = parseWithElementTransform(`
`) + expect(node.callee).toBe(CREATE_VNODE) + expect(node.arguments).toMatchObject([ + `"div"`, + createStaticObjectMatcher({ + id: 'foo', + class: 'bar' + }) + ]) + }) + + test('v-bind="obj"', () => { + const { root, node } = parseWithElementTransform(`
`) + // 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( + `
` + ) + 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( + `
` + ) + 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( + `
` + ) + 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(`
`, { onError }) + expect(onError.mock.calls[0]).toMatchObject([ + { + code: ErrorCodes.X_V_BIND_NO_EXPRESSION + } + ]) + }) + + test('directiveTransforms', () => { + let _dir: DirectiveNode + const { node } = parseWithElementTransform(`
`, { + 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( + `
`, + { + 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( + `
` + ) + 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') +}) diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts new file mode 100644 index 0000000000..0b68b42d7d --- /dev/null +++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts @@ -0,0 +1,8 @@ +import { compile } from '../../src' + +test(`should work`, () => { + const { code } = compile(`
{{ foo }} bar
`, { + prefixIdentifiers: true + }) + expect(code).toContain(`foo`) +}) diff --git a/packages/compiler-core/__tests__/transforms/vFor.spec.ts b/packages/compiler-core/__tests__/transforms/vFor.spec.ts index 92664e75a4..76100fbeb8 100644 --- a/packages/compiler-core/__tests__/transforms/vFor.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vFor.spec.ts @@ -5,7 +5,7 @@ import { ForNode, NodeTypes } from '../../src/ast' import { ErrorCodes } from '../../src/errors' import { CompilerOptions } from '../../src' -function transformWithFor( +function parseWithForTransform( template: string, options: CompilerOptions = {} ): ForNode { @@ -20,7 +20,7 @@ function transformWithFor( describe('compiler: transform v-for', () => { test('number expression', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform('') expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).toBeUndefined() expect(forNode.valueAlias!.content).toBe('index') @@ -28,7 +28,7 @@ describe('compiler: transform v-for', () => { }) test('value', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform('') expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).toBeUndefined() expect(forNode.valueAlias!.content).toBe('item') @@ -36,7 +36,7 @@ describe('compiler: transform v-for', () => { }) test('object de-structured value', () => { - const forNode = transformWithFor( + const forNode = parseWithForTransform( '' ) expect(forNode.keyAlias).toBeUndefined() @@ -46,7 +46,7 @@ describe('compiler: transform v-for', () => { }) test('array de-structured value', () => { - const forNode = transformWithFor( + const forNode = parseWithForTransform( '' ) expect(forNode.keyAlias).toBeUndefined() @@ -56,7 +56,9 @@ describe('compiler: transform v-for', () => { }) test('value and key', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform( + '' + ) expect(forNode.keyAlias).not.toBeUndefined() expect(forNode.keyAlias!.content).toBe('key') expect(forNode.objectIndexAlias).toBeUndefined() @@ -65,7 +67,7 @@ describe('compiler: transform v-for', () => { }) test('value, key and index', () => { - const forNode = transformWithFor( + const forNode = parseWithForTransform( '' ) expect(forNode.keyAlias).not.toBeUndefined() @@ -77,7 +79,9 @@ describe('compiler: transform v-for', () => { }) test('skipped key', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform( + '' + ) expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).not.toBeUndefined() expect(forNode.objectIndexAlias!.content).toBe('index') @@ -86,7 +90,7 @@ describe('compiler: transform v-for', () => { }) test('skipped value and key', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform('') expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).not.toBeUndefined() expect(forNode.objectIndexAlias!.content).toBe('index') @@ -95,7 +99,7 @@ describe('compiler: transform v-for', () => { }) test('unbracketed value', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform('') expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).toBeUndefined() expect(forNode.valueAlias!.content).toBe('item') @@ -103,7 +107,7 @@ describe('compiler: transform v-for', () => { }) test('unbracketed value and key', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform('') expect(forNode.keyAlias).not.toBeUndefined() expect(forNode.keyAlias!.content).toBe('key') expect(forNode.objectIndexAlias).toBeUndefined() @@ -112,7 +116,7 @@ describe('compiler: transform v-for', () => { }) test('unbracketed value, key and index', () => { - const forNode = transformWithFor( + const forNode = parseWithForTransform( '' ) expect(forNode.keyAlias).not.toBeUndefined() @@ -124,7 +128,9 @@ describe('compiler: transform v-for', () => { }) test('unbracketed skipped key', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform( + '' + ) expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).not.toBeUndefined() expect(forNode.objectIndexAlias!.content).toBe('index') @@ -133,7 +139,7 @@ describe('compiler: transform v-for', () => { }) test('unbracketed skipped value and key', () => { - const forNode = transformWithFor('') + const forNode = parseWithForTransform('') expect(forNode.keyAlias).toBeUndefined() expect(forNode.objectIndexAlias).not.toBeUndefined() expect(forNode.objectIndexAlias!.content).toBe('index') @@ -143,7 +149,7 @@ describe('compiler: transform v-for', () => { test('missing expression', () => { const onError = jest.fn() - transformWithFor('', { onError }) + parseWithForTransform('', { onError }) expect(onError).toHaveBeenCalledTimes(1) expect(onError).toHaveBeenCalledWith( @@ -155,7 +161,7 @@ describe('compiler: transform v-for', () => { test('empty expression', () => { const onError = jest.fn() - transformWithFor('', { onError }) + parseWithForTransform('', { onError }) expect(onError).toHaveBeenCalledTimes(1) expect(onError).toHaveBeenCalledWith( @@ -167,7 +173,7 @@ describe('compiler: transform v-for', () => { test('invalid expression', () => { const onError = jest.fn() - transformWithFor('', { onError }) + parseWithForTransform('', { onError }) expect(onError).toHaveBeenCalledTimes(1) expect(onError).toHaveBeenCalledWith( @@ -179,7 +185,7 @@ describe('compiler: transform v-for', () => { test('missing source', () => { const onError = jest.fn() - transformWithFor('', { onError }) + parseWithForTransform('', { onError }) expect(onError).toHaveBeenCalledTimes(1) expect(onError).toHaveBeenCalledWith( @@ -191,7 +197,7 @@ describe('compiler: transform v-for', () => { test('missing value', () => { const onError = jest.fn() - transformWithFor('', { onError }) + parseWithForTransform('', { onError }) expect(onError).toHaveBeenCalledTimes(1) expect(onError).toHaveBeenCalledWith( @@ -204,7 +210,7 @@ describe('compiler: transform v-for', () => { describe('source location', () => { test('value & source', () => { const source = '' - const forNode = transformWithFor(source) + const forNode = parseWithForTransform(source) expect(forNode.valueAlias!.content).toBe('item') expect(forNode.valueAlias!.loc.start.offset).toBe( @@ -227,7 +233,7 @@ describe('compiler: transform v-for', () => { test('bracketed value', () => { const source = '' - const forNode = transformWithFor(source) + const forNode = parseWithForTransform(source) expect(forNode.valueAlias!.content).toBe('item') expect(forNode.valueAlias!.loc.start.offset).toBe( @@ -250,7 +256,7 @@ describe('compiler: transform v-for', () => { test('de-structured value', () => { const source = '' - const forNode = transformWithFor(source) + const forNode = parseWithForTransform(source) expect(forNode.valueAlias!.content).toBe('{ id, key }') expect(forNode.valueAlias!.loc.start.offset).toBe( @@ -275,7 +281,7 @@ describe('compiler: transform v-for', () => { test('bracketed value, key, index', () => { const source = '' - const forNode = transformWithFor(source) + const forNode = parseWithForTransform(source) expect(forNode.valueAlias!.content).toBe('item') expect(forNode.valueAlias!.loc.start.offset).toBe( @@ -318,7 +324,7 @@ describe('compiler: transform v-for', () => { test('skipped key', () => { const source = '' - const forNode = transformWithFor(source) + const forNode = parseWithForTransform(source) expect(forNode.valueAlias!.content).toBe('item') expect(forNode.valueAlias!.loc.start.offset).toBe( diff --git a/packages/compiler-core/__tests__/transforms/vIf.spec.ts b/packages/compiler-core/__tests__/transforms/vIf.spec.ts index aa56d175a8..a9da468896 100644 --- a/packages/compiler-core/__tests__/transforms/vIf.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vIf.spec.ts @@ -11,7 +11,7 @@ import { import { ErrorCodes } from '../../src/errors' import { CompilerOptions } from '../../src' -function transformWithIf( +function parseWithIfTransform( template: string, options: CompilerOptions = {}, returnIndex: number = 0 @@ -27,7 +27,7 @@ function transformWithIf( describe('compiler: transform v-if', () => { test('basic v-if', () => { - const node = transformWithIf(`
`) + const node = parseWithIfTransform(`
`) expect(node.type).toBe(NodeTypes.IF) expect(node.branches.length).toBe(1) expect(node.branches[0].condition!.content).toBe(`ok`) @@ -37,7 +37,7 @@ describe('compiler: transform v-if', () => { }) test('template v-if', () => { - const node = transformWithIf( + const node = parseWithIfTransform( `` ) expect(node.type).toBe(NodeTypes.IF) @@ -53,7 +53,7 @@ describe('compiler: transform v-if', () => { }) test('v-if + v-else', () => { - const node = transformWithIf(`

`) + const node = parseWithIfTransform(`

`) expect(node.type).toBe(NodeTypes.IF) expect(node.branches.length).toBe(2) @@ -71,7 +71,7 @@ describe('compiler: transform v-if', () => { }) test('v-if + v-else-if', () => { - const node = transformWithIf(`

`) + const node = parseWithIfTransform(`

`) expect(node.type).toBe(NodeTypes.IF) expect(node.branches.length).toBe(2) @@ -89,7 +89,7 @@ describe('compiler: transform v-if', () => { }) test('v-if + v-else-if + v-else', () => { - const node = transformWithIf( + const node = parseWithIfTransform( `

` ) expect(node.type).toBe(NodeTypes.IF) @@ -115,7 +115,7 @@ describe('compiler: transform v-if', () => { }) test('comment between branches', () => { - const node = transformWithIf(` + const node = parseWithIfTransform(`

@@ -151,7 +151,7 @@ describe('compiler: transform v-if', () => { test('error on v-else missing adjacent v-if', () => { const onError = jest.fn() - const node1 = transformWithIf(`

`, { onError }) + const node1 = parseWithIfTransform(`
`, { onError }) expect(onError.mock.calls[0]).toMatchObject([ { code: ErrorCodes.X_ELSE_NO_ADJACENT_IF, @@ -159,7 +159,7 @@ describe('compiler: transform v-if', () => { } ]) - const node2 = transformWithIf(`
`, { onError }, 1) + const node2 = parseWithIfTransform(`
`, { onError }, 1) expect(onError.mock.calls[1]).toMatchObject([ { code: ErrorCodes.X_ELSE_NO_ADJACENT_IF, @@ -167,7 +167,7 @@ describe('compiler: transform v-if', () => { } ]) - const node3 = transformWithIf(`
foo
`, { onError }, 2) + const node3 = parseWithIfTransform(`
foo
`, { onError }, 2) expect(onError.mock.calls[2]).toMatchObject([ { code: ErrorCodes.X_ELSE_NO_ADJACENT_IF, @@ -179,7 +179,7 @@ describe('compiler: transform v-if', () => { test('error on v-else-if missing adjacent v-if', () => { const onError = jest.fn() - const node1 = transformWithIf(`
`, { onError }) + const node1 = parseWithIfTransform(`
`, { onError }) expect(onError.mock.calls[0]).toMatchObject([ { code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF, @@ -187,7 +187,7 @@ describe('compiler: transform v-if', () => { } ]) - const node2 = transformWithIf( + const node2 = parseWithIfTransform( `
`, { onError }, 1 @@ -199,7 +199,7 @@ describe('compiler: transform v-if', () => { } ]) - const node3 = transformWithIf( + const node3 = parseWithIfTransform( `
foo
`, { onError }, 2 diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 3b3e547869..0259c3bbf4 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -147,6 +147,9 @@ export function generate( if (!prefixIdentifiers) { push(`with (this) {`) indent() + } else { + push(`const _ctx = this`) + newline() } push(`return `) genChildren(ast.children, context, true /* asRoot */) diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts index 7b0a95decb..127b29c251 100644 --- a/packages/compiler-core/src/index.ts +++ b/packages/compiler-core/src/index.ts @@ -5,10 +5,10 @@ import { RootNode } from './ast' 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 @@ -32,8 +32,8 @@ export function compile( nodeTransforms: [ transformIf, transformFor, - ...(prefixIdentifiers ? [expressionTransform] : []), - prepareElementForCodegen, + ...(prefixIdentifiers ? [transformExpression] : []), + transformElement, ...(options.nodeTransforms || []) // user transforms ], directiveTransforms: { @@ -65,4 +65,6 @@ export { ErrorCodes, CompilerError, createCompilerError } from './errors' export * from './ast' // debug -export { prepareElementForCodegen } from './transforms/element' +export { + transformElement as prepareElementForCodegen +} from './transforms/transformElement' diff --git a/packages/compiler-core/src/runtimeConstants.ts b/packages/compiler-core/src/runtimeConstants.ts index c7a393be52..bc58599568 100644 --- a/packages/compiler-core/src/runtimeConstants.ts +++ b/packages/compiler-core/src/runtimeConstants.ts @@ -7,3 +7,4 @@ export const APPLY_DIRECTIVES = `applyDirectives` export const RENDER_LIST = `renderList` export const CAPITALIZE = `capitalize` export const TO_STRING = `toString` +export const MERGE_PROPS = `mergeProps` diff --git a/packages/compiler-core/src/transforms/element.ts b/packages/compiler-core/src/transforms/transformElement.ts similarity index 93% rename from packages/compiler-core/src/transforms/element.ts rename to packages/compiler-core/src/transforms/transformElement.ts index 2c6ff252e6..fe381dedca 100644 --- a/packages/compiler-core/src/transforms/element.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -20,13 +20,14 @@ import { 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 || @@ -91,9 +92,8 @@ export const prepareElementForCodegen: NodeTransform = (node, context) => { } else if (node.tagType === ElementTypes.SLOT) { // // TODO - } else if (node.tagType === ElementTypes.TEMPLATE) { - // do nothing } + // node.tagType can also be TEMPLATE, in which case nothing needs to be done } } @@ -101,7 +101,7 @@ function buildProps( { loc, props }: ElementNode, context: TransformContext ): { - props: ObjectExpression | CallExpression + props: ObjectExpression | CallExpression | ExpressionNode directives: DirectiveNode[] } { let properties: ObjectExpression['properties'] = [] @@ -160,7 +160,7 @@ function buildProps( } } - let ret: ObjectExpression | CallExpression + let ret: ObjectExpression | CallExpression | ExpressionNode // has v-bind="object", wrap with mergeProps if (mergeArgs.length) { @@ -168,10 +168,11 @@ function buildProps( 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) diff --git a/packages/compiler-core/src/transforms/expression.ts b/packages/compiler-core/src/transforms/transformExpression.ts similarity index 98% rename from packages/compiler-core/src/transforms/expression.ts rename to packages/compiler-core/src/transforms/transformExpression.ts index 08e83b690e..adc9ee1cb3 100644 --- a/packages/compiler-core/src/transforms/expression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -15,7 +15,7 @@ import { NodeTypes, createExpression, ExpressionNode } from '../ast' 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) { diff --git a/packages/compiler-core/src/transforms/vFor.ts b/packages/compiler-core/src/transforms/vFor.ts index fdb9d7a2cd..b1cf727aac 100644 --- a/packages/compiler-core/src/transforms/vFor.ts +++ b/packages/compiler-core/src/transforms/vFor.ts @@ -11,7 +11,7 @@ import { 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 = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/ diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts index f0f5830c61..1d8fe08aaf 100644 --- a/packages/compiler-core/src/transforms/vIf.ts +++ b/packages/compiler-core/src/transforms/vIf.ts @@ -10,7 +10,7 @@ import { IfBranchNode } from '../ast' import { createCompilerError, ErrorCodes } from '../errors' -import { processExpression } from './expression' +import { processExpression } from './transformExpression' export const transformIf = createStructuralDirectiveTransform( /^(if|else|else-if)$/,