hoist var declarations to before function definition when let block scoping
This commit is contained in:
parent
74f831bd39
commit
fd932e20e9
1
lib/6to5/templates/assign.js
Normal file
1
lib/6to5/templates/assign.js
Normal file
@ -0,0 +1 @@
|
||||
KEY = VALUE;
|
||||
1
lib/6to5/templates/variable-declare.js
Normal file
1
lib/6to5/templates/variable-declare.js
Normal file
@ -0,0 +1 @@
|
||||
var KEY;
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@ -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) {
|
||||
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -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
test/fixtures/block-binding/hoist-multiple/actual.js
vendored
Normal file
2
test/fixtures/block-binding/hoist-multiple/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
let MULTIPLIER = 5;
|
||||
var foo = "bar", bar = "foo";
|
||||
7
test/fixtures/block-binding/hoist-multiple/expected.js
vendored
Normal file
7
test/fixtures/block-binding/hoist-multiple/expected.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
var foo;
|
||||
var bar;
|
||||
(function () {
|
||||
var MULTIPLIER = 5;
|
||||
foo = "bar";
|
||||
bar = "foo";
|
||||
})();
|
||||
2
test/fixtures/block-binding/hoist/actual.js
vendored
Normal file
2
test/fixtures/block-binding/hoist/actual.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
let MULTIPLIER = 5;
|
||||
var foo = "bar";
|
||||
5
test/fixtures/block-binding/hoist/expected.js
vendored
Normal file
5
test/fixtures/block-binding/hoist/expected.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
var foo;
|
||||
(function () {
|
||||
var MULTIPLIER = 5;
|
||||
foo = "bar";
|
||||
})();
|
||||
3
test/fixtures/constants/program/expected.js
vendored
3
test/fixtures/constants/program/expected.js
vendored
@ -1,6 +1,7 @@
|
||||
var i;
|
||||
(function () {
|
||||
var MULTIPLIER = 5;
|
||||
for (var i in arr) {
|
||||
for (i in arr) {
|
||||
console.log(arr[i] * MULTIPLIER);
|
||||
}
|
||||
}());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user