hoist FunctionDeclaration exports to top, possible fix for #30

This commit is contained in:
Sebastian McKenzie
2014-10-10 14:38:46 +11:00
parent a484ea6003
commit 8d74a4d925
5 changed files with 71 additions and 13 deletions

View File

@@ -34,7 +34,7 @@ var transform = module.exports = function (code, opts) {
};
transform._run = function (code, tree, opts) {
traverse.replace(tree, function (node) {
traverse(tree, function (node) {
if (node.type === "EmptyStatement") {
return traverse.Delete;
}
@@ -70,13 +70,22 @@ transform._run = function (code, tree, opts) {
};
transform._runTransformer = function (transformer, tree, opts, generateUid) {
if (transformer.Program) transformer.Program(tree, opts);
var build = function (exit) {
return function (node, parent) {
var fns = transformer[node.type] || transformer.all;
if (!fns) return;
traverse.replace(tree, function (node, parent) {
var fn = transformer[node.type] || transformer.all;
if (!fn) return;
var fn = fns.enter || fns;
if (exit) fn = fns.exit;
if (!fn || !_.isFunction(fn)) return;
return fn(node, parent, opts, generateUid);
return fn(node, parent, opts, generateUid);
};
};
traverse(tree, {
enter: build(),
exit: build(true)
});
};

View File

@@ -61,7 +61,7 @@ var pushExportSpecifiers = function (node, nodes) {
});
};
var pushExportDeclaration = function (node, nodes) {
var pushExportDeclaration = function (node, parent, nodes) {
var declar = node.declaration;
if (node.default) {
@@ -80,19 +80,43 @@ var pushExportDeclaration = function (node, nodes) {
id = declar.declarations[0].id;
}
nodes.push(declar);
nodes.push(util.template("exports-assign", {
var assign = util.template("exports-assign", {
VALUE: id,
KEY: id
}, true));
}, true);
nodes.push(declar);
if (declar.type === "FunctionDeclaration") {
assign._modulesHoist = true;
}
nodes.push(assign);
}
};
exports.ExportDeclaration = function (node) {
exports.Program = {
exit: function (node) {
var unshift = [];
node.body = node.body.filter(function (bodyNode) {
if (bodyNode._modulesHoist) {
unshift.push(bodyNode);
return false;
} else {
return true;
}
});
node.body = unshift.concat(node.body);
}
};
exports.ExportDeclaration = function (node, parent) {
var nodes = [];
if (node.declaration) {
pushExportDeclaration(node, nodes);
pushExportDeclaration(node, parent, nodes);
} else {
pushExportSpecifiers(node, nodes);
}