add support for tail calls when in completion record position - fixes #1572

This commit is contained in:
Sebastian McKenzie 2015-05-31 09:07:44 +01:00
parent f642c2baa8
commit 07a992e6d3
5 changed files with 65 additions and 7 deletions

View File

@ -34,6 +34,12 @@ var visitor = {
return state.subTransform(node.argument);
},
ExpressionStatement(node, parent, scope, state) {
if (this.isCompletionRecord(true)) {
return state.subTransform(node.expression);
}
},
Function() {
this.skip();
},

View File

@ -121,17 +121,20 @@ export function isPreviousType(type: string): boolean {
* Check whether the current path references a completion record
*/
export function isCompletionRecord() {
export function isCompletionRecord(allowInsideFunction?) {
var path = this;
var first = true;
do {
var container = path.container;
// we're in a function so can't be a completion record
if (path.isFunctionDeclaration()) {
return false;
if (path.isFunction() && !first) {
return !!allowInsideFunction;
}
first = false;
// check to see if we're the last item in the container and if we are
// we're a completion record!
if (Array.isArray(container) && path.key !== container.length - 1) {

View File

@ -2,12 +2,19 @@
(function () {
var _this = this,
_arguments = arguments;
_arguments2 = arguments;
var foo = function foo() {
_this;
_arguments;
foo();
var _again = true;
_function: while (_again) {
_again = false;
_this;
_arguments2;
_again = true;
continue _function;
}
};
foo();
});

View File

@ -0,0 +1,11 @@
function skipWhile(cond) {
if (!hasNext() || cond(current, last)) return;
move();
skipWhile(cond);
}
var skipWhile2 = function (cond) {
if (!hasNext() || cond(current, last)) return;
move();
skipWhile2(cond);
};

View File

@ -0,0 +1,31 @@
"use strict";
function skipWhile(_x) {
var _again = true;
_function: while (_again) {
var cond = _x;
_again = false;
if (!hasNext() || cond(current, last)) return;
move();
_x = cond;
_again = true;
continue _function;
}
}
var skipWhile2 = function skipWhile2(_x2) {
var _again2 = true;
_function2: while (_again2) {
var cond = _x2;
_again2 = false;
if (!hasNext() || cond(current, last)) return;
move();
_x2 = cond;
_again2 = true;
continue _function2;
}
};