Skip to content

Commit

Permalink
hoist var declarations to before function definition when let block s…
Browse files Browse the repository at this point in the history
…coping
  • Loading branch information
sebmck committed Sep 29, 2014
1 parent 74f831b commit fd932e2
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 7 deletions.
1 change: 1 addition & 0 deletions lib/6to5/templates/assign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KEY = VALUE;
1 change: 1 addition & 0 deletions lib/6to5/templates/variable-declare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var KEY;
49 changes: 44 additions & 5 deletions lib/6to5/transformers/block-binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var _ = require("lodash");
var isLet = function (node) {
if (node.type === "VariableDeclaration" && node.kind === "let") {
node.kind = "var";
node._ignoreBlockBindingHoist = true;
return true;
}
};
Expand All @@ -21,7 +22,7 @@ var hasLet = function (nodes) {

exports.Program = function (node) {
if (hasLet(node.body)) {
node.body = [buildNode(node.body)];
node.body = buildNode(node.body);
}
};

Expand All @@ -31,7 +32,7 @@ exports.BlockStatement = function (node, parent) {
// ignore if we're the body of a closure already
if (parent.type === "FunctionExpression") return;

node.body = [buildNode(node.body)];
node.body = buildNode(node.body);
};

exports.ForInStatement = function (node) {
Expand All @@ -43,13 +44,47 @@ exports.ForStatement = function (node) {
};

var buildNode = function (node) {
var nodes = [];

// hoist normal variable declarations

node = [].concat(node);
node = node.map(function (node) {
if (node._ignoreBlockBindingHoist) return node;

if (node.type === "VariableDeclaration" && node.kind === "var") {
_.each(node.declarations, function (declar) {
nodes.push(util.template("variable-declare", {
KEY: declar.id
}));
});

return node.declarations.map(function (declar) {
return util.template("assign", {
KEY: declar.id,
VALUE: declar.init
}, true);
});
} else if (node.type === "ForInStatement" && !node.left._ignoreBlockBindingHoist) {
var id = node.left.declarations[0].id;
node.left = id;
nodes.push(util.template("variable-declare", {
KEY: id
}));
}

return node;
});

//

var func = {
type: "FunctionExpression",
params: [],
defaults: [],
body: {
type: "BlockStatement",
body: [].concat(node)
body: node
}
};

Expand All @@ -58,7 +93,11 @@ var buildNode = function (node) {
templateName = "function-call-this";
}

return util.template(templateName, {
//

nodes.push(util.template(templateName, {
FUNCTION: func
}, true);
}, true));

return nodes;
};
23 changes: 22 additions & 1 deletion lib/6to5/traverse/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ var traverse = module.exports = function (parent, callback) {
_.each(nodes, function (node, i) {
handle(nodes, i);
});
parent[key] = _.flatten(nodes).filter(function (node) {

parent[key] = _.flatten(parent[key]).filter(function (node) {
return node !== traverse.Delete;
});
} else {
handle(parent, key);

if (parent[key] === traverse.Delete) {
throw new Error("trying to delete property " + key + " from " +
parent.type + " but can't because it's required");
}
}
});
};
Expand Down Expand Up @@ -66,3 +72,18 @@ traverse.replace = function (node, callback) {
if (result != null) obj[key] = result;
});
};

traverse.replace.shallow = function (node, callback) {
traverse(node, function (node, parent, obj, key) {
var result = callback(node, parent);
if (result != null) obj[key] = result;
return false;
});
};

traverse.shallow = function (node, callback) {
traverse(node, function () {
callback.apply(this, arguments);
return false;
});
};
2 changes: 2 additions & 0 deletions test/fixtures/block-binding/hoist-multiple/actual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let MULTIPLIER = 5;
var foo = "bar", bar = "foo";
7 changes: 7 additions & 0 deletions test/fixtures/block-binding/hoist-multiple/expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var foo;
var bar;
(function () {
var MULTIPLIER = 5;
foo = "bar";
bar = "foo";
})();
2 changes: 2 additions & 0 deletions test/fixtures/block-binding/hoist/actual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let MULTIPLIER = 5;
var foo = "bar";
5 changes: 5 additions & 0 deletions test/fixtures/block-binding/hoist/expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var foo;
(function () {
var MULTIPLIER = 5;
foo = "bar";
})();
3 changes: 2 additions & 1 deletion test/fixtures/constants/program/expected.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var i;
(function () {
var MULTIPLIER = 5;
for (var i in arr) {
for (i in arr) {
console.log(arr[i] * MULTIPLIER);
}
}());

0 comments on commit fd932e2

Please sign in to comment.