add file class to simplify transforming
This commit is contained in:
102
lib/6to5/file.js
Normal file
102
lib/6to5/file.js
Normal file
@@ -0,0 +1,102 @@
|
||||
module.exports = File;
|
||||
|
||||
var transform = require("./transform");
|
||||
var traverse = require("./traverse");
|
||||
var util = require("./util");
|
||||
var _ = require("lodash");
|
||||
|
||||
function File(opts) {
|
||||
this.uids = {};
|
||||
this.opts = File.normaliseOptions(opts);
|
||||
this.ast = {};
|
||||
}
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
opts = opts || {};
|
||||
|
||||
_.defaults(opts, {
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
filename: "unknown",
|
||||
format: {}
|
||||
});
|
||||
|
||||
_.defaults(opts, {
|
||||
sourceFileName: opts.filename,
|
||||
sourceMapName: opts.filename
|
||||
});
|
||||
|
||||
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
||||
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
File.prototype.transform = function (ast) {
|
||||
this.ast = ast;
|
||||
|
||||
var self = this;
|
||||
var opts = this.opts;
|
||||
|
||||
_.each(transform.transformers, function (transformer, name) {
|
||||
self.runTransformer(name, transformer);
|
||||
});
|
||||
|
||||
var result = util.generate(ast, opts);
|
||||
|
||||
if (opts.sourceMap === "inline") {
|
||||
result.code += "\n" + util.sourceMapToComment(result.map);
|
||||
}
|
||||
|
||||
result.map = result.map || null;
|
||||
result.ast = ast;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
File.prototype.generateUid = function (name) {
|
||||
var uids = this.uids;
|
||||
var i = uids[name] || 1;
|
||||
|
||||
var id = name;
|
||||
if (i > 1) id += i;
|
||||
uids[name] = i + 1;
|
||||
return "_" + id;
|
||||
};
|
||||
|
||||
File.prototype.canRunTransformer = function (name) {
|
||||
var opts = this.opts;
|
||||
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && _.contains(blacklist, name)) return false;
|
||||
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist.length && !_.contains(whitelist, name)) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
File.prototype.runTransformer = function (name, transformer) {
|
||||
if (!this.canRunTransformer(name)) return;
|
||||
|
||||
var self = this;
|
||||
|
||||
var build = function (exit) {
|
||||
return function (node, parent) {
|
||||
var fns = transformer[node.type] || transformer.all;
|
||||
if (!fns) return;
|
||||
|
||||
var fn = fns.enter || fns;
|
||||
if (exit) fn = fns.exit;
|
||||
if (!fn || !_.isFunction(fn)) return;
|
||||
|
||||
return fn(node, parent, self);
|
||||
};
|
||||
};
|
||||
|
||||
traverse(this.ast, {
|
||||
enter: build(),
|
||||
exit: build(true)
|
||||
});
|
||||
};
|
||||
@@ -1,86 +1,21 @@
|
||||
module.exports = transform;
|
||||
|
||||
var sourceMap = require("source-map");
|
||||
var traverse = require("./traverse");
|
||||
var recast = require("recast");
|
||||
var File = require("./file");
|
||||
var util = require("./util");
|
||||
var _ = require("lodash");
|
||||
|
||||
var ensureTransformerNames = function (type, keys) {
|
||||
_.each(keys, function (key) {
|
||||
if (!transform.transformers[key]) {
|
||||
throw new ReferenceError("unknown transformer " + key + " specified in " + type);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var transform = module.exports = function (code, opts) {
|
||||
function transform(code, opts) {
|
||||
opts = opts || {};
|
||||
code = (code || "") + "";
|
||||
|
||||
_.defaults(opts, {
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
filename: "unknown",
|
||||
format: {}
|
||||
});
|
||||
|
||||
_.defaults(opts, {
|
||||
sourceFileName: opts.filename,
|
||||
sourceMapName: opts.filename
|
||||
});
|
||||
|
||||
ensureTransformerNames("blacklist", opts.blacklist);
|
||||
ensureTransformerNames("whitelist", opts.whitelist);
|
||||
var file = new File(opts);
|
||||
|
||||
return util.parse(opts, code, function (tree) {
|
||||
return transform._run(code, tree, opts);
|
||||
return file.transform(tree);
|
||||
});
|
||||
};
|
||||
|
||||
transform._run = function (code, tree, opts) {
|
||||
var generateUid = util.buildUidGenerator();
|
||||
|
||||
_.each(transform.transformers, function (transformer, name) {
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && _.contains(blacklist, name)) return;
|
||||
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist.length && !_.contains(whitelist, name)) return;
|
||||
|
||||
transform._runTransformer(transformer, tree, opts, generateUid);
|
||||
});
|
||||
|
||||
var result = util.generate(tree, opts);
|
||||
|
||||
if (opts.sourceMap === "inline") {
|
||||
result.code += "\n" + util.sourceMapToComment(result.map);
|
||||
}
|
||||
|
||||
result.map = result.map || null;
|
||||
result.ast = tree;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
transform._runTransformer = function (transformer, tree, opts, generateUid) {
|
||||
var build = function (exit) {
|
||||
return function (node, parent) {
|
||||
var fns = transformer[node.type] || transformer.all;
|
||||
if (!fns) return;
|
||||
|
||||
var fn = fns.enter || fns;
|
||||
if (exit) fn = fns.exit;
|
||||
if (!fn || !_.isFunction(fn)) return;
|
||||
|
||||
return fn(node, parent, opts, generateUid);
|
||||
};
|
||||
};
|
||||
|
||||
traverse(tree, {
|
||||
enter: build(),
|
||||
exit: build(true)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
transform.test = function (task, assert) {
|
||||
var actual = task.actual;
|
||||
@@ -111,12 +46,20 @@ transform.test = function (task, assert) {
|
||||
|
||||
_.each(task.sourceMappings, function (mapping, i) {
|
||||
var pos = consumer.originalPositionFor(mapping.generated);
|
||||
var msg = "source mapping " + ++i + " - generated: " + mapping.generated.line + ":" + mapping.generated.column;
|
||||
var msg = "source mapping " + i + " - generated: " + mapping.generated.line + ":" + mapping.generated.column;
|
||||
assert.equal(pos.line + ":" + pos.column, mapping.original.line + ":" + mapping.original.column, msg);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
transform._ensureTransformerNames = function (type, keys) {
|
||||
_.each(keys, function (key) {
|
||||
if (!transform.transformers[key]) {
|
||||
throw new ReferenceError("unknown transformer " + key + " specified in " + type);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
transform.transformers = {
|
||||
modules: require("./transformers/modules"),
|
||||
computedPropertyNames: require("./transformers/computed-property-names"),
|
||||
@@ -130,7 +73,7 @@ transform.transformers = {
|
||||
propertyMethodAssignment: require("./transformers/property-method-assignment"),
|
||||
defaultParameters: require("./transformers/default-parameters"),
|
||||
generators: require("./transformers/generators"),
|
||||
blockBinding: require("./transformers/block-binding"),
|
||||
letScoping: require("./transformers/let-scoping"),
|
||||
restParameters: require("./transformers/rest-parameters"),
|
||||
destructuring: require("./transformers/destructuring"),
|
||||
forOf: require("./transformers/for-of"),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var util = require("../util");
|
||||
var _ = require("lodash");
|
||||
|
||||
// TODO: support `arguments` and `this` inside
|
||||
|
||||
var single = function (node) {
|
||||
var block = node.blocks[0];
|
||||
|
||||
@@ -15,8 +17,8 @@ var single = function (node) {
|
||||
});
|
||||
};
|
||||
|
||||
var multiple = function (node, generateUid) {
|
||||
var uid = generateUid("arr");
|
||||
var multiple = function (node, file) {
|
||||
var uid = file.generateUid("arr");
|
||||
|
||||
var container = util.template("array-comprehension-container", {
|
||||
KEY: uid
|
||||
@@ -64,7 +66,7 @@ var multiple = function (node, generateUid) {
|
||||
return container;
|
||||
};
|
||||
|
||||
exports.ComprehensionExpression = function (node, parent, opts, generateUid) {
|
||||
exports.ComprehensionExpression = function (node, parent, file) {
|
||||
_.each(node.blocks, function (block) {
|
||||
if (!block.of) {
|
||||
throw util.errorWithNode(block, "for-in array comprehension is not supported");
|
||||
@@ -74,6 +76,6 @@ exports.ComprehensionExpression = function (node, parent, opts, generateUid) {
|
||||
if (node.blocks.length === 1) {
|
||||
return single(node);
|
||||
} else {
|
||||
return multiple(node, generateUid);
|
||||
return multiple(node, file);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,14 +3,14 @@ var util = require("../util");
|
||||
var b = require("ast-types").builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, opts, generateUid) {
|
||||
exports.ClassDeclaration = function (node, parent, file) {
|
||||
return b.variableDeclaration("var", [
|
||||
b.variableDeclarator(node.id, buildClass(node, generateUid))
|
||||
b.variableDeclarator(node.id, buildClass(node, file))
|
||||
]);
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, opts, generateUid) {
|
||||
return buildClass(node, generateUid);
|
||||
exports.ClassExpression = function (node, parent, file) {
|
||||
return buildClass(node, file);
|
||||
};
|
||||
|
||||
var getMemberExpressionObject = function (node) {
|
||||
@@ -20,15 +20,9 @@ var getMemberExpressionObject = function (node) {
|
||||
return node;
|
||||
};
|
||||
|
||||
var buildClass = function (node, generateUid) {
|
||||
var buildClass = function (node, file) {
|
||||
var superName = node.superClass;
|
||||
var className = node.id;
|
||||
|
||||
var noName = false;
|
||||
if (!className) {
|
||||
className = b.identifier(generateUid("class"));
|
||||
noName = true;
|
||||
}
|
||||
var className = node.id || b.identifier(file.generateUid("class"));
|
||||
|
||||
var superClassArgument = node.superClass;
|
||||
var superClassCallee = node.superClass;
|
||||
@@ -38,7 +32,7 @@ var buildClass = function (node, generateUid) {
|
||||
superClassArgument = superClassCallee = getMemberExpressionObject(superName);
|
||||
} else if (superName.type !== "Identifier") {
|
||||
superClassArgument = superName;
|
||||
superClassCallee = superName = b.identifier(generateUid("ref"));
|
||||
superClassCallee = superName = b.identifier(file.generateUid("ref"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +43,8 @@ var buildClass = function (node, generateUid) {
|
||||
var block = container.callee.body;
|
||||
var body = block.body;
|
||||
|
||||
if (noName) {
|
||||
body[0].declarations[0].init.id = null;
|
||||
if (node.id) {
|
||||
body[0].declarations[0].init.id = className;
|
||||
}
|
||||
|
||||
var returnStatement = body.pop();
|
||||
@@ -135,10 +129,10 @@ var buildClassBody = function (body, className, superName, node) {
|
||||
};
|
||||
|
||||
var superIdentifier = function (superName, methodNode, methodName, node, parent) {
|
||||
if (parent.property === node) return;
|
||||
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
if (parent.type === "CallExpression" && parent.callee === node) {
|
||||
if (parent.property === node) {
|
||||
return;
|
||||
} else if (parent.type === "CallExpression" && parent.callee === node) {
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
parent.arguments.unshift(b.thisExpression());
|
||||
|
||||
if (methodName === "constructor") {
|
||||
|
||||
@@ -3,7 +3,7 @@ var util = require("../util");
|
||||
var b = require("ast-types").builders;
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, opts, generateUid) {
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var hasComputed = false;
|
||||
var hasThis = false;
|
||||
|
||||
@@ -25,7 +25,7 @@ exports.ObjectExpression = function (node, parent, opts, generateUid) {
|
||||
var templateName = "function-return-obj";
|
||||
if (hasThis) templateName += "-this";
|
||||
|
||||
var objId = b.identifier(generateUid("ref"));
|
||||
var objId = b.identifier(file.generateUid("ref"));
|
||||
|
||||
var container = util.template(templateName, {
|
||||
KEY: objId,
|
||||
|
||||
@@ -47,9 +47,9 @@ var pushArrayPattern = function (kind, nodes, pattern, parentId) {
|
||||
});
|
||||
};
|
||||
|
||||
var pushPattern = function (kind, nodes, pattern, parentId, generateUid) {
|
||||
var pushPattern = function (kind, nodes, pattern, parentId, file) {
|
||||
if (parentId.type !== "MemberExpression" && parentId.type !== "Identifier") {
|
||||
var key = generateUid("ref");
|
||||
var key = file.generateUid("ref");
|
||||
|
||||
nodes.push(util.template("variable-assign", {
|
||||
KEY: key,
|
||||
@@ -63,14 +63,14 @@ var pushPattern = function (kind, nodes, pattern, parentId, generateUid) {
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, opts, generateUid) {
|
||||
exports.ForOfStatement = function (node, parent, file) {
|
||||
var declar = node.left;
|
||||
if (declar.type !== "VariableDeclaration") return;
|
||||
|
||||
var pattern = declar.declarations[0].id;
|
||||
if (!util.isPattern(pattern)) return;
|
||||
|
||||
var key = b.identifier(generateUid("ref"));
|
||||
var key = b.identifier(file.generateUid("ref"));
|
||||
node.left = b.variableDeclaration(declar.kind, [
|
||||
b.variableDeclarator(key, null)
|
||||
]);
|
||||
@@ -87,7 +87,7 @@ exports.ForOfStatement = function (node, parent, opts, generateUid) {
|
||||
|
||||
exports.ArrowFunctionExpression =
|
||||
exports.FunctionDeclaration =
|
||||
exports.FunctionExpression = function (node, parent, opts, generateUid) {
|
||||
exports.FunctionExpression = function (node, parent, file) {
|
||||
var block = node.body;
|
||||
var nodes = [];
|
||||
|
||||
@@ -97,8 +97,8 @@ exports.FunctionExpression = function (node, parent, opts, generateUid) {
|
||||
if (!util.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuring = true;
|
||||
var parentId = b.identifier(generateUid("ref"));
|
||||
pushPattern("var", nodes, pattern, parentId, generateUid);
|
||||
var parentId = b.identifier(file.generateUid("ref"));
|
||||
pushPattern("var", nodes, pattern, parentId, file);
|
||||
return parentId;
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ exports.FunctionExpression = function (node, parent, opts, generateUid) {
|
||||
block.body = nodes.concat(block.body || []);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, opts, generateUid) {
|
||||
exports.ExpressionStatement = function (node, parent, file) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
|
||||
@@ -115,7 +115,7 @@ exports.ExpressionStatement = function (node, parent, opts, generateUid) {
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var ref = b.identifier(generateUid("ref"));
|
||||
var ref = b.identifier(file.generateUid("ref"));
|
||||
nodes.push(b.variableDeclaration("var", [
|
||||
b.variableDeclarator(ref, expr.right)
|
||||
]));
|
||||
@@ -125,7 +125,7 @@ exports.ExpressionStatement = function (node, parent, opts, generateUid) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, opts, generateUid) {
|
||||
exports.VariableDeclaration = function (node, parent, file) {
|
||||
if (parent.type === "ForInStatement") return;
|
||||
|
||||
var nodes = [];
|
||||
@@ -143,7 +143,7 @@ exports.VariableDeclaration = function (node, parent, opts, generateUid) {
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
if (util.isPattern(pattern) && patternId) {
|
||||
pushPattern(node.kind, nodes, pattern, patternId, generateUid);
|
||||
pushPattern(node.kind, nodes, pattern, patternId, file);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(node.kind, declar.id, declar.init));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
var util = require("../util");
|
||||
var b = require("ast-types").builders;
|
||||
|
||||
exports.ForOfStatement = function (node, parent, opts, generateUid) {
|
||||
exports.ForOfStatement = function (node, parent, file) {
|
||||
var left = node.left;
|
||||
var declar;
|
||||
|
||||
var stepKey = b.identifier(generateUid("step"));
|
||||
var stepKey = b.identifier(file.generateUid("step"));
|
||||
var stepValueId = b.memberExpression(stepKey, b.identifier("value"), false);
|
||||
|
||||
if (left.type === "Identifier") {
|
||||
@@ -19,7 +19,7 @@ exports.ForOfStatement = function (node, parent, opts, generateUid) {
|
||||
}
|
||||
|
||||
var node2 = util.template("for-of", {
|
||||
ITERATOR_KEY: generateUid("iterator"),
|
||||
ITERATOR_KEY: file.generateUid("iterator"),
|
||||
STEP_KEY: stepKey,
|
||||
OBJECT: node.right
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ exports.Property = function (node) {
|
||||
if (node.method) node.method = false;
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, opts, generateUid) {
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var mutatorMap = {};
|
||||
|
||||
node.properties = node.properties.filter(function (prop) {
|
||||
@@ -20,7 +20,7 @@ exports.ObjectExpression = function (node, parent, opts, generateUid) {
|
||||
|
||||
if (_.isEmpty(mutatorMap)) return;
|
||||
|
||||
var objId = b.identifier(generateUid("ref"))
|
||||
var objId = b.identifier(file.generateUid("ref"));
|
||||
|
||||
return util.template("object-define-properties-closure", {
|
||||
KEY: objId,
|
||||
|
||||
Reference in New Issue
Block a user