145 lines
3.0 KiB
JavaScript
145 lines
3.0 KiB
JavaScript
module.exports = File;
|
|
|
|
var SHEBANG_REGEX = /^\#\!.*/;
|
|
|
|
var transform = require("./transform");
|
|
var recast = require("recast");
|
|
var util = require("./util");
|
|
var b = require("ast-types").builders;
|
|
var _ = require("lodash");
|
|
|
|
function File(opts) {
|
|
this.opts = File.normaliseOptions(opts);
|
|
this.moduleFormatter = this.getModuleFormatter(opts.modules);
|
|
|
|
this.declarations = {};
|
|
this.uids = {};
|
|
this.ast = {};
|
|
}
|
|
|
|
File.normaliseOptions = function (opts) {
|
|
opts = opts || {};
|
|
|
|
_.defaults(opts, {
|
|
blacklist: [],
|
|
whitelist: [],
|
|
sourceMap: false,
|
|
filename: "unknown",
|
|
modules: "common"
|
|
});
|
|
|
|
_.defaults(opts, {
|
|
sourceFileName: opts.filename,
|
|
sourceMapName: opts.filename
|
|
});
|
|
|
|
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
|
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
|
|
|
return opts;
|
|
};
|
|
|
|
File.prototype.getModuleFormatter = function (type) {
|
|
var ModuleLoader = transform.moduleFormatters[type];
|
|
if (!ModuleLoader) throw new ReferenceError("unknown module formatter type " + type);
|
|
return new ModuleLoader(this);
|
|
};
|
|
|
|
File.prototype.parseShebang = function (code) {
|
|
var shebangMatch = code.match(SHEBANG_REGEX);
|
|
if (shebangMatch) {
|
|
this.shebang = shebangMatch[0];
|
|
|
|
// remove shebang
|
|
code = code.replace(SHEBANG_REGEX, "");
|
|
}
|
|
|
|
return code;
|
|
};
|
|
|
|
File.prototype.addDeclaration = function (name) {
|
|
var declar = this.declarations[name];
|
|
if (declar) return declar.uid;
|
|
|
|
var uid = b.identifier(this.generateUid(name));
|
|
this.declarations[name] = {
|
|
uid: uid,
|
|
node: util.template(name)
|
|
};
|
|
return uid;
|
|
};
|
|
|
|
File.prototype.parse = function (code) {
|
|
var self = this;
|
|
|
|
code = this.parseShebang(code);
|
|
|
|
return util.parse(this.opts, code, function (tree) {
|
|
return self.transform(tree);
|
|
});
|
|
};
|
|
|
|
File.prototype.transform = function (ast) {
|
|
this.ast = ast;
|
|
|
|
var self = this;
|
|
|
|
_.each(transform.transformers, function (transformer) {
|
|
transformer.transform(self);
|
|
});
|
|
|
|
return this.generate();
|
|
};
|
|
|
|
File.prototype.generate = function () {
|
|
var opts = this.opts;
|
|
var ast = this.ast;
|
|
|
|
var printOpts = {
|
|
tabWidth: 2
|
|
};
|
|
|
|
if (opts.sourceMap) {
|
|
printOpts.sourceMapName = opts.sourceMapName;
|
|
}
|
|
|
|
var result = recast.print(ast, printOpts);
|
|
var code = result.code;
|
|
|
|
if (this.shebang) {
|
|
// add back shebang
|
|
code = this.shebang + code;
|
|
}
|
|
|
|
if (opts.sourceMap === "inline") {
|
|
code += "\n" + util.sourceMapToComment(result.map);
|
|
}
|
|
|
|
return {
|
|
code: code,
|
|
map: result.map || null,
|
|
ast: ast
|
|
};
|
|
};
|
|
|
|
File.prototype.generateUid = function (name) {
|
|
// replace all non-valid identifiers with dashes
|
|
name = name.replace(/[^a-zA-Z0-9]/g, "-");
|
|
|
|
// remove all dashes and numbers from start of name
|
|
name = name.replace(/^[-0-9]+/, "");
|
|
|
|
// camel case
|
|
name = name.replace(/[-_\s]+(.)?/g, function (match, c) {
|
|
return c ? c.toUpperCase() : "";
|
|
});
|
|
|
|
var uids = this.uids;
|
|
var i = uids[name] || 1;
|
|
|
|
var id = name;
|
|
if (i > 1) id += i;
|
|
uids[name] = i + 1;
|
|
return "_" + id;
|
|
};
|