]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler): block optimization codegen for RootNode
authorEvan You <yyx990803@gmail.com>
Wed, 2 Oct 2019 17:11:07 +0000 (13:11 -0400)
committerEvan You <yyx990803@gmail.com>
Wed, 2 Oct 2019 17:11:07 +0000 (13:11 -0400)
15 files changed:
packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap
packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
packages/compiler-core/__tests__/codegen.spec.ts
packages/compiler-core/__tests__/transforms/__snapshots__/optimizeText.spec.ts.snap
packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
packages/compiler-core/__tests__/transforms/transformElement.spec.ts
packages/compiler-core/src/ast.ts
packages/compiler-core/src/codegen.ts
packages/compiler-core/src/parse.ts
packages/compiler-core/src/transform.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-core/src/transforms/vFor.ts
packages/compiler-core/src/transforms/vSlot.ts
packages/compiler-core/src/utils.ts

index 628f352e65b2fee6cf7c863412075e0ececc2956..fa71bf319b3aa98bdbb625bee530f524368b2675 100644 (file)
@@ -4,25 +4,16 @@ exports[`compiler: codegen ConditionalExpression 1`] = `
 "
 return function render() {
   with (this) {
-    return (foo, ok
+    return ok
       ? foo()
       : orNot
         ? bar()
-        : baz())
+        : baz()
   }
 }"
 `;
 
-exports[`compiler: codegen SequenceExpression 1`] = `
-"
-return function render() {
-  with (this) {
-    return (foo, bar(baz))
-  }
-}"
-`;
-
-exports[`compiler: codegen callExpression + objectExpression + arrayExpression 1`] = `
+exports[`compiler: codegen Element (callExpression + objectExpression + arrayExpression) 1`] = `
 "
 return function render() {
   with (this) {
@@ -40,6 +31,15 @@ return function render() {
 }"
 `;
 
+exports[`compiler: codegen SequenceExpression 1`] = `
+"
+return function render() {
+  with (this) {
+    return (foo, bar(baz))
+  }
+}"
+`;
+
 exports[`compiler: codegen comment 1`] = `
 "
 return function render() {
@@ -58,6 +58,15 @@ return function render() {
 }"
 `;
 
+exports[`compiler: codegen forNode 1`] = `
+"
+return function render() {
+  with (this) {
+    return (foo, bar)
+  }
+}"
+`;
+
 exports[`compiler: codegen function mode preamble 1`] = `
 "const _Vue = Vue
 
@@ -145,28 +154,3 @@ return function render() {
   }
 }"
 `;
-
-exports[`compiler: codegen text + comment + interpolation 1`] = `
-"
-return function render() {
-  with (this) {
-    return [
-      \\"foo\\",
-      _toString(hello),
-      _createVNode(_Comment, 0, \\"foo\\")
-    ]
-  }
-}"
-`;
-
-exports[`compiler: codegen text + comment + interpolation w/ prefixIdentifiers: true 1`] = `
-"
-return function render() {
-  const _ctx = this
-  return [
-    \\"foo\\",
-    toString(hello),
-    createVNode(Comment, 0, \\"foo\\")
-  ]
-}"
-`;
index 8d7ae5dd4c98f39bf555a111c0984e0e2187ce79..c859f8b08be156c64a69c2a72b6f869f80c37af3 100644 (file)
@@ -7,7 +7,7 @@ return function render() {
   with (this) {
     const { toString: _toString, openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Empty: _Empty, Fragment: _Fragment, renderList: _renderList } = _Vue
     
-    return _createVNode(\\"div\\", {
+    return (_openBlock(), _createBlock(\\"div\\", {
       id: \\"foo\\",
       class: bar.baz
     }, [
@@ -22,7 +22,7 @@ return function render() {
           _createVNode(\\"span\\", null, _toString(value + index), 1 /* TEXT */)
         ]))
       }), 128 /* UNKEYED_FRAGMENT */))
-    ], 2 /* CLASS */)
+    ], 2 /* CLASS */))
   }
 }"
 `;
@@ -32,7 +32,7 @@ exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`
 
 return function render() {
   const _ctx = this
-  return createVNode(\\"div\\", {
+  return (openBlock(), createBlock(\\"div\\", {
     id: \\"foo\\",
     class: _ctx.bar.baz
   }, [
@@ -47,7 +47,7 @@ return function render() {
         createVNode(\\"span\\", null, toString(value + index), 1 /* TEXT */)
       ]))
     }), 128 /* UNKEYED_FRAGMENT */))
-  ], 2 /* CLASS */)
+  ], 2 /* CLASS */))
 }"
 `;
 
@@ -56,7 +56,7 @@ exports[`compiler: integration tests module mode 1`] = `
 
 export default function render() {
   const _ctx = this
-  return createVNode(\\"div\\", {
+  return (openBlock(), createBlock(\\"div\\", {
     id: \\"foo\\",
     class: _ctx.bar.baz
   }, [
@@ -71,6 +71,6 @@ export default function render() {
         createVNode(\\"span\\", null, _toString(value + index), 1 /* TEXT */)
       ]))
     }), 128 /* UNKEYED_FRAGMENT */))
-  ], 2 /* CLASS */)
+  ], 2 /* CLASS */))
 }"
 `;
index 4076be861a44ae6daeddb87cc087404a28e6a53c..307925a31b1f807e762c2fa5b93ca8916f1456d6 100644 (file)
@@ -45,6 +45,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -110,6 +111,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -175,6 +177,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -258,6 +261,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -341,6 +345,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -424,6 +429,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -507,6 +513,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -573,6 +580,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -639,6 +647,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -705,6 +714,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -771,6 +781,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -836,6 +847,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -926,6 +938,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -992,6 +1005,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1058,6 +1072,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1124,6 +1139,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1266,6 +1282,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1337,6 +1354,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1408,6 +1426,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1474,6 +1493,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1540,6 +1560,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1611,6 +1632,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1701,6 +1723,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1766,6 +1789,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1831,6 +1855,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1896,6 +1921,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -1961,6 +1987,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2026,6 +2053,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2092,6 +2120,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2158,6 +2187,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2229,6 +2259,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2300,6 +2331,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2390,6 +2422,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2480,6 +2513,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2570,6 +2604,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2677,6 +2712,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2784,6 +2820,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2891,6 +2928,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -2998,6 +3036,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3105,6 +3144,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3212,6 +3252,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3319,6 +3360,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3426,6 +3468,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3491,6 +3534,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3532,6 +3576,7 @@ Object {
       "type": 3,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3597,6 +3642,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3662,6 +3708,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3727,6 +3774,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3792,6 +3840,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3858,6 +3907,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -3940,6 +3990,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4006,6 +4057,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4089,6 +4141,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4196,6 +4249,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4286,6 +4340,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4376,6 +4431,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4423,6 +4479,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4489,6 +4546,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4555,6 +4613,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4621,6 +4680,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4765,6 +4825,7 @@ class=\\"bar\\"></div></template>",
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4908,6 +4969,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -4973,6 +5035,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5038,6 +5101,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5103,6 +5167,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5168,6 +5233,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5234,6 +5300,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5300,6 +5367,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5366,6 +5434,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5432,6 +5501,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5539,6 +5609,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5646,6 +5717,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5753,6 +5825,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5860,6 +5933,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -5967,6 +6041,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6074,6 +6149,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6181,6 +6257,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6288,6 +6365,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6378,6 +6456,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6485,6 +6564,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6550,6 +6630,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6658,6 +6739,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6724,6 +6806,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6790,6 +6873,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6855,6 +6939,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6902,6 +6987,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -6949,6 +7035,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7031,6 +7118,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7097,6 +7185,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7200,6 +7289,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7271,6 +7361,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7342,6 +7433,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7384,6 +7476,7 @@ Object {
       "type": 2,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7426,6 +7519,7 @@ Object {
       "type": 2,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7484,6 +7578,7 @@ Object {
       "type": 5,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7558,6 +7653,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7741,6 +7837,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
@@ -7943,6 +8040,7 @@ Object {
       "type": 1,
     },
   ],
+  "codegenNode": undefined,
   "hoists": Array [],
   "imports": Array [],
   "loc": Object {
index 469e6ed3a0197a8d61ff55734585e1e913843696..49311c8f31382c0d504453b60fa8cf37a4aa4ac1 100644 (file)
@@ -23,6 +23,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
     imports: [],
     statements: [],
     hoists: [],
+    codegenNode: undefined,
     loc: locStub,
     ...options
   }
@@ -103,14 +104,12 @@ describe('compiler: codegen', () => {
   test('static text', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          {
-            type: NodeTypes.TEXT,
-            content: 'hello',
-            isEmpty: false,
-            loc: locStub
-          }
-        ]
+        codegenNode: {
+          type: NodeTypes.TEXT,
+          content: 'hello',
+          isEmpty: false,
+          loc: locStub
+        }
       })
     )
     expect(code).toMatch(`return "hello"`)
@@ -120,7 +119,7 @@ describe('compiler: codegen', () => {
   test('interpolation', () => {
     const { code } = generate(
       createRoot({
-        children: [createInterpolation(`hello`, locStub)]
+        codegenNode: createInterpolation(`hello`, locStub)
       })
     )
     expect(code).toMatch(`return _${TO_STRING}(hello)`)
@@ -130,380 +129,138 @@ describe('compiler: codegen', () => {
   test('comment', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          {
-            type: NodeTypes.COMMENT,
-            content: 'foo',
-            loc: locStub
-          }
-        ]
+        codegenNode: {
+          type: NodeTypes.COMMENT,
+          content: 'foo',
+          loc: locStub
+        }
       })
     )
     expect(code).toMatch(`return _${CREATE_VNODE}(_${COMMENT}, 0, "foo")`)
     expect(code).toMatchSnapshot()
   })
 
-  test('text + comment + interpolation', () => {
+  test('compound expression', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          {
-            type: NodeTypes.TEXT,
-            content: 'foo',
-            isEmpty: false,
-            loc: locStub
-          },
-          createInterpolation(`hello`, locStub),
+        codegenNode: createCompoundExpression([
+          `_ctx.`,
+          createSimpleExpression(`foo`, false, locStub),
+          ` + `,
           {
-            type: NodeTypes.COMMENT,
-            content: 'foo',
-            loc: locStub
+            type: NodeTypes.INTERPOLATION,
+            loc: locStub,
+            content: createSimpleExpression(`bar`, false, locStub)
           }
-        ]
+        ])
       })
     )
-    expect(code).toMatch(`
-    return [
-      "foo",
-      _${TO_STRING}(hello),
-      _${CREATE_VNODE}(_${COMMENT}, 0, "foo")
-    ]`)
-    expect(code).toMatchSnapshot()
-  })
-
-  test('text + comment + interpolation w/ prefixIdentifiers: true', () => {
-    const { code } = generate(
-      createRoot({
-        children: [
-          {
-            type: NodeTypes.TEXT,
-            content: 'foo',
-            isEmpty: false,
-            loc: locStub
-          },
-          createInterpolation(`hello`, locStub),
-          {
-            type: NodeTypes.COMMENT,
-            content: 'foo',
-            loc: locStub
-          }
-        ]
-      }),
-      {
-        prefixIdentifiers: true
-      }
-    )
-    expect(code).toMatch(`
-  return [
-    "foo",
-    ${TO_STRING}(hello),
-    ${CREATE_VNODE}(${COMMENT}, 0, "foo")
-  ]`)
+    expect(code).toMatch(`return _ctx.foo + _${TO_STRING}(bar)`)
     expect(code).toMatchSnapshot()
   })
 
-  test('compound expression', () => {
+  test('ifNode', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          createCompoundExpression([
-            `_ctx.`,
-            createSimpleExpression(`foo`, false, locStub),
-            ` + `,
-            {
-              type: NodeTypes.INTERPOLATION,
-              loc: locStub,
-              content: createSimpleExpression(`bar`, false, locStub)
-            }
+        codegenNode: {
+          type: NodeTypes.IF,
+          loc: locStub,
+          branches: [],
+          codegenNode: createSequenceExpression([
+            createSimpleExpression('foo', false),
+            createSimpleExpression('bar', false)
           ])
-        ]
+        }
       })
     )
-    expect(code).toMatch(`return _ctx.foo + _${TO_STRING}(bar)`)
+    expect(code).toMatch(`return (foo, bar)`)
     expect(code).toMatchSnapshot()
   })
 
-  test('ifNode', () => {
+  test('forNode', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          {
-            type: NodeTypes.IF,
-            loc: locStub,
-            branches: [],
-            codegenNode: createSequenceExpression([
-              createSimpleExpression('foo', false),
-              createSimpleExpression('bar', false)
-            ])
-          }
-        ]
+        codegenNode: {
+          type: NodeTypes.FOR,
+          loc: locStub,
+          source: createSimpleExpression('foo', false),
+          valueAlias: undefined,
+          keyAlias: undefined,
+          objectIndexAlias: undefined,
+          children: [],
+          codegenNode: createSequenceExpression([
+            createSimpleExpression('foo', false),
+            createSimpleExpression('bar', false)
+          ])
+        }
       })
     )
     expect(code).toMatch(`return (foo, bar)`)
     expect(code).toMatchSnapshot()
   })
 
-  // test('forNode', () => {
-  //   const { code } = generate(
-  //     createRoot({
-  //       children: [
-  //         {
-  //           type: NodeTypes.FOR,
-  //           loc: locStub,
-  //           source: createSimpleExpression(`list`, false, locStub),
-  //           valueAlias: createSimpleExpression(`v`, false, locStub),
-  //           keyAlias: createSimpleExpression(`k`, false, locStub),
-  //           objectIndexAlias: createSimpleExpression(`i`, false, locStub),
-  //           children: [createInterpolation(`v`, locStub)]
-  //         }
-  //       ]
-  //     })
-  //   )
-  //   expect(code).toMatch(
-  //     `return _${RENDER_LIST}(list, (v, k, i) => {
-  //     return _${TO_STRING}(v)
-  //   })`
-  //   )
-  //   expect(code).toMatchSnapshot()
-  // })
-
-  // test('forNode w/ prefixIdentifiers: true', () => {
-  //   const { code } = generate(
-  //     createRoot({
-  //       children: [
-  //         {
-  //           type: NodeTypes.FOR,
-  //           loc: locStub,
-  //           source: createSimpleExpression(`list`, false, locStub),
-  //           valueAlias: createSimpleExpression(`v`, false, locStub),
-  //           keyAlias: createSimpleExpression(`k`, false, locStub),
-  //           objectIndexAlias: createSimpleExpression(`i`, false, locStub),
-  //           children: [createInterpolation(`v`, locStub)]
-  //         }
-  //       ]
-  //     }),
-  //     {
-  //       prefixIdentifiers: true
-  //     }
-  //   )
-  //   expect(code).toMatch(
-  //     `return ${RENDER_LIST}(list, (v, k, i) => {
-  //   return ${TO_STRING}(v)
-  // })`
-  //   )
-  //   expect(code).toMatchSnapshot()
-  // })
-
-  // test('forNode w/ skipped value alias', () => {
-  //   const { code } = generate(
-  //     createRoot({
-  //       children: [
-  //         {
-  //           type: NodeTypes.FOR,
-  //           loc: locStub,
-  //           source: createSimpleExpression(`list`, false, locStub),
-  //           valueAlias: undefined,
-  //           keyAlias: createSimpleExpression(`k`, false, locStub),
-  //           objectIndexAlias: createSimpleExpression(`i`, false, locStub),
-  //           children: [createInterpolation(`v`, locStub)]
-  //         }
-  //       ]
-  //     })
-  //   )
-  //   expect(code).toMatch(
-  //     `return _${RENDER_LIST}(list, (__value, k, i) => {
-  //     return _${TO_STRING}(v)
-  //   })`
-  //   )
-  //   expect(code).toMatchSnapshot()
-  // })
-
-  // test('forNode w/ skipped key alias', () => {
-  //   const { code } = generate(
-  //     createRoot({
-  //       children: [
-  //         {
-  //           type: NodeTypes.FOR,
-  //           loc: locStub,
-  //           source: createSimpleExpression(`list`, false, locStub),
-  //           valueAlias: createSimpleExpression(`v`, false, locStub),
-  //           keyAlias: undefined,
-  //           objectIndexAlias: createSimpleExpression(`i`, false, locStub),
-  //           children: [createInterpolation(`v`, locStub)]
-  //         }
-  //       ]
-  //     })
-  //   )
-  //   expect(code).toMatch(
-  //     `return _${RENDER_LIST}(list, (v, __key, i) => {
-  //     return _${TO_STRING}(v)
-  //   })`
-  //   )
-  //   expect(code).toMatchSnapshot()
-  // })
-
-  // test('forNode w/ skipped value and key aliases', () => {
-  //   const { code } = generate(
-  //     createRoot({
-  //       children: [
-  //         {
-  //           type: NodeTypes.FOR,
-  //           loc: locStub,
-  //           source: createSimpleExpression(`list`, false, locStub),
-  //           valueAlias: undefined,
-  //           keyAlias: undefined,
-  //           objectIndexAlias: createSimpleExpression(`i`, false, locStub),
-  //           children: [createInterpolation(`v`, locStub)]
-  //         }
-  //       ]
-  //     })
-  //   )
-  //   expect(code).toMatch(
-  //     `return _${RENDER_LIST}(list, (__value, __key, i) => {
-  //     return _${TO_STRING}(v)
-  //   })`
-  //   )
-  //   expect(code).toMatchSnapshot()
-  // })
-
-  // test('SlotFunctionExpression', () => {
-  //   const { code } = generate(
-  //     createRoot({
-  //       children: [
-  //         {
-  //           type: NodeTypes.ELEMENT,
-  //           tagType: ElementTypes.COMPONENT,
-  //           ns: Namespaces.HTML,
-  //           isSelfClosing: false,
-  //           tag: `Comp`,
-  //           loc: locStub,
-  //           props: [],
-  //           children: [],
-  //           codegenNode: {
-  //             type: NodeTypes.JS_CALL_EXPRESSION,
-  //             loc: locStub,
-  //             callee: `_${CREATE_VNODE}`,
-  //             arguments: [
-  //               `Comp`,
-  //               `0`,
-  //               {
-  //                 type: NodeTypes.JS_OBJECT_EXPRESSION,
-  //                 loc: locStub,
-  //                 properties: [
-  //                   {
-  //                     type: NodeTypes.JS_PROPERTY,
-  //                     loc: locStub,
-  //                     key: {
-  //                       type: NodeTypes.SIMPLE_EXPRESSION,
-  //                       isStatic: true,
-  //                       content: `default`,
-  //                       loc: locStub
-  //                     },
-  //                     value: {
-  //                       type: NodeTypes.JS_FUNCTION_EXPRESSION,
-  //                       loc: locStub,
-  //                       params: {
-  //                         type: NodeTypes.SIMPLE_EXPRESSION,
-  //                         isStatic: false,
-  //                         content: `{ foo }`,
-  //                         loc: locStub
-  //                       },
-  //                       returns: [
-  //                         {
-  //                           type: NodeTypes.INTERPOLATION,
-  //                           loc: locStub,
-  //                           content: {
-  //                             type: NodeTypes.SIMPLE_EXPRESSION,
-  //                             isStatic: false,
-  //                             content: `foo`,
-  //                             loc: locStub
-  //                           }
-  //                         }
-  //                       ]
-  //                     }
-  //                   }
-  //                 ]
-  //               }
-  //             ]
-  //           }
-  //         }
-  //       ]
-  //     })
-  //   )
-  //   expect(code).toMatch(
-  //     `return _createVNode(Comp, 0, {
-  //     default: ({ foo }) => [
-  //       _toString(foo)
-  //     ]
-  //   })`
-  //   )
-  //   expect(code).toMatchSnapshot()
-  // })
-
-  test('callExpression + objectExpression + arrayExpression', () => {
+  test('Element (callExpression + objectExpression + arrayExpression)', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          createElementWithCodegen([
-            // string
-            `"div"`,
-            // ObjectExpression
-            createObjectExpression(
-              [
-                createObjectProperty(
-                  createSimpleExpression(`id`, true, locStub),
-                  createSimpleExpression(`foo`, true, locStub)
-                ),
-                createObjectProperty(
-                  createSimpleExpression(`prop`, false, locStub),
-                  createSimpleExpression(`bar`, false, locStub)
-                ),
-                // compound expression as computed key
-                createObjectProperty(
-                  {
-                    type: NodeTypes.COMPOUND_EXPRESSION,
-                    loc: locStub,
-                    children: [
-                      `foo + `,
-                      createSimpleExpression(`bar`, false, locStub)
-                    ]
-                  },
-                  createSimpleExpression(`bar`, false, locStub)
-                )
-              ],
-              locStub
-            ),
-            // ChildNode[]
+        codegenNode: createElementWithCodegen([
+          // string
+          `"div"`,
+          // ObjectExpression
+          createObjectExpression(
             [
-              createElementWithCodegen([
-                `"p"`,
-                createObjectExpression(
-                  [
-                    createObjectProperty(
-                      // should quote the key!
-                      createSimpleExpression(`some-key`, true, locStub),
-                      createSimpleExpression(`foo`, true, locStub)
-                    )
-                  ],
-                  locStub
-                )
-              ])
-            ],
-            // ArrayExpression
-            createArrayExpression(
-              [
-                'foo',
+              createObjectProperty(
+                createSimpleExpression(`id`, true, locStub),
+                createSimpleExpression(`foo`, true, locStub)
+              ),
+              createObjectProperty(
+                createSimpleExpression(`prop`, false, locStub),
+                createSimpleExpression(`bar`, false, locStub)
+              ),
+              // compound expression as computed key
+              createObjectProperty(
                 {
-                  type: NodeTypes.JS_CALL_EXPRESSION,
+                  type: NodeTypes.COMPOUND_EXPRESSION,
                   loc: locStub,
-                  callee: CREATE_VNODE,
-                  arguments: [`"p"`]
-                }
-              ],
-              locStub
-            )
-          ])
-        ]
+                  children: [
+                    `foo + `,
+                    createSimpleExpression(`bar`, false, locStub)
+                  ]
+                },
+                createSimpleExpression(`bar`, false, locStub)
+              )
+            ],
+            locStub
+          ),
+          // ChildNode[]
+          [
+            createElementWithCodegen([
+              `"p"`,
+              createObjectExpression(
+                [
+                  createObjectProperty(
+                    // should quote the key!
+                    createSimpleExpression(`some-key`, true, locStub),
+                    createSimpleExpression(`foo`, true, locStub)
+                  )
+                ],
+                locStub
+              )
+            ])
+          ],
+          // ArrayExpression
+          createArrayExpression(
+            [
+              'foo',
+              {
+                type: NodeTypes.JS_CALL_EXPRESSION,
+                loc: locStub,
+                callee: CREATE_VNODE,
+                arguments: [`"p"`]
+              }
+            ],
+            locStub
+          )
+        ])
       })
     )
     expect(code).toMatch(`
@@ -523,17 +280,10 @@ describe('compiler: codegen', () => {
   test('SequenceExpression', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          {
-            type: NodeTypes.IF,
-            loc: locStub,
-            branches: [],
-            codegenNode: createSequenceExpression([
-              createSimpleExpression(`foo`, false),
-              createCallExpression(`bar`, [`baz`])
-            ])
-          }
-        ]
+        codegenNode: createSequenceExpression([
+          createSimpleExpression(`foo`, false),
+          createCallExpression(`bar`, [`baz`])
+        ])
       })
     )
     expect(code).toMatch(`return (foo, bar(baz))`)
@@ -543,33 +293,23 @@ describe('compiler: codegen', () => {
   test('ConditionalExpression', () => {
     const { code } = generate(
       createRoot({
-        children: [
-          {
-            type: NodeTypes.IF,
-            loc: locStub,
-            branches: [],
-            codegenNode: createSequenceExpression([
-              createSimpleExpression(`foo`, false),
-              createConditionalExpression(
-                createSimpleExpression(`ok`, false),
-                createCallExpression(`foo`),
-                createConditionalExpression(
-                  createSimpleExpression(`orNot`, false),
-                  createCallExpression(`bar`),
-                  createCallExpression(`baz`)
-                )
-              )
-            ])
-          }
-        ]
+        codegenNode: createConditionalExpression(
+          createSimpleExpression(`ok`, false),
+          createCallExpression(`foo`),
+          createConditionalExpression(
+            createSimpleExpression(`orNot`, false),
+            createCallExpression(`bar`),
+            createCallExpression(`baz`)
+          )
+        )
       })
     )
     expect(code).toMatch(
-      `return (foo, ok
+      `return ok
       ? foo()
       : orNot
         ? bar()
-        : baz())`
+        : baz()`
     )
     expect(code).toMatchSnapshot()
   })
index 89da629edf1e8d9875550fa95e3d684daccdf3ce..a876945f3887c5202d423962e26211caf16bb338 100644 (file)
@@ -17,13 +17,13 @@ exports[`compiler: optimize interpolation consecutive text between elements 1`]
 
 return function render() {
   with (this) {
-    const { createVNode: _createVNode, toString: _toString } = _Vue
+    const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
     
-    return [
+    return (_openBlock(), _createBlock(_Fragment, null, [
       _createVNode(\\"div\\"),
       _toString(foo) + \\" bar \\" + _toString(baz),
       _createVNode(\\"div\\")
-    ]
+    ]))
   }
 }"
 `;
@@ -33,15 +33,15 @@ exports[`compiler: optimize interpolation consecutive text mixed with elements 1
 
 return function render() {
   with (this) {
-    const { createVNode: _createVNode, toString: _toString } = _Vue
+    const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
     
-    return [
+    return (_openBlock(), _createBlock(_Fragment, null, [
       _createVNode(\\"div\\"),
       _toString(foo) + \\" bar \\" + _toString(baz),
       _createVNode(\\"div\\"),
       _toString(foo) + \\" bar \\" + _toString(baz),
       _createVNode(\\"div\\")
-    ]
+    ]))
   }
 }"
 `;
index d1810ae7ab08161f7f0fdd3d81fa98cef99efecc..a43309a54c4779e3345e059123413af6ae159179 100644 (file)
@@ -1,13 +1,13 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`compiler: transform component slots dynamically named slots 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
 
 return function render() {
   const _ctx = this
   const _component_Comp = resolveComponent(\\"Comp\\")
   
-  return createVNode(_component_Comp, null, {
+  return (openBlock(), createBlock(_component_Comp, null, {
     [_ctx.one]: ({ foo }) => [
       toString(foo),
       toString(_ctx.bar)
@@ -16,49 +16,49 @@ return function render() {
       toString(_ctx.foo),
       toString(bar)
     ]
-  }, 256 /* DYNAMIC_SLOTS */)
+  }, 256 /* DYNAMIC_SLOTS */))
 }"
 `;
 
 exports[`compiler: transform component slots explicit default slot 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
 
 return function render() {
   const _ctx = this
   const _component_Comp = resolveComponent(\\"Comp\\")
   
-  return createVNode(_component_Comp, null, {
+  return (openBlock(), createBlock(_component_Comp, null, {
     default: ({ foo }) => [
       toString(foo),
       toString(_ctx.bar)
     ]
-  })
+  }))
 }"
 `;
 
 exports[`compiler: transform component slots implicit default slot 1`] = `
-"const { createVNode, resolveComponent } = Vue
+"const { createVNode, resolveComponent, openBlock, createBlock } = Vue
 
 return function render() {
   const _ctx = this
   const _component_Comp = resolveComponent(\\"Comp\\")
   
-  return createVNode(_component_Comp, null, {
+  return (openBlock(), createBlock(_component_Comp, null, {
     default: () => [
       createVNode(\\"div\\")
     ]
-  })
+  }))
 }"
 `;
 
 exports[`compiler: transform component slots named slots 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
 
 return function render() {
   const _ctx = this
   const _component_Comp = resolveComponent(\\"Comp\\")
   
-  return createVNode(_component_Comp, null, {
+  return (openBlock(), createBlock(_component_Comp, null, {
     one: ({ foo }) => [
       toString(foo),
       toString(_ctx.bar)
@@ -67,19 +67,19 @@ return function render() {
       toString(_ctx.foo),
       toString(bar)
     ]
-  })
+  }))
 }"
 `;
 
 exports[`compiler: transform component slots nested slots scoping 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
 
 return function render() {
   const _ctx = this
   const _component_Inner = resolveComponent(\\"Inner\\")
   const _component_Comp = resolveComponent(\\"Comp\\")
   
-  return createVNode(_component_Comp, null, {
+  return (openBlock(), createBlock(_component_Comp, null, {
     default: ({ foo }) => [
       createVNode(_component_Inner, null, {
         default: ({ bar }) => [
@@ -92,6 +92,6 @@ return function render() {
       toString(_ctx.bar),
       toString(_ctx.baz)
     ]
-  })
+  }))
 }"
 `;
index f2aed954ee919f7b15b188aeacd826a701d1320c..cc2f80df6b7e6c3929ae5713c1170532dc7d65aa 100644 (file)
@@ -247,6 +247,17 @@ describe('compiler: element transform', () => {
     })
   })
 
+  test('should handle plain <template> as normal element', () => {
+    const { node } = parseWithElementTransform(`<template id="foo" />`)
+    expect(node.callee).toBe(`_${CREATE_VNODE}`)
+    expect(node.arguments).toMatchObject([
+      `"template"`,
+      createObjectMatcher({
+        id: 'foo'
+      })
+    ])
+  })
+
   test('error on v-bind with no argument', () => {
     const onError = jest.fn()
     parseWithElementTransform(`<div v-bind/>`, { onError })
index 52cda7aeacd89d4da16a2f26a5f29e4663f2561b..5dbf853ac6ce212e30ab20833a68a6e8db798006 100644 (file)
@@ -78,6 +78,7 @@ export interface RootNode extends Node {
   imports: string[]
   statements: string[]
   hoists: JSChildNode[]
+  codegenNode: TemplateChildNode | JSChildNode | undefined
 }
 
 export interface ElementNode extends Node {
index ac3950929f58281c6e0b5d366b5406f51e6a9665..143deee70ec748f1aa05833161661ca47d4babfd 100644 (file)
@@ -230,8 +230,11 @@ export function generate(
 
   // generate the VNode tree expression
   push(`return `)
-
-  genRoot(ast, context)
+  if (ast.codegenNode) {
+    genNode(ast.codegenNode, context)
+  } else {
+    push(`null`)
+  }
 
   if (useWithBlock) {
     deindent()
@@ -256,18 +259,6 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) {
   context.newline()
 }
 
-function genRoot(root: RootNode, context: CodegenContext) {
-  // TODO handle blocks
-  const { children } = root
-  if (children.length === 0) {
-    context.push(`null`)
-  } else if (children.length === 1) {
-    genNode(children[0], context)
-  } else {
-    genNodeListAsArray(children, context)
-  }
-}
-
 function genNodeListAsArray(
   nodes: (string | CodegenNode | TemplateChildNode[])[],
   context: CodegenContext
index bc4f5258ff88c2c7cd25980a8634579b4ae73da2..601a6e4fca29c728a3ec1010f95b0d54f22f8466 100644 (file)
@@ -86,6 +86,7 @@ export function parse(content: string, options: ParserOptions = {}): RootNode {
     imports: [],
     statements: [],
     hoists: [],
+    codegenNode: undefined,
     loc: getSelection(context, start)
   }
 }
index 6b8bc70cf147ca7b2bdaf9dd95e30f960a145c60..6ac73db5407e75fe3fce6566367741ec3877335b 100644 (file)
@@ -9,11 +9,13 @@ import {
   ExpressionNode,
   createSimpleExpression,
   JSChildNode,
-  SimpleExpressionNode
+  SimpleExpressionNode,
+  ElementTypes
 } from './ast'
 import { isString, isArray } from '@vue/shared'
 import { CompilerError, defaultOnError } from './errors'
-import { TO_STRING, COMMENT, CREATE_VNODE } from './runtimeConstants'
+import { TO_STRING, COMMENT, CREATE_VNODE, FRAGMENT } from './runtimeConstants'
+import { createBlockExpression } from './utils'
 
 // There are two types of transforms:
 //
@@ -182,6 +184,42 @@ function createTransformContext(
 export function transform(root: RootNode, options: TransformOptions) {
   const context = createTransformContext(root, options)
   traverseNode(root, context)
+  finalizeRoot(root, context)
+}
+
+function finalizeRoot(root: RootNode, context: TransformContext) {
+  const { helper } = context
+  const { children } = root
+  if (children.length === 1) {
+    const child = children[0]
+    if (child.type === NodeTypes.ELEMENT && child.codegenNode) {
+      // only child is a <slot/> - it needs to be in a fragment block.
+      if (child.tagType === ElementTypes.SLOT) {
+        root.codegenNode = createBlockExpression(
+          [helper(FRAGMENT), `null`, child.codegenNode],
+          context
+        )
+      } else {
+        // turn root element into a block
+        root.codegenNode = createBlockExpression(
+          child.codegenNode.arguments,
+          context
+        )
+      }
+    } else {
+      // IfNode, ForNode, TextNodes or transform calls without transformElement.
+      // Just generate the node as-is
+      root.codegenNode = child
+    }
+  } else if (children.length > 1) {
+    // root has multiple nodes - return a fragment block.
+    root.codegenNode = createBlockExpression(
+      [helper(FRAGMENT), `null`, root.children],
+      context
+    )
+  }
+
+  // finalize meta information
   root.imports = [...context.imports]
   root.statements = [...context.statements]
   root.hoists = context.hoists
@@ -214,8 +252,7 @@ export function traverseNode(
   const { nodeTransforms } = context
   const exitFns = []
   for (let i = 0; i < nodeTransforms.length; i++) {
-    const plugin = nodeTransforms[i]
-    const onExit = plugin(node, context)
+    const onExit = nodeTransforms[i](node, context)
     if (onExit) {
       if (isArray(onExit)) {
         exitFns.push(...onExit)
@@ -234,9 +271,9 @@ export function traverseNode(
 
   switch (node.type) {
     case NodeTypes.COMMENT:
-      context.helper(CREATE_VNODE)
       // inject import for the Comment symbol, which is needed for creating
       // comment nodes with `createVNode`
+      context.helper(CREATE_VNODE)
       context.helper(COMMENT)
       break
     case NodeTypes.INTERPOLATION:
index 70733b3f88719ee349a6508f757b0dc6c0dc9aa0..121e0fbc368d3c4316fceeee84e18dcadb02bcea 100644 (file)
@@ -27,7 +27,7 @@ import {
   TO_HANDLERS
 } from '../runtimeConstants'
 import { getInnerRange } from '../utils'
-import { buildSlots } from './vSlot'
+import { buildSlots, isVSlot } from './vSlot'
 
 const toValidId = (str: string): string => str.replace(/[^\w]/g, '')
 
@@ -36,7 +36,10 @@ export const transformElement: NodeTransform = (node, context) => {
   if (node.type === NodeTypes.ELEMENT) {
     if (
       node.tagType === ElementTypes.ELEMENT ||
-      node.tagType === ElementTypes.COMPONENT
+      node.tagType === ElementTypes.COMPONENT ||
+      // <template> with v-if or v-for are ignored during traversal.
+      // <template> without v-slot should be treated as a normal element.
+      (node.tagType === ElementTypes.TEMPLATE && !node.props.some(isVSlot))
     ) {
       // perform the work on exit, after all child expressions have been
       // processed and merged.
index 1abc4994eb17631a89fbf4e8ee146413b1b63b77..2a8a6ff24a4f4a3b8eddaf9f4d6a2fc2222928f5 100644 (file)
@@ -19,7 +19,7 @@ import {
   CallExpression
 } from '../ast'
 import { createCompilerError, ErrorCodes } from '../errors'
-import { getInnerRange, findProp } from '../utils'
+import { getInnerRange, findProp, createBlockExpression } from '../utils'
 import {
   RENDER_LIST,
   OPEN_BLOCK,
@@ -69,7 +69,8 @@ export const transformFor = createStructuralDirectiveTransform(
           valueAlias: value,
           keyAlias: key,
           objectIndexAlias: index,
-          children: [node],
+          children:
+            node.tagType === ElementTypes.TEMPLATE ? node.children : [node],
           codegenNode
         })
 
@@ -126,6 +127,8 @@ export const transformFor = createStructuralDirectiveTransform(
             }
             let childBlockChildren: TemplateChildNode[] | CallExpression =
               node.children
+            // if the only child is a <slot/>, use it directly as fragment
+            // children since it already returns an array.
             if (childBlockChildren.length === 1) {
               const child = childBlockChildren[0]
               if (
@@ -135,22 +138,17 @@ export const transformFor = createStructuralDirectiveTransform(
                 childBlockChildren = child.codegenNode!
               }
             }
-            childBlock = createSequenceExpression([
-              createCallExpression(helper(OPEN_BLOCK)),
-              createCallExpression(helper(CREATE_BLOCK), [
-                helper(FRAGMENT),
-                childBlockProps,
-                childBlockChildren
-              ])
-            ])
+            childBlock = createBlockExpression(
+              [helper(FRAGMENT), childBlockProps, childBlockChildren],
+              context
+            )
           } else {
-            // Normal element v-for. Directly use the child's codegenNode,
+            // Normal element v-for. Directly use the child's codegenNode arguments,
             // but replace createVNode() with createBlock()
-            node.codegenNode!.callee = helper(CREATE_BLOCK)
-            childBlock = createSequenceExpression([
-              createCallExpression(helper(OPEN_BLOCK)),
-              node.codegenNode!
-            ])
+            childBlock = createBlockExpression(
+              node.codegenNode!.arguments,
+              context
+            )
           }
 
           renderExp.arguments.push(
index 45f7f00ee0429705a3f456b3b066c540b5dbd24b..989ccce77d10d223103acb287349fecefd11a668 100644 (file)
@@ -17,7 +17,7 @@ import { TransformContext, NodeTransform } from '../transform'
 import { createCompilerError, ErrorCodes } from '../errors'
 import { isString } from '@vue/shared'
 
-const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode =>
+export const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode =>
   p.type === NodeTypes.DIRECTIVE && p.name === 'slot'
 
 // A NodeTransform that tracks scope identifiers for scoped slots so that they
index 4562932134773e6a4b99edec0e3f28f87d798c6f..23eabba02e89f882ccc28799c3bbc2f47061a073 100644 (file)
@@ -1,6 +1,17 @@
-import { SourceLocation, Position, ElementNode, NodeTypes } from './ast'
+import {
+  SourceLocation,
+  Position,
+  ElementNode,
+  NodeTypes,
+  CallExpression,
+  SequenceExpression,
+  createSequenceExpression,
+  createCallExpression
+} from './ast'
 import { parse } from 'acorn'
 import { walk } from 'estree-walker'
+import { TransformContext } from './transform'
+import { OPEN_BLOCK, CREATE_BLOCK } from './runtimeConstants'
 
 // cache node requires
 // lazy require dependencies so that they don't end up in rollup's dep graph
@@ -116,3 +127,13 @@ export function findProp(
     }
   }
 }
+
+export function createBlockExpression(
+  args: CallExpression['arguments'],
+  context: TransformContext
+): SequenceExpression {
+  return createSequenceExpression([
+    createCallExpression(context.helper(OPEN_BLOCK)),
+    createCallExpression(context.helper(CREATE_BLOCK), args)
+  ])
+}