diff --git a/packages/compiler-core/__tests__/codegen.spec.ts b/packages/compiler-core/__tests__/codegen.spec.ts index ef202ef2..6a746f21 100644 --- a/packages/compiler-core/__tests__/codegen.spec.ts +++ b/packages/compiler-core/__tests__/codegen.spec.ts @@ -14,7 +14,10 @@ import { createConditionalExpression, IfCodegenNode, ForCodegenNode, - createCacheExpression + createCacheExpression, + createTemplateLiteral, + createBlockStatement, + createIfStatement } from '../src' import { CREATE_VNODE, @@ -407,4 +410,133 @@ describe('compiler: codegen', () => { ) expect(code).toMatchSnapshot() }) + + test('TemplateLiteral', () => { + const { code } = generate( + createRoot({ + codegenNode: createCallExpression(`_push`, [ + createTemplateLiteral([ + `foo`, + createCallExpression(`_renderAttr`, ['id', 'foo']), + `bar` + ]) + ]) + }), + { ssr: true, mode: 'module' } + ) + expect(code).toMatchInlineSnapshot(` + " + export function ssrRender(_ctx, _push, _parent) { + _push(\`foo\${_renderAttr(id, foo)}bar\`) + }" + `) + }) + + describe('IfStatement', () => { + test('if', () => { + const { code } = generate( + createRoot({ + codegenNode: createBlockStatement([ + createIfStatement( + createSimpleExpression('foo', false), + createBlockStatement([createCallExpression(`ok`)]) + ) + ]) + }), + { ssr: true, mode: 'module' } + ) + expect(code).toMatchInlineSnapshot(` + " + export function ssrRender(_ctx, _push, _parent) { + if (foo) { + ok() + } + }" + `) + }) + + test('if/else', () => { + const { code } = generate( + createRoot({ + codegenNode: createBlockStatement([ + createIfStatement( + createSimpleExpression('foo', false), + createBlockStatement([createCallExpression(`foo`)]), + createBlockStatement([createCallExpression('bar')]) + ) + ]) + }), + { ssr: true, mode: 'module' } + ) + expect(code).toMatchInlineSnapshot(` + " + export function ssrRender(_ctx, _push, _parent) { + if (foo) { + foo() + } else { + bar() + } + }" + `) + }) + + test('if/else-if', () => { + const { code } = generate( + createRoot({ + codegenNode: createBlockStatement([ + createIfStatement( + createSimpleExpression('foo', false), + createBlockStatement([createCallExpression(`foo`)]), + createIfStatement( + createSimpleExpression('bar', false), + createBlockStatement([createCallExpression(`bar`)]) + ) + ) + ]) + }), + { ssr: true, mode: 'module' } + ) + expect(code).toMatchInlineSnapshot(` + " + export function ssrRender(_ctx, _push, _parent) { + if (foo) { + foo() + } else if (bar) { + bar() + } + }" + `) + }) + + test('if/else-if/else', () => { + const { code } = generate( + createRoot({ + codegenNode: createBlockStatement([ + createIfStatement( + createSimpleExpression('foo', false), + createBlockStatement([createCallExpression(`foo`)]), + createIfStatement( + createSimpleExpression('bar', false), + createBlockStatement([createCallExpression(`bar`)]), + createBlockStatement([createCallExpression('baz')]) + ) + ) + ]) + }), + { ssr: true, mode: 'module' } + ) + expect(code).toMatchInlineSnapshot(` + " + export function ssrRender(_ctx, _push, _parent) { + if (foo) { + foo() + } else if (bar) { + bar() + } else { + baz() + } + }" + `) + }) + }) }) diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index 058d78b1..73efd832 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -329,7 +329,7 @@ export interface IfStatement extends Node { type: NodeTypes.JS_IF_STATEMENT test: ExpressionNode consequent: BlockStatement - alternate: IfStatement | BlockStatement + alternate: IfStatement | BlockStatement | undefined } // Codegen Node Types ---------------------------------------------------------- @@ -671,6 +671,16 @@ export function createCacheExpression( } } +export function createBlockStatement( + body: BlockStatement['body'] +): BlockStatement { + return { + type: NodeTypes.JS_BLOCK_STATEMENT, + body, + loc: locStub + } +} + export function createTemplateLiteral( elements: TemplateLiteral['elements'] ): TemplateLiteral { @@ -680,3 +690,17 @@ export function createTemplateLiteral( loc: locStub } } + +export function createIfStatement( + test: IfStatement['test'], + consequent: IfStatement['consequent'], + alternate?: IfStatement['alternate'] +): IfStatement { + return { + type: NodeTypes.JS_IF_STATEMENT, + test, + consequent, + alternate, + loc: locStub + } +} diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index adfc4587..245e33b0 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -20,7 +20,8 @@ import { CacheExpression, locStub, SSRCodegenNode, - TemplateLiteral + TemplateLiteral, + IfStatement } from './ast' import { SourceMapGenerator, RawSourceMap } from 'source-map' import { @@ -489,7 +490,7 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) { !__BROWSER__ && genTemplateLiteral(node, context) break case NodeTypes.JS_IF_STATEMENT: - // TODO + !__BROWSER__ && genIfStatement(node, context) break /* istanbul ignore next */ @@ -731,3 +732,27 @@ function genTemplateLiteral(node: TemplateLiteral, context: CodegenContext) { } push('`') } + +function genIfStatement(node: IfStatement, context: CodegenContext) { + const { push, indent, deindent } = context + const { test, consequent, alternate } = node + push(`if (`) + genNode(test, context) + push(`) {`) + indent() + genNode(consequent, context) + deindent() + push(`}`) + if (alternate) { + push(` else `) + if (alternate.type === NodeTypes.JS_IF_STATEMENT) { + genIfStatement(alternate, context) + } else { + push(`{`) + indent() + genNode(alternate, context) + deindent() + push(`}`) + } + } +}