UNPKG

traceur

Version:
476 lines (475 loc) 16.7 kB
"use strict"; function $__interopRequire(id) { id = require(id); return id && id.__esModule && id || {default: id}; } Object.defineProperties(module.exports, { __esModule: {value: true}, InternalLoader: { enumerable: true, get: function() { return InternalLoader; } }, internals: { enumerable: true, get: function() { return internals; } } }); var $__createClass = $__interopRequire("traceur/dist/commonjs/runtime/modules/createClass.js").default; var $__superConstructor = $__interopRequire("traceur/dist/commonjs/runtime/modules/superConstructor.js").default; var assert = require("../util/assert.js").assert; var LoaderCompiler = require("./LoaderCompiler.js").LoaderCompiler; var ExportsList = require("../codegeneration/module/ModuleSymbol.js").ExportsList; var $__15 = require("../util/url.js"), isAbsolute = $__15.isAbsolute, resolveUrl = $__15.resolveUrl; var Options = require("../Options.js").Options; var NOT_STARTED = 0; var LOADING = 1; var LOADED = 2; var PARSED = 3; var TRANSFORMING = 4; var TRANSFORMED = 5; var COMPLETE = 6; var ERROR = 7; function mapToValues(map) { var array = []; map.forEach(function(v) { array.push(v); }); return array; } var LoaderError = function($__super) { function LoaderError(msg, tree) { $__superConstructor(LoaderError).call(this); this.message = msg; this.tree = tree; this.name = 'LoaderError'; } return ($__createClass)(LoaderError, {}, {}, $__super); }(Error); var CodeUnit = function() { function CodeUnit(loaderCompiler, normalizedName, type, state, name, referrerName, address) { var $__8 = this; this.promise = new Promise(function(res, rej) { $__8.loaderCompiler = loaderCompiler; $__8.normalizedName = normalizedName; $__8.type = type; $__8.name_ = name; $__8.referrerName_ = referrerName; $__8.address = address; $__8.state_ = state || NOT_STARTED; $__8.error = null; $__8.result = null; $__8.metadata_ = {}; $__8.dependencies = []; $__8.resolve = res; $__8.reject = rej; }); } return ($__createClass)(CodeUnit, { get state() { return this.state_; }, set state(value) { if (value < this.state_) { throw new Error('Invalid state change'); } this.state_ = value; }, get metadata() { return this.metadata_; }, set metadata(value) { assert(value); this.metadata_ = value; }, nameTrace: function() { var trace = this.specifiedAs(); if (isAbsolute(this.name_)) { return trace + 'An absolute name.\n'; } if (this.referrerName_) { return trace + this.importedBy() + this.normalizesTo(); } return trace + this.normalizesTo(); }, specifiedAs: function() { return ("Specified as " + this.name_ + ".\n"); }, importedBy: function() { return ("Imported by " + this.referrerName_ + ".\n"); }, normalizesTo: function() { return 'Normalizes to ' + this.normalizedName + '\n'; } }, {}); }(); var PreCompiledCodeUnit = function($__super) { function PreCompiledCodeUnit(loaderCompiler, normalizedName, name, referrerName, address, module) { $__superConstructor(PreCompiledCodeUnit).call(this, loaderCompiler, normalizedName, 'module', COMPLETE, name, referrerName, address); this.result = module; this.resolve(this.result); } return ($__createClass)(PreCompiledCodeUnit, {}, {}, $__super); }(CodeUnit); var BundledCodeUnit = function($__super) { function BundledCodeUnit(loaderCompiler, normalizedName, name, referrerName, address, deps, execute, setModule) { $__superConstructor(BundledCodeUnit).call(this, loaderCompiler, normalizedName, 'module', TRANSFORMED, name, referrerName, address); this.deps = deps; this.execute = execute; } return ($__createClass)(BundledCodeUnit, { getModuleSpecifiers: function() { return this.deps; }, evaluate: function() { var $__8 = this; var normalizedNames = this.deps.map(function(name) { return $__8.loader_.normalize(name); }); var module = this.execute.apply(Reflect.global, normalizedNames); setModule(this.normalizedName, module); return module; } }, {}, $__super); }(CodeUnit); var HookedCodeUnit = function($__super) { function HookedCodeUnit() { $__superConstructor(HookedCodeUnit).apply(this, arguments); } return ($__createClass)(HookedCodeUnit, { getModuleSpecifiers: function() { return this.loaderCompiler.getModuleSpecifiers(this); }, evaluate: function() { return this.loaderCompiler.evaluateCodeUnit(this); } }, {}, $__super); }(CodeUnit); var LoadCodeUnit = function($__super) { function LoadCodeUnit(loaderCompiler, normalizedName, name, referrerName, address) { $__superConstructor(LoadCodeUnit).call(this, loaderCompiler, normalizedName, 'module', NOT_STARTED, name, referrerName, address); } return ($__createClass)(LoadCodeUnit, {}, {}, $__super); }(HookedCodeUnit); var EvalCodeUnit = function($__super) { function EvalCodeUnit(loaderCompiler, code) { var type = arguments[2] !== (void 0) ? arguments[2] : 'script'; var normalizedName = arguments[3]; var referrerName = arguments[4]; var address = arguments[5]; $__superConstructor(EvalCodeUnit).call(this, loaderCompiler, normalizedName, type, LOADED, null, referrerName, address); this.source = code; } return ($__createClass)(EvalCodeUnit, {}, {}, $__super); }(HookedCodeUnit); var uniqueNameCount = 0; var InternalLoader = function() { function InternalLoader(loader, loaderCompiler) { assert(loaderCompiler); this.loader_ = loader; this.loaderCompiler = loaderCompiler; this.cache = new Map(); this.urlToKey = Object.create(null); this.sync_ = false; this.sourceMapsByURL_ = Object.create(null); this.sourceMapsByOutputName_ = Object.create(null); } return ($__createClass)(InternalLoader, { defaultMetadata_: function() { var metadata = arguments[0] !== (void 0) ? arguments[0] : {}; var incoming = metadata.traceurOptions; if (incoming && !(incoming instanceof Options)) { var unknown = Options.listUnknownOptions(incoming); if (unknown.length) { console.warn('Unknown metadata.traceurOptions ignored: ' + unknown.join(',')); } } metadata.traceurOptions = incoming || new Options(); return metadata; }, defaultModuleMetadata_: function() { var metadata = arguments[0] !== (void 0) ? arguments[0] : {}; var metadata = this.defaultMetadata_(metadata); metadata.traceurOptions.script = false; return metadata; }, getSourceMap: function(url) { return this.sourceMapsByURL_[url] || this.sourceMapsByOutputName_[url]; }, load: function(name) { var referrerName = arguments[1] !== (void 0) ? arguments[1] : this.loader_.baseURL; var address = arguments[2]; var metadata = arguments[3] !== (void 0) ? arguments[3] : {}; metadata = this.defaultMetadata_(metadata); var codeUnit = this.getOrCreateCodeUnit_(name, referrerName, address, metadata); this.load_(codeUnit); return codeUnit.promise.then(function() { return codeUnit; }); }, load_: function(codeUnit) { var $__8 = this; if (codeUnit.state === ERROR) { return codeUnit; } if (codeUnit.state === TRANSFORMED) { this.handleCodeUnitLoaded(codeUnit); } else { if (codeUnit.state !== NOT_STARTED) return codeUnit; codeUnit.state = LOADING; codeUnit.address = this.loader_.locate(codeUnit); this.loader_.fetch(codeUnit).then(function(text) { codeUnit.source = text; return codeUnit; }).then(function(load) { return $__8.loader_.translate(load); }).then(function(source) { codeUnit.source = source; codeUnit.state = LOADED; $__8.handleCodeUnitLoaded(codeUnit); return codeUnit; }).catch(function(err) { try { codeUnit.state = ERROR; codeUnit.error = err; $__8.handleCodeUnitLoadError(codeUnit); } catch (ex) { console.error('Internal Error ' + (ex.stack || ex)); } }); } return codeUnit; }, module: function(code, referrerName, address, metadata) { var codeUnit = new EvalCodeUnit(this.loaderCompiler, code, 'module', null, referrerName, address); codeUnit.metadata = this.defaultMetadata_(metadata); this.cache.set({}, codeUnit); this.handleCodeUnitLoaded(codeUnit); return codeUnit.promise; }, define: function(normalizedName, code, address, metadata) { var codeUnit = new EvalCodeUnit(this.loaderCompiler, code, 'module', normalizedName, null, address); var key = this.getKey(normalizedName, 'module'); codeUnit.metadata = this.defaultMetadata_(metadata); this.cache.set(key, codeUnit); this.handleCodeUnitLoaded(codeUnit); return codeUnit.promise; }, script: function(code, name, referrerName, address, metadata) { var normalizedName = this.loader_.normalize(name || '', referrerName, address); var codeUnit = new EvalCodeUnit(this.loaderCompiler, code, 'script', normalizedName, referrerName, address); var key = {}; if (name) key = this.getKey(normalizedName, 'script'); codeUnit.metadata = this.defaultMetadata_(metadata); this.cache.set(key, codeUnit); this.handleCodeUnitLoaded(codeUnit); return codeUnit.promise; }, getKey: function(url, type) { var combined = type + ':' + url; if (combined in this.urlToKey) { return this.urlToKey[combined]; } return this.urlToKey[combined] = {}; }, getCodeUnit_: function(normalizedName, type) { var key = this.getKey(normalizedName, type); var codeUnit = this.cache.get(key); return { key: key, codeUnit: codeUnit }; }, getOrCreateCodeUnit_: function(name, referrerName, address, metadata) { var normalizedName = this.loader_.normalize(name, referrerName, address); var type = 'module'; if (metadata && metadata.traceurOptions && metadata.traceurOptions.script) type = 'script'; var $__9 = this.getCodeUnit_(normalizedName, type), key = $__9.key, codeUnit = $__9.codeUnit; if (!codeUnit) { assert(metadata && metadata.traceurOptions); var module = this.loader_.get(normalizedName); if (module) { codeUnit = new PreCompiledCodeUnit(this.loaderCompiler, normalizedName, name, referrerName, address, module); codeUnit.type = 'module'; } else { codeUnit = new LoadCodeUnit(this.loaderCompiler, normalizedName, name, referrerName, address); codeUnit.type = type; } codeUnit.metadata = { traceurOptions: metadata.traceurOptions, outputName: metadata.outputName, rootModule: metadata.rootModule }; this.cache.set(key, codeUnit); } return codeUnit; }, areAll: function(state) { return mapToValues(this.cache).every(function(codeUnit) { return codeUnit.state >= state; }); }, getCodeUnitForModuleSpecifier: function(name, referrerName) { var normalizedName = this.loader_.normalize(name, referrerName); return this.getCodeUnit_(normalizedName, 'module').codeUnit; }, getExportsListForModuleSpecifier: function(name, referrer) { var codeUnit = this.getCodeUnitForModuleSpecifier(name, referrer); var exportsList = codeUnit.metadata.moduleSymbol; if (!exportsList) { if (codeUnit.result) { exportsList = new ExportsList(codeUnit.normalizedName); exportsList.addExportsFromModule(codeUnit.result); } else { throw new Error(("InternalError: " + name + " is not a module, required by " + referrer)); } } return exportsList; }, handleCodeUnitLoaded: function(codeUnit) { var $__8 = this; var referrerName = codeUnit.normalizedName; try { var moduleSpecifiers = codeUnit.getModuleSpecifiers(); codeUnit.state = PARSED; if (!moduleSpecifiers) { this.abortAll(("No module specifiers in " + referrerName)); return; } codeUnit.dependencies = moduleSpecifiers.map(function(name) { return $__8.getOrCreateCodeUnit_(name, referrerName, null, $__8.defaultModuleMetadata_(codeUnit.metadata)); }); } catch (error) { this.rejectOneAndAll(codeUnit, error); return; } codeUnit.dependencies.forEach(function(dependency) { $__8.load_(dependency); }); if (this.areAll(PARSED)) { try { if (codeUnit.type === 'module') this.analyze(); this.transform(); this.evaluate(); } catch (error) { this.rejectOneAndAll(codeUnit, error); } } }, rejectOneAndAll: function(codeUnit, error) { codeUnit.state.ERROR; codeUnit.error = error; codeUnit.reject(error); this.abortAll(error); }, handleCodeUnitLoadError: function(codeUnit) { var message = codeUnit.error ? String(codeUnit.error) + '\n' : ("Failed to load '" + codeUnit.address + "'.\n"); message += codeUnit.nameTrace() + this.loader_.nameTrace(codeUnit); this.rejectOneAndAll(codeUnit, new Error(message)); }, abortAll: function(errorMessage) { this.cache.forEach(function(codeUnit) { if (codeUnit.state !== ERROR) codeUnit.reject(errorMessage); }); }, analyze: function() { this.loaderCompiler.analyzeDependencies(mapToValues(this.cache), this); }, transform: function() { this.transformDependencies_(mapToValues(this.cache)); }, transformDependencies_: function(dependencies, dependentName) { for (var i = 0; i < dependencies.length; i++) { var codeUnit = dependencies[i]; if (codeUnit.state >= TRANSFORMED) { continue; } if (codeUnit.state === TRANSFORMING) { var cir = codeUnit.normalizedName; var cle = dependentName; this.rejectOneAndAll(codeUnit, new Error(("Unsupported circular dependency between " + cir + " and " + cle))); return; } codeUnit.state = TRANSFORMING; try { this.transformCodeUnit_(codeUnit); } catch (error) { this.rejectOneAndAll(codeUnit, error); return; } } }, transformCodeUnit_: function(codeUnit) { this.transformDependencies_(codeUnit.dependencies, codeUnit.normalizedName); if (codeUnit.state === ERROR) return; this.loaderCompiler.transform(codeUnit); codeUnit.state = TRANSFORMED; this.loaderCompiler.write(codeUnit); var info = codeUnit.metadata.compiler.sourceMapInfo; if (info) { this.sourceMapsByURL_[info.url] = info.map; this.sourceMapsByOutputName_[info.outputName] = info.map; } this.loader_.instantiate(codeUnit); }, orderDependencies: function() { var visited = new Map(); var ordered = []; function orderCodeUnits(codeUnit) { if (visited.has(codeUnit)) { return; } visited.set(codeUnit, true); codeUnit.dependencies.forEach(orderCodeUnits); ordered.push(codeUnit); } this.cache.forEach(orderCodeUnits); return ordered; }, evaluate: function() { var dependencies = this.orderDependencies(); for (var i = 0; i < dependencies.length; i++) { var codeUnit = dependencies[i]; if (codeUnit.state >= COMPLETE) { continue; } var result = void 0; try { result = codeUnit.evaluate(); } catch (ex) { this.rejectOneAndAll(codeUnit, ex); return; } codeUnit.result = result; codeUnit.source = null; } for (var i = 0; i < dependencies.length; i++) { var codeUnit = dependencies[i]; if (codeUnit.state >= COMPLETE) { continue; } codeUnit.state = COMPLETE; codeUnit.resolve(codeUnit.result); } } }, {}); }(); var internals = { CodeUnit: CodeUnit, EvalCodeUnit: EvalCodeUnit, LoadCodeUnit: LoadCodeUnit, LoaderCompiler: LoaderCompiler };