# add dist

This commit is contained in:
Mario Romano
2016-04-21 11:56:31 +01:00
parent 5914688467
commit 07807e7bc3
13499 changed files with 1808930 additions and 5 deletions

View File

@@ -0,0 +1,393 @@
var System = require('systemjs');
var traceur = require('traceur');
var vm = require('vm');
var traceurGet = require('../lib/utils').traceurGet;
var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer;
var parseExpression = traceurGet('codegeneration/PlaceholderParser.js').parseExpression;
var CJSRequireTransformer = require('./cjs').CJSRequireTransformer;
var Promise = require('bluebird');
// First of two-pass transform
// lists number of define statements, the named module it defines (if any), and deps
// second pass will do rewriting based on this info
// we set this.anonDefine, which is true if there is one named define, or one anonymous define
// if there are more than one anonymous defines, it is invalid
function AMDDependenciesTransformer(map) {
// optional mapping function
this.map = map;
this.anonDefine = false;
this.anonDefineIndex = -1;
this.anonNamed = false;
this.deps = [];
this.bundleDefines = [];
this.defineRedefined = false;
return ParseTreeTransformer.call(this);
}
AMDDependenciesTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
AMDDependenciesTransformer.prototype.filterAMDDeps = function(deps) {
var newDeps = [];
var bundleDefines = this.bundleDefines;
deps.forEach(function(dep) {
if (['require', 'exports', 'module'].indexOf(dep) != -1)
return;
if (bundleDefines.indexOf(dep) != -1)
return;
newDeps.push(dep);
});
return newDeps;
};
// var define = x is the stopping point for handling a define
// we still allow (function(define) {})
// these are the same rules of the r.js optimizer
// var define disables until we quit the existing scope
AMDDependenciesTransformer.prototype.transformVariableDeclaration = function(tree) {
if (tree.lvalue.identifierToken && tree.lvalue.identifierToken.value == 'define')
this.defineRedefined = true;
return tree;
};
// this catches the scope exit, although should be better handled than this (eg blocks for ES6)
AMDDependenciesTransformer.prototype.transformFunctionDeclaration = function(tree) {
var defineRedefined = this.defineRedefined;
tree = ParseTreeTransformer.prototype.transformFunctionDeclaration.call(this, tree);
if (defineRedefined === false)
this.defineRedefined = false;
return tree;
};
AMDDependenciesTransformer.prototype.transformFunctionExpression = function(tree) {
var defineRedefined = this.defineRedefined;
tree = ParseTreeTransformer.prototype.transformFunctionExpression.call(this, tree);
if (defineRedefined === false)
this.defineRedefined = false;
return tree;
};
AMDDependenciesTransformer.prototype.transformCallExpression = function(tree) {
if (this.defineRedefined || !tree.operand.identifierToken || tree.operand.identifierToken.value != 'define')
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
var args = tree.args.args;
var name;
var depArg = -1;
if (args[0].type == 'LITERAL_EXPRESSION' || args[1] && args[1].type == 'ARRAY_LITERAL') {
name = args[0].literalToken && args[0].literalToken.processedValue || true;
if (args[1] && args[1].type == 'ARRAY_LITERAL')
depArg = 1;
}
else if (args[0].type == 'ARRAY_LITERAL') {
depArg = 0;
}
var factoryArg = name && depArg == -1 ? 1 : depArg + 1;
// ignore requires of the wrong form
if (!args[factoryArg])
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
// note the define index
// so we know which one to name for the second pass
if (!this.anonDefine || this.anonNamed)
this.anonDefineIndex++;
var parseDeps = false;
// anonymous define
if (!name) {
if (this.anonDefine && !this.anonNamed)
throw new Error('Multiple anonymous defines.');
this.anonDefine = true;
this.anonNamed = false;
parseDeps = true;
}
// named define
else {
if (typeof name != 'boolean') {
this.bundleDefines.push(name);
// remove any deps which exactly reference a name
var depsIndex = this.deps.indexOf(name);
if (depsIndex != -1)
this.deps.splice(depsIndex, 1);
}
if (!this.anonDefine && this.anonDefineIndex == 0 && typeof name != 'boolean') {
this.anonDefine = true;
this.anonNamed = true;
parseDeps = true;
}
else if (this.anonDefine && this.anonNamed) {
this.anonDefine = false;
this.anonNamed = false;
this.deps = [];
}
}
// only continue to extracting dependencies if this is THE anonymous define
if (!parseDeps)
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
if (depArg != -1) {
var deps = args[depArg].elements.map(function(dep) {
return dep.literalToken.processedValue;
});
// apply the map
var depMap = this.map;
if (depMap)
deps = deps.map(function(dep) {
if (['require', 'exports', 'module'].indexOf(dep) != -1)
return dep;
return depMap(dep);
});
// store dependencies for trace
this.deps = this.filterAMDDeps(deps);
// this is ONLY a mutation for remap which will be deprecated
args[depArg] = parseExpression([JSON.stringify(deps)]);
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
}
if (depArg == -1 && args[factoryArg].type == 'FUNCTION_EXPRESSION') {
var cjsFactory = args[factoryArg];
// now we need to do a scope transformer for the require function at this position
var fnParameters = cjsFactory.parameterList.parameters;
var reqName = fnParameters[0] && fnParameters[0].parameter.binding.identifierToken.value;
// now we create a new scope transformer and apply it to this function to find every call of
// the function reqName, noting the require
var cjsRequires = new CJSRequireTransformer(reqName);
cjsFactory.body = cjsRequires.transformAny(cjsFactory.body);
this.deps = this.filterAMDDeps(cjsRequires.requires);
}
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
};
exports.AMDDependenciesTransformer = AMDDependenciesTransformer;
// AMD System.registerDynamic transpiler
// This is the second of the two pass transform
function AMDDefineRegisterTransformer(moduleName, load, anonDefine, anonDefineIndex, depMap) {
this.name = moduleName;
this.load = load;
this.anonDefine = anonDefine;
this.anonDefineIndex = anonDefineIndex;
this.curDefineIndex = -1;
this.depMap = depMap;
this.defineRedefined = false;
return ParseTreeTransformer.call(this);
}
AMDDefineRegisterTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
AMDDefineRegisterTransformer.prototype.transformVariableDeclaration = AMDDependenciesTransformer.prototype.transformVariableDeclaration;
AMDDefineRegisterTransformer.prototype.transformFunctionDeclaration = AMDDependenciesTransformer.prototype.transformFunctionDeclaration;
AMDDefineRegisterTransformer.prototype.transformFunctionExpression = AMDDependenciesTransformer.prototype.transformFunctionExpression;
AMDDefineRegisterTransformer.prototype.transformCallExpression = function(tree) {
if (this.defineRedefined || !tree.operand.identifierToken || tree.operand.identifierToken.value != 'define')
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
var self = this;
var args = tree.args.args;
var name;
var depArg = -1;
if (args[0].type == 'LITERAL_EXPRESSION' || args[1] && args[1].type == 'ARRAY_LITERAL') {
name = args[0].literalToken && args[0].literalToken.processedValue || true;
if (args[1] && args[1].type == 'ARRAY_LITERAL')
depArg = 1;
}
else if (args[0].type == 'ARRAY_LITERAL') {
depArg = 0;
}
var factoryArg = name && depArg == -1 ? 1 : depArg + 1;
// ignore requires of the wrong form
// skip all named defines until we reach our anonymous define
// then skip all further named defines
if (!args[factoryArg] || ++this.curDefineIndex != this.anonDefineIndex)
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
var factoryTree = args[factoryArg];
// put together normalized deps array
var deps = [];
if (depArg != -1) {
deps = args[depArg].elements.map(function(dep) {
var depVal = dep.literalToken.processedValue;
return self.depMap[depVal] || depVal;
});
// amend deps with any extra dependencies from metadata
deps = deps.concat(this.load.deps.map(function(dep) {
return self.depMap[dep] || dep;
}).filter(function(dep) {
return deps.indexOf(dep) == -1;
}));
}
else if (factoryTree.type == 'FUNCTION_EXPRESSION') {
deps = ['require', 'exports', 'module'].splice(0, factoryTree.parameterList.parameters.length).concat(this.load.deps.map(function(dep) {
return self.depMap[dep] || dep;
}));
}
// normalize CommonJS-style requires in body
var requireIndex = deps.indexOf('require');
if (requireIndex != -1 && factoryTree.type == 'FUNCTION_EXPRESSION') {
var fnParameters = factoryTree.parameterList.parameters;
var reqName = fnParameters[requireIndex] && fnParameters[requireIndex].parameter.binding.identifierToken.value;
var cjsRequireTransformer = new CJSRequireTransformer(reqName, function(v) { return self.depMap[v] || v });
factoryTree.body = cjsRequireTransformer.transformAny(factoryTree.body);
}
// support for single named modules as doubling as anonymous modules
/*
define('jquery', function() {
...
})
->
define('this:name', function() {
...
}), define('jquery', ['this:name'], function(m) { return m; })
*/
var nameAlias = '';
if (name && this.name && name != this.name)
nameAlias = ', define("' + name + '", ["' + this.name + '"], function(m) { return m; })';
// write out the anonymous define as named and dep-normalized
return parseExpression(['define(' + (this.name ? '"' + this.name + '", ' : '') + JSON.stringify(deps) + ', ', ')' + nameAlias + ';'], factoryTree);
};
exports.AMDDefineRegisterTransformer = AMDDefineRegisterTransformer;
function dedupe(deps) {
var newDeps = [];
for (var i = 0, l = deps.length; i < l; i++)
if (newDeps.indexOf(deps[i]) == -1)
newDeps.push(deps[i])
return newDeps;
}
function group(deps) {
var names = [];
var indices = [];
for (var i = 0, l = deps.length; i < l; i++) {
var index = names.indexOf(deps[i]);
if (index === -1) {
names.push(deps[i]);
indices.push([i]);
}
else {
indices[index].push(i);
}
}
return { names: names, indices: indices };
}
// override System instantiate to handle AMD dependencies
exports.attach = function(loader) {
var systemInstantiate = loader.instantiate;
loader.instantiate = function(load) {
var loader = this;
return systemInstantiate.call(this, load).then(function(result) {
if (load.metadata.format == 'amd') {
// extract AMD dependencies using tree parsing
// NB can remove after Traceur 0.0.77
if (!load.source) load.source = ' ';
var compiler = new traceur.Compiler({ script: true, sourceRoot: true });
load.metadata.parseTree = compiler.parse(load.source, load.path);
var depTransformer = new AMDDependenciesTransformer();
depTransformer.transformAny(load.metadata.parseTree);
// we store the results as meta
load.metadata.anonDefine = depTransformer.anonDefine;
load.metadata.anonDefineIndex = depTransformer.anonDefineIndex;
var entry = loader.defined[load.name];
entry.deps = dedupe(depTransformer.deps.concat(load.metadata.deps));
load.metadata.builderExecute = function(require, exports, module) {
var removeDefine = loader.get('@@amd-helpers').createDefine(loader);
// NB source maps, System overwriting skipped here
vm.runInThisContext(load.source);
removeDefine(loader);
var lastModule = loader.get('@@amd-helpers').lastModule;
if (!lastModule.anonDefine && !lastModule.isBundle)
throw new TypeError('AMD module ' + load.name + ' did not define');
if (lastModule.anonDefine)
return lastModule.anonDefine.execute.apply(this, arguments);
lastModule.isBundle = false;
lastModule.anonDefine = null;
};
// first, normalize all dependencies
var normalizePromises = [];
for (var i = 0, l = entry.deps.length; i < l; i++)
normalizePromises.push(Promise.resolve(loader.normalize(entry.deps[i], load.name)));
return Promise.all(normalizePromises).then(function(normalizedDeps) {
entry.normalizedDeps = normalizedDeps;
entry.originalIndices = group(entry.deps);
return {
deps: entry.deps,
execute: result.execute
};
});
}
return result;
});
};
};
exports.remap = function(source, map, fileName) {
var options = { script: true, sourceRoot: true };
var compiler = new traceur.Compiler(options);
var tree = compiler.parse(source, fileName || '');
var transformer = new AMDDependenciesTransformer(map);
tree = transformer.transformAny(tree);
var output = compiler.write(tree);
return Promise.resolve(output);
};
// converts anonymous AMDs into named AMD for the module
exports.compile = function(load, opts, loader) {
var normalize = opts.normalize;
var options = { sourceRoot: true, script: true };
if (opts.sourceMaps)
options.sourceMaps = 'memory';
if (opts.lowResSourceMaps)
options.lowResolutionSourceMap = true;
if (load.metadata.sourceMap)
options.inputSourceMap = load.metadata.sourceMap;
var compiler = new traceur.Compiler(options);
var tree = load.metadata.parseTree || compiler.parse(load.source, load.path);
var transformer = new AMDDefineRegisterTransformer(!opts.anonymous && load.name, load, load.metadata.anonDefine, load.metadata.anonDefineIndex, normalize ? load.depMap : {});
tree = transformer.transformAny(tree);
var output = compiler.write(tree, load.path);
// AMD define extraction via parsing stops on var define redefinitions
// so this creates a natural boundary to allow future folds of this same code through rebundling
return Promise.resolve({
source: '(function() {\nvar define = ' + opts.systemGlobal + '.amdDefine;\n' + output + '\n})();',
sourceMap: compiler.getSourceMap(),
sourceMapOffset: 2
});
};
exports.sfx = function(loader) {
return require('fs').readFileSync(require('path').resolve(__dirname, '../templates/amd-helpers.min.js')).toString();
};

View File

@@ -0,0 +1,243 @@
var path = require('path');
var url = require('url');
var traceur = require('traceur');
var traceurGet = require('../lib/utils').traceurGet;
var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer;
var Script = traceurGet('syntax/trees/ParseTrees.js').Script;
var parseStatements = traceurGet('codegeneration/PlaceholderParser.js').parseStatements;
var parseExpression = traceurGet('codegeneration/PlaceholderParser.js').parseExpression;
var STRING = traceurGet('syntax/TokenType.js').STRING;
var LiteralExpression = traceurGet('syntax/trees/ParseTrees.js').LiteralExpression;
var LiteralToken = traceurGet('syntax/LiteralToken.js').LiteralToken;
var IdentifierExpression = traceurGet('syntax/trees/ParseTrees.js').IdentifierExpression;
var IdentifierToken = traceurGet('syntax/IdentifierToken.js').IdentifierToken;
var BindingIdentifier = traceurGet('syntax/trees/ParseTrees.js').BindingIdentifier;
var createUseStrictDirective = traceurGet('codegeneration/ParseTreeFactory.js').createUseStrictDirective;
var Promise = require('bluebird');
function hasRemoveUseStrict(list) {
for (var i = 0; i < list.length; i++) {
if (!list[i].isDirectivePrologue())
return false;
if (list[i].isUseStrictDirective()) {
list.splice(i, 1);
return true;
}
}
return false;
}
// remap require() statements
function CJSRequireTransformer(requireName, map, mappedRequireName) {
this.requireName = requireName;
this.mappedRequireName = mappedRequireName || requireName;
this.map = map;
this.requires = [];
return ParseTreeTransformer.call(this);
}
CJSRequireTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
CJSRequireTransformer.prototype.transformCallExpression = function(tree) {
// found a require
if (tree.operand.identifierToken && tree.operand.identifierToken.value == this.requireName
&& tree.args.args.length && tree.args.args.length == 1) {
var arg = tree.args.args[0];
var mappedCallExpression;
// require('x');
if (arg.literalToken) {
var requireModule = tree.args.args[0].literalToken.processedValue;
// mirror behaviour at https://github.com/systemjs/systemjs/blob/0.19.8/lib/cjs.js#L50 to remove trailing slash
if (requireModule[requireModule.length - 1] == '/')
requireModule = requireModule.substr(0, requireModule.length - 1);
var requireModuleMapped = this.map && this.map(requireModule) || requireModule;
this.requires.push(requireModule);
mappedCallExpression = parseExpression([this.mappedRequireName + "('" + requireModuleMapped + "')"], []);
}
// require(expr)
else {
mappedCallExpression = parseExpression([this.mappedRequireName + '(', ')'], [arg]);
}
return ParseTreeTransformer.prototype.transformCallExpression.call(this, mappedCallExpression);
}
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
};
CJSRequireTransformer.prototype.transformBindingIdentifier = function(tree) {
if (tree.identifierToken.value == this.requireName)
tree = new BindingIdentifier(tree.location, new IdentifierToken(tree.identifierToken.location, this.mappedRequireName));
return ParseTreeTransformer.prototype.transformBindingIdentifier.call(this, tree);
};
CJSRequireTransformer.prototype.transformIdentifierExpression = function(tree) {
if (tree.identifierToken.value == this.requireName)
tree = new IdentifierExpression(tree.location, new IdentifierToken(tree.identifierToken.location, this.mappedRequireName));
return ParseTreeTransformer.prototype.transformIdentifierExpression.call(this, tree);
};
exports.CJSRequireTransformer = CJSRequireTransformer;
// convert CommonJS into System.registerDynamic
function CJSRegisterTransformer(name, deps, path, optimize, static, globals, systemGlobal) {
this.name = name;
this.deps = deps;
this.path = path;
this.usesFilePaths = false;
this.usesRequireResolve = false;
this.optimize = optimize;
this.static = static;
this.globals = globals;
this.systemGlobal = systemGlobal;
return ParseTreeTransformer.call(this);
}
CJSRegisterTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
CJSRegisterTransformer.prototype.transformCallExpression = function(tree) {
// require.resolve
if (!this.usesRequireResolve && tree.operand.type == 'MEMBER_EXPRESSION' &&
tree.operand.operand.identifierToken && tree.operand.operand.identifierToken.value == '$__require' &&
tree.operand.memberName && tree.operand.memberName.value == 'resolve') {
this.usesRequireResolve = true;
}
return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
}
CJSRegisterTransformer.prototype.transformMemberExpression = function(tree) {
if (this.optimize && tree.operand.operand && tree.operand.operand.identifierToken &&
tree.operand.operand.identifierToken.value == 'process' &&
tree.operand.memberName == 'env' && tree.memberName.value == 'NODE_ENV') {
return new LiteralExpression(tree.location, new LiteralToken(STRING, '"production"', tree.location));
}
return tree;
};
CJSRegisterTransformer.prototype.transformIdentifierExpression = function(tree) {
var value = tree.identifierToken.value;
if (value == '__filename' || value == '__dirname')
this.usesFilePaths = true;
return ParseTreeTransformer.prototype.transformIdentifierExpression.call(this, tree);
};
CJSRegisterTransformer.prototype.transformerBindingIdentifier = function(tree) {
var value = tree.identifierToken.value;
if (value == '__filename' || value == '__dirname')
this.usesFilePaths = true;
return ParseTreeTransformer.prototype.transformBindingIdentifier.call(this, tree);
};
CJSRegisterTransformer.prototype.transformScript = function(tree) {
tree = ParseTreeTransformer.prototype.transformScript.call(this, tree);
var scriptItemList = tree.scriptItemList;
var nl = '\n ';
if (this.usesFilePaths && this.static)
scriptItemList = parseStatements([
"var __filename = '" + this.path + "', __dirname = '" + this.path.split('/').slice(0, -1).join('/') + "';"
]).concat(scriptItemList);
if (this.usesRequireResolve && !this.static) {
scriptItemList = parseStatements([
"$__require.resolve = function(request) { return " + this.systemGlobal + ".get('@@cjs-helpers').requireResolve(request, module.id); };"
]).concat(scriptItemList);
}
if (this.usesFilePaths && !this.static)
scriptItemList = parseStatements([
"var $__pathVars = " + this.systemGlobal + ".get('@@cjs-helpers').getPathVars(module.id), __filename = $__pathVars.filename, __dirname = $__pathVars.dirname;"
]).concat(scriptItemList);
var globalExpression = '';
if (this.globals) {
globalExpression = 'var ';
var first = true;
for (var g in this.globals) {
globalExpression += (first ? '' : ', ') + g + '= $__require("' + this.globals[g] + '")';
first = false;
}
if (first == true)
globalExpression = '';
globalExpression += ';';
}
var useStrict = hasRemoveUseStrict(scriptItemList) ? [createUseStrictDirective()] : [];
scriptItemList = useStrict.concat(parseStatements([
(globalExpression ? globalExpression + nl : '') + 'var define, global = this, GLOBAL = this;'
])).concat(scriptItemList).concat(parseStatements([
'return module.exports;'
]));
// wrap everything in System.register
return new Script(tree.location, parseStatements([
this.systemGlobal + '.registerDynamic(' + (this.name ? '"' + this.name + '", ' : '') + JSON.stringify(this.deps) + ', true, function($__require, exports, module) {',
'});'], scriptItemList));
};
exports.CJSRegisterTransformer = CJSRequireTransformer;
exports.compile = function(load, opts, loader) {
var options = { script: true, sourceRoot: true };
if (opts.sourceMaps)
options.sourceMaps = 'memory';
if (opts.lowResSourceMaps)
options.lowResolutionSourceMap = true;
if (load.metadata.sourceMap)
options.inputSourceMap = load.metadata.sourceMap;
var compiler = new traceur.Compiler(options);
var tree = compiler.parse(load.source, load.path);
var transformer;
var normalize = opts.normalize;
transformer = new CJSRequireTransformer('require', function(dep) { return opts.normalize ? load.depMap[dep] : dep; }, '$__require');
tree = transformer.transformAny(tree);
var deps = opts.normalize ? load.deps.map(function(dep) { return load.depMap[dep]; }) : load.deps;
var globals = {};
for (var g in load.metadata.globals) {
globals[g] = normalize && load.depMap[load.metadata.globals[g]] || load.metadata.globals[g];
}
if (opts.static) {
var path = load.path;
if (path.substr(0, loader.baseURL.length) == loader.baseURL)
path = path.substr(loader.baseURL.length);
}
transformer = new CJSRegisterTransformer(!opts.anonymous && load.name, deps, path, opts.production, opts.static, globals, opts.systemGlobal);
tree = transformer.transformAny(tree);
var output = compiler.write(tree, load.path);
if (opts.systemGlobal != 'System')
output = output.replace(/(^|[^_])System\._nodeRequire/g, function(match, startArg) {
return startArg + opts.systemGlobal + '._nodeRequire';
});
return Promise.resolve({
source: output,
sourceMap: compiler.getSourceMap()
});
};
function remap(source, map, fileName) {
var options = {script: true};
var compiler = new traceur.Compiler(options);
var tree = compiler.parse(source, fileName);
var transformer = new CJSRequireTransformer('require', map);
tree = transformer.transformAny(tree);
var output = compiler.write(tree, fileName);
return Promise.resolve({
source: output
});
}
exports.remap = remap;

View File

@@ -0,0 +1,301 @@
var traceur = require('traceur');
var traceurGet = require('../lib/utils').traceurGet;
var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer;
var ModuleSpecifier = traceurGet('syntax/trees/ParseTrees.js').ModuleSpecifier;
var createStringLiteralToken = traceurGet('codegeneration/ParseTreeFactory.js').createStringLiteralToken;
var InstantiateModuleTransformer = traceurGet('codegeneration/InstantiateModuleTransformer.js').InstantiateModuleTransformer;
var extend = require('../lib/utils').extend;
// patch pending https://github.com/google/traceur-compiler/pull/2053
var createUseStrictDirective = traceurGet('codegeneration/ParseTreeFactory.js').createUseStrictDirective;
InstantiateModuleTransformer.prototype.__proto__.moduleProlog = function() {
return [createUseStrictDirective()];
};
var CollectingErrorReporter = traceurGet('util/CollectingErrorReporter.js').CollectingErrorReporter;
var UniqueIdentifierGenerator = traceurGet('codegeneration/UniqueIdentifierGenerator.js').UniqueIdentifierGenerator;
function TraceurImportNormalizeTransformer(map) {
this.map = map;
return ParseTreeTransformer.apply(this, arguments);
}
TraceurImportNormalizeTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
TraceurImportNormalizeTransformer.prototype.transformModuleSpecifier = function(tree) {
var depName = this.map(tree.token.processedValue) || tree.token.processedValue;
return new ModuleSpecifier(tree.location, createStringLiteralToken(depName));
};
exports.TraceurImportNormalizeTransformer = TraceurImportNormalizeTransformer;
function remap(source, map, fileName) {
var compiler = new traceur.Compiler();
var tree = compiler.parse(source, fileName);
tree = new TraceurImportNormalizeTransformer(map).transformAny(tree);
return Promise.resolve({
source: compiler.write(tree)
});
}
exports.remap = remap;
// override System instantiate to handle esm tracing
exports.attach = function(loader) {
var systemInstantiate = loader.instantiate;
loader.instantiate = function(load) {
// skip plugin loader attachment || non es modules || es modules handled by internal transpilation layer
if (!loader.builder || load.metadata.format != 'esm' || load.metadata.originalSource)
return systemInstantiate.call(this, load);
var compiler = new traceur.Compiler({ script: false, sourceRoot: true });
load.metadata.parseTree = compiler.parse(load.source, load.path);
var depsList = load.metadata.deps.concat([]);
var extractDependencyTransformer = new TraceurImportNormalizeTransformer(function(dep) {
if (depsList.indexOf(dep) == -1)
depsList.push(dep);
});
extractDependencyTransformer.transformAny(load.metadata.parseTree);
return Promise.resolve({
deps: depsList,
execute: null
});
};
};
var versionCheck = true;
// helper functions used by trace
exports.parse = function(source) {
var compiler = new traceur.Compiler({ script: false, sourceRoot: true });
return compiler.parse(source);
};
exports.getDeps = function(tree) {
var deps = [];
var transformer = new TraceurImportNormalizeTransformer(function(dep) {
deps.push(dep);
});
transformer.transformAny(tree);
return deps;
};
exports.compile = function(load, opts, loader) {
var normalize = opts.normalize;
var options;
// transpiler used was a plugin transpiler
if (!load.metadata.originalSource) {
var compiler = new traceur.Compiler({
script: false,
sourceRoot: true,
moduleName: !opts.anonymous,
inputSourceMap: load.metadata.sourceMap,
sourceMaps: opts.sourceMaps && load.path && 'memory',
lowResolutionSourceMap: opts.lowResSourceMaps
});
var tree = load.metadata.parseTree || compiler.parse(load.source, load.path);
if (opts.normalize) {
var transformer = new TraceurImportNormalizeTransformer(function(dep) {
return load.depMap[dep];
});
tree = transformer.transformAny(tree);
}
var errorReporter = new CollectingErrorReporter();
tree.moduleName = load.name;
var transformer = new InstantiateModuleTransformer(new UniqueIdentifierGenerator(), errorReporter, compiler.options_);
tree = transformer.transformAny(tree, load.name);
compiler.throwIfErrors(errorReporter);
var outputSource = compiler.write(tree, load.path);
if (opts.systemGlobal != 'System')
outputSource = outputSource.replace(/System\.register\(/, opts.systemGlobal + '.register(');
return Promise.resolve({
source: outputSource,
sourceMap: compiler.getSourceMap()
});
}
// ... legacy transpilation, to be deprecated with internal transpilation layer
// load.metadata.originalSource set by esm layer to allow plugin -> esm
var source = load.metadata.originalSource || load.source;
// plugin to esm -> ONLY do traceur instantiate conversion, and nothing else
if (load.metadata.loader && load.metadata.format == 'esm') {
var compiler = new traceur.Compiler({
script: false,
sourceRoot: true,
moduleName: !opts.anonymous,
inputSourceMap: load.metadata.sourceMap,
sourceMaps: opts.sourceMaps && 'memory',
lowResolutionSourceMap: opts.lowResSourceMaps
});
var tree = load.metadata.parseTree || compiler.parse(source, load.path);
if (opts.normalize) {
var transformer = new TraceurImportNormalizeTransformer(function(dep) {
return load.depMap[dep];
});
tree = transformer.transformAny(tree);
}
var errorReporter = new CollectingErrorReporter();
tree.moduleName = load.name;
var transformer = new InstantiateModuleTransformer(new UniqueIdentifierGenerator(), errorReporter, compiler.options_);
tree = transformer.transformAny(tree, load.name);
compiler.throwIfErrors(errorReporter);
var outputSource = compiler.write(tree, load.path);
if (opts.systemGlobal != 'System')
outputSource = outputSource.replace(/System\.register\(/, opts.systemGlobal + '.register(');
return Promise.resolve({
source: outputSource,
sourceMap: compiler.getSourceMap()
});
}
return Promise.resolve(global[loader.transpiler == 'typescript' ? 'ts' : loader.transpiler] || loader.pluginLoader.import(loader.transpiler))
.then(function(transpiler) {
if (transpiler.__useDefault)
transpiler = transpiler['default'];
if (transpiler.Compiler) {
options = loader.traceurOptions || {};
options.modules = 'instantiate';
options.script = false;
options.sourceRoot = true;
options.moduleName = !opts.anonymous;
if (opts.sourceMaps)
options.sourceMaps = 'memory';
if (opts.lowResSourceMaps)
options.lowResolutionSourceMap = true;
if (load.metadata.sourceMap)
options.inputSourceMap = load.metadata.sourceMap;
var compiler = new transpiler.Compiler(options);
var tree = compiler.parse(source, load.path);
var transformer = new TraceurImportNormalizeTransformer(function(dep) {
return normalize ? load.depMap[dep] : dep;
});
tree = transformer.transformAny(tree);
tree = compiler.transform(tree, load.name);
var outputSource = compiler.write(tree, load.path);
if (outputSource.match(/\$traceurRuntime/))
load.metadata.usesTraceurRuntimeGlobal = true;
return Promise.resolve({
source: outputSource,
sourceMap: compiler.getSourceMap()
});
}
else if (transpiler.createLanguageService) {
var options = loader.typescriptOptions || {};
if (options.target === undefined)
options.target = transpiler.ScriptTarget.ES5;
options.module = transpiler.ModuleKind.System;
var transpileOptions = {
compilerOptions: options,
renamedDependencies: load.depMap,
fileName: load.path,
moduleName: !opts.anonymous && load.name
};
var transpiled = transpiler.transpileModule(source, transpileOptions);
return Promise.resolve({
source: transpiled.outputText,
sourceMap: transpiled.sourceMapText
});
}
else {
if (versionCheck) {
var babelVersion = transpiler.version;
if (babelVersion.split('.')[0] > 5)
console.log('Warning - using Babel ' + babelVersion + '. This version of SystemJS builder is designed to run against Babel 5.');
versionCheck = false;
}
options = extend({}, loader.babelOptions || {});
options.modules = 'system';
if (opts.sourceMaps)
options.sourceMap = true;
if (load.metadata.sourceMap)
options.inputSourceMap = load.metadata.sourceMap;
options.filename = load.path;
options.filenameRelative = load.name;
options.sourceFileName = load.path;
options.keepModuleIdExtensions = true;
options.code = true;
options.ast = false;
options.moduleIds = !opts.anonymous;
options.externalHelpers = true;
if (transpiler.version.match(/^4/))
options.returnUsedHelpers = true;
else if (transpiler.version.match(/^5\.[01234]\./))
options.metadataUsedHelpers = true;
if (normalize)
options.resolveModuleSource = function(dep) {
return load.depMap[dep] || dep;
};
var output = transpiler.transform(source, options);
var usedHelpers = output.usedHelpers || output.metadata && output.metadata.usedHelpers;
if ((!options.optional || options.optional.indexOf('runtime') == -1) && usedHelpers.length)
load.metadata.usesBabelHelpersGlobal = true;
// pending Babel v5, we need to manually map the helpers
if (options.optional && options.optional.indexOf('runtime') != -1)
load.deps.forEach(function(dep) {
if (dep.match(/^babel-runtime/))
output.code = output.code.replace(dep, load.depMap[dep]);
});
// clear options for reuse
delete options.filenameRelative;
delete options.sourceFileName;
return Promise.resolve({
source: output.code,
sourceMap: output.map
});
}
})
.then(function(output) {
if (opts.systemGlobal != 'System')
output.source = output.source.replace(/System\.register\(/, opts.systemGlobal + '.register(');
return output;
});
};

View File

@@ -0,0 +1,151 @@
var traceur = require('traceur');
var traceurGet = require('../lib/utils').traceurGet;
var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer;
var parseStatements = traceurGet('codegeneration/PlaceholderParser.js').parseStatements;
var parseStatement = traceurGet('codegeneration/PlaceholderParser.js').parseStatement;
var parseExpression = traceurGet('codegeneration/PlaceholderParser.js').parseExpression;
var Script = traceurGet('syntax/trees/ParseTrees.js').Script;
var FunctionBody = traceurGet('syntax/trees/ParseTrees.js').FunctionBody;
// wraps global scripts
function GlobalTransformer(name, deps, exportName, globals, systemGlobal) {
this.name = name;
this.deps = deps;
this.exportName = exportName;
this.varGlobals = [];
this.fnGlobals = [];
this.globals = globals;
this.inOuterScope = true;
this.systemGlobal = systemGlobal;
return ParseTreeTransformer.call(this);
}
GlobalTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
GlobalTransformer.prototype.transformVariableDeclarationList = function(tree) {
this.isVarDeclaration = tree.declarationType == 'var';
return ParseTreeTransformer.prototype.transformVariableDeclarationList.call(this, tree);
}
GlobalTransformer.prototype.transformVariableDeclaration = function(tree) {
tree = ParseTreeTransformer.prototype.transformVariableDeclaration.call(this, tree);
if (!this.inOuterScope || !this.isVarDeclaration)
return tree;
var varName = tree.lvalue.identifierToken.value;
if (this.varGlobals.indexOf(varName) == -1)
this.varGlobals.push(varName);
return tree;
}
GlobalTransformer.prototype.enterScope = function() {
var revert = this.inOuterScope;
this.inOuterScope = false;
return revert;
}
GlobalTransformer.prototype.exitScope = function(revert) {
if (revert)
this.inOuterScope = true;
}
GlobalTransformer.prototype.transformFunctionDeclaration = function(tree) {
// named functions in outer scope are globals
if (this.inOuterScope && tree.name)
this.fnGlobals.push(tree.name.identifierToken.value);
var revert = this.enterScope();
tree = ParseTreeTransformer.prototype.transformFunctionDeclaration.call(this, tree);
this.exitScope(revert);
return tree;
}
GlobalTransformer.prototype.transformFunctionExpression = function(tree) {
var revert = this.enterScope();
tree = ParseTreeTransformer.prototype.transformFunctionExpression.call(this, tree);
this.exitScope(revert);
return tree;
}
GlobalTransformer.prototype.transformScript = function(tree) {
tree = ParseTreeTransformer.prototype.transformScript.call(this, tree);
// hoist function declaration assignments to the global
var scriptItemList = this.fnGlobals.map(function(g) {
return parseStatement(['this["' + g + '"] = ' + g + ';']);
})
// for globals defined as "var x = 5;" in outer scope, add "this.x = x;" at end
.concat(this.varGlobals.map(function(g) {
return parseStatement(['var ' + g + ' = this["' + g + '"];']);
}))
.concat(tree.scriptItemList).concat(this.varGlobals.map(function(g) {
return parseStatement(['this["' + g + '"] = ' + g + ';']);
}));
var wrapperFunction = parseExpression(['function() {}'])
wrapperFunction.location = null;
wrapperFunction.body = new FunctionBody(null, scriptItemList);
var globalExpression;
if (this.globals) {
var nl = '\n ';
globalExpression = '{';
var first = true;
for (var g in this.globals) {
if (!this.globals[g])
continue;
globalExpression += (first ? '' : ',') + nl + '"' + g + '": $__require("' + this.globals[g] + '")';
first = false;
}
globalExpression += nl + '}';
}
return new Script(tree.location, parseStatements([
this.systemGlobal + '.registerDynamic(' + (this.name ? '"' + this.name + '", ' : '') + JSON.stringify(this.deps) + ', false, function($__require, $__exports, $__module) {\n'
+ 'var _retrieveGlobal = ' + this.systemGlobal + '.get("@@global-helpers").prepareGlobal($__module.id, '
+ (this.exportName ? '"' + this.exportName + '"' : 'null') + ', ' + (globalExpression ? globalExpression : 'null') + ');\n'
+ ' (',
')();\n'
+ ' return _retrieveGlobal();\n'
+ '});'], wrapperFunction));
}
exports.GlobalTransformer = GlobalTransformer;
exports.compile = function(load, opts, loader) {
var options = { script: true, sourceRoot: true };
if (opts.sourceMaps)
options.sourceMaps = 'memory';
if (opts.lowResSourceMaps)
options.lowResolutionSourceMap = true;
if (load.metadata.sourceMap)
options.inputSourceMap = load.metadata.sourceMap;
var compiler = new traceur.Compiler(options);
var tree = compiler.parse(load.source, load.path);
var deps = opts.normalize ? load.deps.map(function(dep) { return load.depMap[dep]; }) : load.deps;
// send normalized globals into the transformer
var normalizedGlobals
if (load.metadata.globals) {
normalizedGlobals = {};
for (var g in load.metadata.globals)
normalizedGlobals[g] = opts.normalize ? load.depMap[load.metadata.globals[g]] : load.metadata.globals[g];
}
var transformer = new GlobalTransformer(!opts.anonymous && load.name, deps, load.metadata.exports, normalizedGlobals, opts.systemGlobal);
tree = transformer.transformAny(tree);
var output = compiler.write(tree, load.path);
return Promise.resolve({
source: output,
sourceMap: compiler.getSourceMap()
});
};
exports.sfx = function(loader) {
return require('fs').readFileSync(require('path').resolve(__dirname, '../templates/global-helpers.min.js')).toString();
};

View File

@@ -0,0 +1,61 @@
function hasProperties(obj) {
for (var p in obj)
return true;
return false;
}
exports.compile = function(load, opts, loader) {
try {
var json = JSON.parse(load.source)
}
catch(e) {
throw new Error('Unable to parse JSON module ' + load.name + ' contents as JSON.');
}
if (load.isPackageConfig)
json = optimizePackageConfig(json);
return Promise.resolve({
source: opts.systemGlobal + '.registerDynamic(' + (opts.anonymous ? '' : '"' + load.name + '", ') + '[], false, function() {\n' +
' return ' + JSON.stringify(json, null, 2).replace(/\n/g, '\n ') + ';\n' +
'});\n'
});
};
// because bundles are for the browser only
// if this is a package config file json we are compiling
// then we can optimize out the node-only configurations to make it smaller
function optimizePackageConfig(json) {
if (json.systemjs)
json = json.systemjs;
// remove non SystemJS package config properties
var loaderConfigProperties = ['baseDir', 'defaultExtension', 'format', 'meta', 'map', 'main'];
for (var p in json)
if (loaderConfigProperties.indexOf(p) == -1)
delete json[p];
if (json.map && !json.map['@env']) {
Object.keys(json.map).forEach(function(target) {
var mapped = json.map[target];
if (typeof mapped == 'string' && mapped.substr(0, 6) == '@node/')
delete json.map[target];
if (typeof mapped == 'object') {
Object.keys(mapped).forEach(function(condition) {
if (condition == 'node')
delete mapped[condition];
});
if (!hasProperties(mapped))
delete json.map[target];
}
});
if (!hasProperties(json.map))
delete json.map;
}
return json;
}

View File

@@ -0,0 +1,120 @@
var traceur = require('traceur');
var traceurGet = require('../lib/utils').traceurGet;
var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer;
var CallExpression = traceurGet('syntax/trees/ParseTrees.js').CallExpression;
var ArgumentList = traceurGet('syntax/trees/ParseTrees.js').ArgumentList;
var ArrayLiteral = traceurGet('syntax/trees/ParseTrees.js').ArrayLiteral;
var createStringLiteral = traceurGet('codegeneration/ParseTreeFactory.js').createStringLiteral;
var parseExpression = traceurGet('codegeneration/PlaceholderParser.js').parseExpression;
var FunctionBody = traceurGet('syntax/trees/ParseTrees.js').FunctionBody;
// converts anonymous System.register([] into named System.register('name', [], ...
// NB need to add that if no anon, last named must define this module
// also this should be rewritten with a proper parser!
function RegisterTransformer(moduleName, map, systemGlobal) {
this.name = moduleName;
this.hasAnonRegister = false;
this.map = map;
this.systemOperand = parseExpression([systemGlobal + '.register']);
this.usesModuleName = false;
return ParseTreeTransformer.call(this);
}
RegisterTransformer.prototype = Object.create(ParseTreeTransformer.prototype);
RegisterTransformer.prototype.transformCallExpression = function(tree) {
tree = ParseTreeTransformer.prototype.transformCallExpression.call(this, tree);
if (tree.operand.type == 'MEMBER_EXPRESSION'
&& tree.operand.memberName.value == 'register'
&& tree.operand.operand.type == 'IDENTIFIER_EXPRESSION'
&& tree.operand.operand.identifierToken.value == 'System'
&& tree.args) {
var firstArg = tree.args.args[0];
var declare;
if (firstArg.type == 'ARRAY_LITERAL')
declare = tree.args.args[1];
else
declare = tree.args.args[2];
// contains a __moduleName reference, while System.register declare function doesn't have a __moduleName argument
// so add it
// this is backwards compatibility for https://github.com/systemjs/builder/issues/416
if (this.usesModuleName && declare && declare.parameterList && declare.parameterList.parameters.length == 1) {
var newDeclare = parseExpression(['function() {}']);
newDeclare.location = declare.location;
newDeclare.body = new FunctionBody(declare.body.location, declare.body.statements);
newDeclare.parameterList.parameters.push(declare.parameterList.parameters[0]);
newDeclare.parameterList.parameters.push(parseExpression(['__moduleName']));
declare = newDeclare;
}
// System.register(deps, declare)
if (firstArg.type == 'ARRAY_LITERAL') {
if (this.hasAnonRegister) {
throw 'Source ' + this.name + ' has multiple anonymous System.register calls.';
}
// normalize dependencies in array
var map = this.map;
var normalizedDepArray = new ArrayLiteral(firstArg.location, firstArg.elements.map(function(el) {
var str = el.literalToken.value.toString();
return createStringLiteral(map(str.substr(1, str.length - 2)));
}));
this.hasAnonRegister = true;
var newArgs = this.name ? [createStringLiteral(this.name), normalizedDepArray, declare] : [normalizedDepArray, declare];
return new CallExpression(tree.location, this.systemOperand, new ArgumentList(tree.args.location, newArgs));
}
// System.register(name, deps, declare)
else {
var args = tree.args.args.concat([]);
args.splice(2, 1, declare);
return new CallExpression(tree.location, this.systemOperand, args);
}
}
return tree;
};
RegisterTransformer.prototype.transformIdentifierExpression = function(tree) {
if (tree.identifierToken.value == '__moduleName')
this.usesModuleName = true;
return ParseTreeTransformer.prototype.transformIdentifierExpression.call(this, tree);
};
exports.compile = function(load, opts, loader) {
var options = { script: true, sourceRoot: true };
if (opts.sourceMaps)
options.sourceMaps = 'memory';
if (opts.lowResSourceMaps)
options.lowResolutionSourceMap = true;
if (load.metadata.sourceMap)
options.inputSourceMap = load.metadata.sourceMap;
var compiler = new traceur.Compiler(options);
var tree = compiler.parse(load.source, load.path);
var transformer = new RegisterTransformer(!opts.anonymous && load.name, function(dep) { return opts.normalize ? load.depMap[dep] : dep; }, opts.systemGlobal);
tree = transformer.transformAny(tree);
// if the transformer didn't find an anonymous System.register
// then this is a bundle itself
// so we need to reconstruct files with load.metadata.execute etc
// if this comes up, we can tackle it or work around it
if (!transformer.hasAnonRegister)
throw new TypeError('Source ' + load.path + ' is already a bundle file, so can\'t be built as a module.');
var output = compiler.write(tree, load.path);
return Promise.resolve({
source: output,
sourceMap: compiler.getSourceMap()
});
};