11function Plugin ( babel ) {
22 const t = babel . types ;
3+ function markTailCall ( retStmt ) {
4+ if ( retStmt . argument === null ) return ;
5+ if ( retStmt . argument . type === "CallExpression" ) {
6+ retStmt . argument . isTailCall = true ;
7+ } else if ( retStmt . argument . type === "SequenceExpression" && retStmt . argument . expressions . length > 0 ) {
8+ const lastExp = retStmt . argument . expressions [ retStmt . argument . expressions . length - 1 ] ;
9+ if ( lastExp . type !== "CallExpression" ) return ;
10+ lastExp . isTailCall = true ;
11+ }
12+ }
313 // Function call without arguments
414 function hzCall ( callee ) {
515 return t . sequenceExpression ( [
@@ -190,7 +200,7 @@ function Plugin(babel) {
190200 t . variableDeclarator (
191201 funcDec . id ,
192202 hzCoroutine ( t . functionExpression (
193- funcDec . id ,
203+ null ,
194204 funcDec . params ,
195205 funcDec . body ,
196206 true
@@ -204,7 +214,7 @@ function Plugin(babel) {
204214 t . variableDeclarator (
205215 funcDec . id ,
206216 hzGenerator ( t . functionExpression (
207- funcDec . id ,
217+ null ,
208218 funcDec . params ,
209219 funcDec . body ,
210220 true
@@ -346,6 +356,7 @@ function Plugin(babel) {
346356 } ,
347357 exit : function ( path ) {
348358 //if (path.getFunctionParent().type === "Program") return;
359+ const isTailCall = "isTailCall" in path . node ;
349360 if ( path . node . callee . type === "MemberExpression" ) {
350361 if ( path . node . arguments . length === 0 ) {
351362 path . replaceWith ( hzCallMethod (
@@ -371,10 +382,16 @@ function Plugin(babel) {
371382 ) ) ;
372383 }
373384 }
385+ if ( isTailCall ) {
386+ path . node . expressions [ 0 ] . argument . arguments . push ( t . booleanLiteral ( true ) ) ;
387+ }
374388 path . skip ( ) ;
375389 }
376390 } ,
377391 "ReturnStatement" : {
392+ enter : function ( path ) {
393+ markTailCall ( path . node ) ;
394+ } ,
378395 exit : function ( path ) {
379396 const parentPath = path . getFunctionParent ( ) ;
380397 if ( path . node . argument === null ) path . node . argument = hzReturn ( ) ;
0 commit comments