Просмотр исходного кода

test(compiler-core): test TempalteLiteral and IfStatement codegen

Evan You 6 лет назад
Родитель
Сommit
8fd9e9ba97

+ 133 - 1
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()
+          }
+        }"
+      `)
+    })
+  })
 })

+ 25 - 1
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
+  }
+}

+ 27 - 2
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(`}`)
+    }
+  }
+}