139 lines
4.4 KiB
JavaScript
139 lines
4.4 KiB
JavaScript
var sourceMap = require("source-map");
|
|
var traverse = require("./traverse");
|
|
var recast = require("recast");
|
|
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) {
|
|
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);
|
|
|
|
return util.parse(opts, code, function (tree) {
|
|
return transform._run(code, tree, opts);
|
|
});
|
|
};
|
|
|
|
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;
|
|
var expect = task.expect;
|
|
var opts = task.options;
|
|
|
|
opts.filename = actual.filename;
|
|
|
|
var actualCode = actual.code.trim();
|
|
|
|
var actualResult = transform(actualCode, opts);
|
|
var actualAst = actualResult.ast;
|
|
actualCode = recast.prettyPrint(actualAst).code;
|
|
|
|
var expectCode = expect.code.trim();
|
|
var expectAst = util.parse(expect, expectCode);
|
|
var expectResult = recast.prettyPrint(expectAst);
|
|
expectCode = expectResult.code;
|
|
|
|
assert.equal(actualCode, expectCode);
|
|
|
|
if (task.sourceMap) {
|
|
assert.deepEqual(task.sourceMap, actualResult.map);
|
|
}
|
|
|
|
if (task.sourceMappings) {
|
|
var consumer = new sourceMap.SourceMapConsumer(actualResult.map);
|
|
|
|
_.each(task.sourceMappings, function (mapping, i) {
|
|
var pos = consumer.originalPositionFor(mapping.generated);
|
|
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.transformers = {
|
|
modules: require("./transformers/modules"),
|
|
computedPropertyNames: require("./transformers/computed-property-names"),
|
|
propertyNameShorthand: require("./transformers/property-name-shorthand"),
|
|
constants: require("./transformers/constants"),
|
|
arrayComprehension: require("./transformers/array-comprehension"),
|
|
arrowFunctions: require("./transformers/arrow-functions"),
|
|
classes: require("./transformers/classes"),
|
|
spread: require("./transformers/spread"),
|
|
templateLiterals: require("./transformers/template-literals"),
|
|
propertyMethodAssignment: require("./transformers/property-method-assignment"),
|
|
defaultParameters: require("./transformers/default-parameters"),
|
|
generators: require("./transformers/generators"),
|
|
blockBinding: require("./transformers/block-binding"),
|
|
restParameters: require("./transformers/rest-parameters"),
|
|
destructuring: require("./transformers/destructuring"),
|
|
forOf: require("./transformers/for-of"),
|
|
unicodeRegex: require("./transformers/unicode-regex")
|
|
};
|