Support consts in block-scoping transform

This commit is contained in:
Amjad Masad
2015-11-10 15:55:33 -08:00
parent 4cca0abd2f
commit aa8b96bf38
3 changed files with 19 additions and 19 deletions

View File

@@ -13,9 +13,10 @@ export default function () {
visitor: {
VariableDeclaration(path, file) {
let { node, parent, scope } = path;
if (!isLet(node, parent, scope)) return;
if (!isBlockScoped(node)) return;
convertBlockScopedToVar(node, parent, scope);
if (isLetInitable(node) && node._tdzThis) {
if (node._tdzThis) {
let nodes = [node];
for (let i = 0; i < node.declarations.length; i++) {
@@ -44,7 +45,7 @@ export default function () {
let { node, parent, scope } = path;
let init = node.left || node.init;
if (isLet(init, node, scope)) {
if (isBlockScoped(init)) {
t.ensureBlock(node);
node.body._letDeclarators = [init];
}
@@ -68,13 +69,16 @@ let buildRetCheck = template(`
if (typeof RETURN === "object") return RETURN.v;
`);
function isLet(node, parent, scope) {
function isBlockScoped(node) {
if (!t.isVariableDeclaration(node)) return false;
if (node._let) return true;
if (node.kind !== "let") return false;
if (node.kind !== "let" && node.kind !== "const") return false;
return true;
}
function convertBlockScopedToVar(node, parent, scope) {
// https://github.com/babel/babel/issues/255
if (isLetInitable(node, parent)) {
if (!t.isFor(parent)) {
for (let i = 0; i < node.declarations.length; i++) {
let declar = node.declarations[i];
declar.init = declar.init || scope.buildUndefinedNode();
@@ -83,15 +87,10 @@ function isLet(node, parent, scope) {
node._let = true;
node.kind = "var";
return true;
}
function isLetInitable(node, parent) {
return !t.isFor(parent) || !t.isFor(parent, { left: node });
}
function isVar(node, parent, scope) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent, scope);
function isVar(node, parent) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isBlockScoped(node, parent);
}
function standardizeLets(declars) {
@@ -170,7 +169,7 @@ let hoistVarDeclarationsVisitor = {
let { node, parent, scope } = path;
if (path.isForStatement()) {
if (isVar(node.init, node, scope)) {
if (isVar(node.init, node)) {
let nodes = self.pushDeclar(node.init);
if (nodes.length === 1) {
node.init = nodes[0];
@@ -179,11 +178,11 @@ let hoistVarDeclarationsVisitor = {
}
}
} else if (path.isFor()) {
if (isVar(node.left, node, scope)) {
if (isVar(node.left, node)) {
self.pushDeclar(node.left);
node.left = node.left.declarations[0].id;
}
} else if (isVar(node, parent, scope)) {
} else if (isVar(node, parent)) {
path.replaceWithMultiple(self.pushDeclar(node).map(expr => t.expressionStatement(expr)));
} else if (path.isFunction()) {
return path.skip();
@@ -510,7 +509,8 @@ class BlockScoping {
if (block.body) {
for (let i = 0; i < block.body.length; i++) {
let declar = block.body[i];
if (t.isClassDeclaration(declar) || t.isFunctionDeclaration(declar) || isLet(declar, block, this.scope)) {
if (t.isClassDeclaration(declar) || t.isFunctionDeclaration(declar) || isBlockScoped(declar)) {
if (isBlockScoped(declar)) convertBlockScopedToVar(declar, block, this.scope);
declarators = declarators.concat(declar.declarations || declar);
}
}

View File

@@ -1,4 +1,4 @@
const foo = "foo";
var foo = "foo";
function foobar() {
for (var item of [1, 2, 3]) {

View File

@@ -1,4 +1,4 @@
var _loop = function _loop(i) {
var _loop = function (i) {
var l = i;
setTimeout(function () {
console.log(l);