caffeine-mc
Version:
Select, configure and extend your to-JavaScript compiler, with arbitrary code, on a per file bases from within the file.
255 lines (221 loc) • 8.88 kB
JavaScript
// Generated by CoffeeScript 1.12.7
(function() {
var BaseClass, CaffeineMc, CaffeineMcParser, CompileCache, Compilers, Metacompiler, checkWorkingCacheExpiration, dashCase, formattedInspect, isArray, isFunction, isObject, isString, log, lowerCamelCase, merge, objectWithout, present, realRequire, ref, upperCamelCase,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Compilers = require('./Compilers');
CaffeineMcParser = require('./CaffeineMcParser');
CaffeineMc = require('./namespace');
CompileCache = require('./CompileCache');
CaffeineMc.cacheEnabled = true;
realRequire = eval('require');
ref = require('art-standard-lib'), dashCase = ref.dashCase, formattedInspect = ref.formattedInspect, present = ref.present, isFunction = ref.isFunction, log = ref.log, isString = ref.isString, lowerCamelCase = ref.lowerCamelCase, upperCamelCase = ref.upperCamelCase, merge = ref.merge, objectWithout = ref.objectWithout, isArray = ref.isArray, isObject = ref.isObject;
BaseClass = require('art-class-system').BaseClass;
checkWorkingCacheExpiration = require('./WorkingCache').checkWorkingCacheExpiration;
module.exports = Metacompiler = (function(superClass) {
extend(Metacompiler, superClass);
Metacompiler.compile = function(code, options) {
if (options == null) {
options = {};
}
return new Metacompiler().compile(code, options);
};
Metacompiler.classGetter({
CaffeineScript: function() {
return require('caffeine-script');
}
});
Metacompiler.getter("compiler lastMetacompilerResult", {
current: function() {
return this.compiler;
}
});
Metacompiler.setter({
/*
IN:
string: configure to use one of the CaffeineCompiler classes
function: compileFunction
object:
compiler: custom compiler instance. Must implement:
compile: compileFunction
compileFunction: (sourceCode, options) ->
IN:
sourceCode: string
options: {}
ERROR: throw errors
OUT:
evalable-js-string
OR
object with at least:
compiled: js: evalable-js-string
*/
compiler: function(arg, options) {
return this._compiler = (function() {
if (isString(arg)) {
return this.getCompiler(arg, options);
} else if (isFunction(arg.compile)) {
return arg;
} else if (isFunction(arg)) {
return {
compile: arg
};
} else {
log.error({
InavlidCompiler: arg
});
throw new Error("CaffeineMc: @compiler must be a function or be an object with a .compile method.");
}
}).call(this);
}
});
function Metacompiler() {
Metacompiler.__super__.constructor.apply(this, arguments);
this._metaParser = new CaffeineMcParser;
this._metaCompiler = this;
this._compiler = this["class"].CaffeineScript;
this.compilers = {};
}
Metacompiler.prototype.normalizeCompilerResult = function(result) {
var ref1;
if (isString(result)) {
return {
compiled: {
js: result
}
};
} else if (isString(result != null ? result.code : void 0)) {
return {
compiled: {
js: result.code
}
};
} else if (isString(result != null ? result.js : void 0)) {
return {
compiled: result
};
} else if (isString(result != null ? (ref1 = result.compiled) != null ? ref1.js : void 0 : void 0)) {
return result;
} else {
log.error({
normalizeCompilerResult: {
result: result,
compiler: this.compiler
}
});
throw new Error("CaffeineMc: expected @compiler result to be: (string), {js: string}, or {compiled: {js: string}}. Was: " + (formattedInspect(result)));
}
};
/*
IN:
code: string
options:
sourceMap: t/f
inlineMap: t/f
sourceFile:
sourceDir:
OUT: (an object)
compiled: extension => output map
extension: string, ex: "js"
output: string, ex: "alert();"
If writing to files, we might do:
for extension, output of compiled
write originalFileNameWith(extension), output
*/
Metacompiler.prototype.compile = function(code, options) {
checkWorkingCacheExpiration();
options = merge(CaffeineMc.globalCompilerOptions, options);
if (options.prettier && (options.inlineMap || options.sourceMap)) {
throw new Error("prettier does not support sourcemaps");
}
if (CaffeineMc.cacheEnabled && options.cache && options.sourceFile) {
return this._compileWithCaching(code, options);
} else {
return this._postprocess(options, this._compileWithMetacompiler(code, options));
}
};
Metacompiler.prototype._postprocess = function(options, out) {
return this._postprocesPrettier(options, out);
};
Metacompiler.prototype._postprocesPrettier = function(options, out) {
var e;
if (options.prettier) {
try {
if (out.compiled.js != null) {
out.compiled.js = require("prettier").format(out.compiled.js, {
parser: "babel"
});
}
out.prettier = true;
} catch (error) {
e = error;
log(e.message);
throw e;
}
}
return out;
};
Metacompiler.prototype._compileWithCaching = function(code, options) {
var cacheInfo, cachedCompile, inlineMap, prettier;
options = objectWithout(options, "cache");
cacheInfo = {
compiler: this.compiler,
source: code,
verbose: options.verbose,
sourceFile: options.sourceFile
};
prettier = options.prettier, inlineMap = options.inlineMap;
if (prettier || inlineMap) {
cacheInfo.compilerOptions = merge({
prettier: prettier,
inlineMap: inlineMap
});
}
if (cachedCompile = CompileCache.fetch(cacheInfo)) {
return cachedCompile;
} else {
return CompileCache.cache(merge(cacheInfo, this._postprocess(options, this._compileWithMetacompiler(code, options))));
}
};
Metacompiler.prototype._compileWithMetacompiler = function(rawCode, options) {
var code, compilerName, metaCode, ref1, result;
ref1 = this._metaParser.parse(rawCode.toString()), compilerName = ref1.compilerName, metaCode = ref1.metaCode, code = ref1.code;
if (metaCode || compilerName) {
this._lastMetacompilerResult = metaCode ? (result = this.normalizeCompilerResult(this.compiler.compile(metaCode)), CaffeineMc.evalInContext(result.compiled.js, this)) : this.setCompiler(compilerName, options);
return this._compileWithMetacompiler(code, options);
} else {
return this.normalizeCompilerResult(this.compiler.compile(code, options));
}
};
Metacompiler.getter({
compilerName: function() {
var base, base1;
return (typeof (base = this.compiler).getClassName === "function" ? base.getClassName() : void 0) || (typeof (base1 = this.compiler).getName === "function" ? base1.getName() : void 0) || this._compilerName || 'unknown-compiler';
}
});
Metacompiler.prototype.getCompiler = function(compilerName, options) {
var absolutePath, base, compiler, out, ucCompilerName;
if (compilerName.toLocaleLowerCase() === "javascript") {
compilerName = "JavaScript";
}
if (!present(compilerName)) {
return this.compiler;
}
if (compiler = Compilers[ucCompilerName = upperCamelCase(compilerName)]) {
return compiler;
}
this._compilerName = compilerName;
absolutePath = CaffeineMc.findModuleSync(compilerName, options).absolutePath;
try {
out = (base = this.compilers)[absolutePath] || (base[absolutePath] = realRequire(absolutePath));
if (!isFunction(out.compile)) {
throw new Error;
}
} catch (error) {
throw new Error("CaffeineMc: compiler not found for: " + compilerName + " (normalized: " + ucCompilerName + ", require: " + absolutePath + ")");
}
return out;
};
return Metacompiler;
})(BaseClass);
}).call(this);
//# sourceMappingURL=Metacompiler.js.map