diff --git a/lib/6to5/templates/register.js b/lib/6to5/templates/system.js similarity index 100% rename from lib/6to5/templates/register.js rename to lib/6to5/templates/system.js diff --git a/lib/6to5/transformation/modules/_default.js b/lib/6to5/transformation/modules/_default.js index 927a03cd7b..1f4ab6a32c 100644 --- a/lib/6to5/transformation/modules/_default.js +++ b/lib/6to5/transformation/modules/_default.js @@ -5,12 +5,11 @@ var util = require("../../util"); var t = require("../../types"); var _ = require("lodash"); -function DefaultFormatter(file) { - this.exports = []; - this.file = file; +function DefaultFormatter(file, illegalRemapping) { + this.file = file; this.localExports = this.getLocalExports(); - this.remapAssignments(); + this.remapAssignments(illegalRemapping); } DefaultFormatter.prototype.getLocalExports = function () { @@ -28,26 +27,42 @@ DefaultFormatter.prototype.getLocalExports = function () { return localExports; }; -DefaultFormatter.prototype.remapAssignments = function () { +DefaultFormatter.prototype.remapAssignments = function (illegal) { var localExports = this.localExports; + var remap = function (node) { + return t.assignmentExpression( + "=", + node.left, + t.assignmentExpression( + node.operator, + t.memberExpression(t.identifier("exports"), node.left), + node.right + ) + ); + }; + + var throwIllegal = function (node) { + // todo!! + }; + + var isLocalReference = function (node, scope) { + var left = node.left; + var name = left.name; + return t.isIdentifier(left) && localExports[name] && localExports[name] === scope.get(name, true); + }; + traverse(this.file.ast, { enter: function (node, parent, scope) { if (t.isExportDeclaration(node)) return false; if (t.isAssignmentExpression(node)) { - var left = node.left; - var name = left.name; - if (t.isIdentifier(left) && localExports[name] && localExports[name] === scope.get(name, true)) { - return t.assignmentExpression( - "=", - left, - t.assignmentExpression( - node.operator, - t.memberExpression(t.identifier("exports"), left), - node.right - ) - ); + if (isLocalReference(node, scope)) { + if (illegal) { + throwIllegal(node); + } else { + return remap(node); + } } } } diff --git a/lib/6to5/transformation/modules/system.js b/lib/6to5/transformation/modules/system.js index a06706f8b1..5e035d3c3f 100644 --- a/lib/6to5/transformation/modules/system.js +++ b/lib/6to5/transformation/modules/system.js @@ -1,73 +1,64 @@ module.exports = SystemFormatter; -var util = require("../../util"); -var t = require("../../types"); -var traverse = require("../../traverse"); -var _ = require("lodash"); +var DefaultFormatter = require("./_default"); +var traverse = require("../../traverse"); +var util = require("../../util"); +var t = require("../../types"); +var _ = require("lodash"); var SETTER_MODULE_NAMESPACE = t.identifier("m"); var PRIVATE_MODULE_NAME_IDENTIFIER = t.identifier("__moduleName"); -var DEFAULT_IDENTIFIER = t.identifier("default"); var NULL_SETTER = t.literal(null); function SystemFormatter(file) { - this.moduleNameLiteral = null; + DefaultFormatter.call(this, file, true); + this.exportedStatements = []; this.moduleDependencies = {}; this.importedVariables = {}; - + this.moduleNameLiteral = t.literal(this.getModuleName()); this.exportIdentifier = file.generateUidIdentifier("export"); - this.file = file; - - /** - * @type Function - * @param {Array} args - The arguments of the "_export(...args)" function - * @return {Object} The expression statement with the call expression. - */ - this._makeExportStatements = _.compose( - t.expressionStatement, - // will generate the call expression : _export(...args) - _.partial(t.callExpression, this.exportIdentifier) - ); } -SystemFormatter.prototype.import = - SystemFormatter.prototype.export = function (node, nodes) { - nodes.push(node); - }; +util.inherits(SystemFormatter, DefaultFormatter); + +SystemFormatter.prototype.importDeclaration = +SystemFormatter.prototype.exportDeclaration = function (node, nodes) { + nodes.push(node); +}; SystemFormatter.prototype.importSpecifier = - SystemFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { - if (!nodes.length) nodes.push(node); - }; +SystemFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { + if (!nodes.length) nodes.push(node); +}; + +SystemFormatter.prototype._makeExportStatements = function (args) { + return t.expressionStatement(t.callExpression(this.exportIdentifier, args)); +}; SystemFormatter.prototype.transform = function (ast) { - - var systemTransform = this; - - // extract the module name - this.moduleNameLiteral = t.literal( - this.file.opts.filename.replace(/^.*\//, "").replace(/\..*$/, "") - ); + var self = this; // Post extraction of the import/export declaration - traverse(ast, function (node) { - var replacementNode = null; + traverse(ast, { + enter: function (node) { + var replacementNode = null; - /** - * Process the current node with an extractor. - * @param {Function} extractor Extract the node data - * @returns {*} Can be a `node` (for replacement), void 0 (for removing) - * or false. - */ - function processTheNode(extractor) { - var result = extractor.call(systemTransform, node); - result = (result === void 0) ? [] : result; - replacementNode = result || replacementNode; - return !!replacementNode; - } + /** + * Process the current node with an extractor. + * + * @param {Function} extractor Extract the node data + * @returns {*} Can be a `node` (for replacement), undefined (for removing) or false. + */ - _.some([ + function processTheNode(extractor) { + var result = extractor.call(self, node); + result = (result === undefined) ? [] : result; + replacementNode = result || replacementNode; + return !!replacementNode; + } + + _.some([ // Import SystemFormatter.prototype._extractImportSpecifiers, SystemFormatter.prototype._extractImport, @@ -77,11 +68,10 @@ SystemFormatter.prototype.transform = function (ast) { SystemFormatter.prototype._extractExportVariableDeclaration, SystemFormatter.prototype._extractExportFunctionDeclaration, SystemFormatter.prototype._extractExportSpecifiers - ], - processTheNode - ); + ], processTheNode); - return replacementNode; + return replacementNode; + } }); // Other @@ -91,32 +81,24 @@ SystemFormatter.prototype.transform = function (ast) { this._wrapInSystemRegisterCallExpression(ast); }; -// // Import extraction -// SystemFormatter.prototype._extractImportSpecifiers = function (node) { + var self = this; - var systemTransform = this; - - if (!(t.isImportDeclaration(node) && node.specifiers && node.specifiers.length )) { + if (!(t.isImportDeclaration(node) && node.specifiers && node.specifiers.length)) { return false; } _.each(node.specifiers, function (specifier) { - var variableName = t.getSpecifierName(specifier); - if (specifier.default) { - specifier.id = DEFAULT_IDENTIFIER; - } - var right = SETTER_MODULE_NAMESPACE; if (!t.isImportBatchSpecifier(specifier)) { right = t.memberExpression(right, specifier.id); } - systemTransform.importedVariables[variableName.name] = true; - systemTransform._addImportStatement(node.source.value, t.expressionStatement( + self.importedVariables[variableName.name] = true; + self._addImportStatement(node.source.value, t.expressionStatement( t.assignmentExpression("=", variableName, right) )); @@ -124,16 +106,14 @@ SystemFormatter.prototype._extractImportSpecifiers = function (node) { }; SystemFormatter.prototype._extractImport = function (node) { - if (!(t.isImportDeclaration(node))) { + if (!t.isImportDeclaration(node)) { return false; } this._addImportStatement(node.source.value); }; -// // Export extraction -// SystemFormatter.prototype._extractExportDefault = function (node) { if (!(t.isExportDeclaration(node) && node.default)) { @@ -141,7 +121,6 @@ SystemFormatter.prototype._extractExportDefault = function (node) { } var declar = node.declaration; - var variableName = DEFAULT_IDENTIFIER.name; var returnNode; if (t.isFunction(declar)) { @@ -152,14 +131,14 @@ SystemFormatter.prototype._extractExportDefault = function (node) { declar = declar.id; } - this._addToExportStatements(variableName, declar); + this._addToExportStatements("default", declar); return returnNode; }; SystemFormatter.prototype._extractExportVariableDeclaration = function (node) { - var systemTransform = this; - var declar = node.declaration; + var self = this; + var declar = node.declaration; if (!(t.isExportDeclaration(node) && t.isVariableDeclaration(declar))) { return false; @@ -167,7 +146,7 @@ SystemFormatter.prototype._extractExportVariableDeclaration = function (node) { function separateDeclarationAndInit(memo, varDeclar) { memo.varDeclaration.push(_.omit(varDeclar, "init")); - systemTransform._addToExportStatements(varDeclar.id.name, varDeclar); + self._addToExportStatements(varDeclar.id.name, t.assignmentExpression("=", varDeclar.id, varDeclar.init)); return memo; } @@ -192,24 +171,22 @@ SystemFormatter.prototype._extractExportFunctionDeclaration = function (node) { }; SystemFormatter.prototype._extractExportSpecifiers = function (node) { - var systemTransform = this; + var self = this; - if (!( t.isExportDeclaration(node) && node.specifiers )) { + if (!(t.isExportDeclaration(node) && node.specifiers)) { return false; } _.each(node.specifiers, function (specifier) { - // Run each, break when one is true. _.some([ SystemFormatter.prototype._extractExportBatch, SystemFormatter.prototype._extractExportFrom, SystemFormatter.prototype._extractExportNamed ], function (extractor) { - var result = extractor.call(systemTransform, specifier, node); - return result === void 0 || result; + var result = extractor.call(self, specifier, node); + return result === undefined || result; }); - }); // Note: here we don't care about the node replacement. @@ -218,7 +195,6 @@ SystemFormatter.prototype._extractExportSpecifiers = function (node) { }; SystemFormatter.prototype._extractExportBatch = function (specifier, node) { - if (!(node.source && t.isExportBatchSpecifier(specifier))) { return false; } @@ -228,7 +204,6 @@ SystemFormatter.prototype._extractExportBatch = function (specifier, node) { }; SystemFormatter.prototype._extractExportFrom = function (specifier, node) { - // Weak test here... if (!(node.source)) { return false; @@ -249,7 +224,6 @@ SystemFormatter.prototype._extractExportFrom = function (specifier, node) { }; SystemFormatter.prototype._extractExportNamed = function (specifier) { - // Last case... // Dunno what to test here... @@ -257,9 +231,7 @@ SystemFormatter.prototype._extractExportNamed = function (specifier) { this._addToExportStatements(variableName.name, specifier.id); }; -// // Utils collection handler -// SystemFormatter.prototype._addToExportStatements = function (name, identifier) { this.exportedStatements.push( @@ -267,34 +239,21 @@ SystemFormatter.prototype._addToExportStatements = function (name, identifier) { ); }; -/** - * Generate a export wildcard expression - * /!\ this is a hack over the existing "exports-wildcard" template - * @param objectIdentifier - * @returns the export wildcard expression - * @private - */ SystemFormatter.prototype._makeExportWildcard = function (objectIdentifier) { + var leftIdentifier = t.identifier("i"); + var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true); - var exportStatement = util.template("exports-wildcard", { - OBJECT: objectIdentifier - }, true); + var left = t.variableDeclaration("var", [ + t.variableDeclarator(leftIdentifier) + ]); - delete exportStatement.expression.callee.expression._scopeReferences; + var right = objectIdentifier; - var forStatement = exportStatement.expression.callee.expression.body.body[0]; - var iteratorIdentifier = forStatement.left.declarations[0].id; - var target = t.memberExpression( - forStatement.right, - iteratorIdentifier, - true - ); + var block = t.blockStatement([ + this._makeExportStatements([leftIdentifier, valIdentifier]) + ]); - forStatement.body.body = [ - this._makeExportStatements([iteratorIdentifier, target]) - ]; - - return exportStatement; + return t.forInStatement(left, right, block); }; SystemFormatter.prototype._addImportStatement = function (name, importStatement) { @@ -302,16 +261,12 @@ SystemFormatter.prototype._addImportStatement = function (name, importStatement) importStatement && this.moduleDependencies[name].push(importStatement); }; -// // Additional body content -// SystemFormatter.prototype._prependImportVariables = function (ast) { - var declaredSetters = _(this.importedVariables).keys().map(function (name) { - return _.compose(t.variableDeclarator, t.identifier)(name); - } - ).value(); + return _.compose(t.variableDeclarator, t.identifier)(name); + }).value(); if (declaredSetters.length) { ast.program.body.splice(1, 0, t.variableDeclaration("var", declaredSetters)); @@ -344,7 +299,6 @@ SystemFormatter.prototype._buildSetters = function () { }; SystemFormatter.prototype._appendModuleReturnStatement = function (ast) { - // generate the execute function expression var executeFunctionExpression = t.functionExpression( null, [], t.blockStatement(this.exportedStatements) @@ -370,7 +324,7 @@ SystemFormatter.prototype._wrapInSystemRegisterCallExpression = function (ast) { .keys(this.moduleDependencies) .map(t.literal); - var runner = util.template("register", { + var runner = util.template("system", { MODULE_NAME: this.moduleNameLiteral, MODULE_DEPENDENCIES: t.arrayExpression(moduleDependencyNames), MODULE_BODY: t.functionExpression( @@ -378,7 +332,7 @@ SystemFormatter.prototype._wrapInSystemRegisterCallExpression = function (ast) { [this.exportIdentifier], t.blockStatement(body) ) - }); + }, true); - program.body = [t.expressionStatement(runner)]; + program.body = [runner]; }; diff --git a/test/fixtures/transformation/es6-modules-system/exports-default/expected.js b/test/fixtures/transformation/es6-modules-system/exports-default/expected.js index 934c42e2f3..d7f15bc3db 100644 --- a/test/fixtures/transformation/es6-modules-system/exports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-default/expected.js @@ -1,12 +1,14 @@ -System.register("actual", [], function (_export) { +System.register("es6-modules-system/exports-default/expected", [], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/exports-default/expected"; function _anonymous() {} - var _anonymous2; + function _anonymous2() {} + function foo() {} - var Foo; + function Foo() {} + return { setters: [], execute: function () { @@ -20,11 +22,11 @@ System.register("actual", [], function (_export) { _export("default", _anonymous); - _export("default", _anonymous2 = function _anonymous2() {}); + _export("default", _anonymous2); _export("default", foo); - _export("default", Foo = function Foo() {}); + _export("default", Foo); } }; }); diff --git a/test/fixtures/transformation/es6-modules-system/exports-from/expected.js b/test/fixtures/transformation/es6-modules-system/exports-from/expected.js index b1ff79e7e4..4586168df1 100644 --- a/test/fixtures/transformation/es6-modules-system/exports-from/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-from/expected.js @@ -1,15 +1,13 @@ -System.register("actual", ["foo"], function (_export) { +System.register("es6-modules-system/exports-from/expected", ["foo"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/exports-from/expected"; return { setters: [function (m) { - (function (obj) { - for (var i in obj) { - _export(i, obj[i]); - } - })(m); + for (var i in m) { + _export(i, m[i]); + } _export("foo", m.foo); diff --git a/test/fixtures/transformation/es6-modules-system/exports-named/expected.js b/test/fixtures/transformation/es6-modules-system/exports-named/expected.js index 716fd14641..2a85134834 100644 --- a/test/fixtures/transformation/es6-modules-system/exports-named/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-named/expected.js @@ -1,7 +1,7 @@ -System.register("actual", [], function (_export) { +System.register("es6-modules-system/exports-named/expected", [], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/exports-named/expected"; return { setters: [], diff --git a/test/fixtures/transformation/es6-modules-system/exports-variable/expected.js b/test/fixtures/transformation/es6-modules-system/exports-variable/expected.js index 39fe8267e1..5fe0f898f6 100644 --- a/test/fixtures/transformation/es6-modules-system/exports-variable/expected.js +++ b/test/fixtures/transformation/es6-modules-system/exports-variable/expected.js @@ -1,7 +1,7 @@ -System.register("actual", [], function (_export) { +System.register("es6-modules-system/exports-variable/expected", [], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/exports-variable/expected"; var foo; var foo2; @@ -10,8 +10,6 @@ System.register("actual", [], function (_export) { var foo5; var foo6; function foo7() {} - _export("foo7", foo7); - var foo8; return { setters: [], @@ -20,11 +18,11 @@ System.register("actual", [], function (_export) { _export("foo2", foo2 = function () {}); - _export("foo3", foo3); + _export("foo3", foo3 = undefined); _export("foo4", foo4 = 2); - _export("foo5", foo5); + _export("foo5", foo5 = undefined); _export("foo6", foo6 = 3); diff --git a/test/fixtures/transformation/es6-modules-system/hoist-function-exports/expected.js b/test/fixtures/transformation/es6-modules-system/hoist-function-exports/expected.js index 6e20c45e3d..3434b17c6c 100644 --- a/test/fixtures/transformation/es6-modules-system/hoist-function-exports/expected.js +++ b/test/fixtures/transformation/es6-modules-system/hoist-function-exports/expected.js @@ -1,13 +1,12 @@ -System.register("actual", ["./evens"], function (_export) { +System.register("es6-modules-system/hoist-function-exports/expected", ["./evens"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/hoist-function-exports/expected"; var isEven; function nextOdd(n) { return isEven(n) ? n + 1 : n + 2; } - _export("nextOdd", nextOdd); var isOdd; return { @@ -15,6 +14,8 @@ System.register("actual", ["./evens"], function (_export) { isEven = m.isEven; }], execute: function () { + _export("nextOdd", nextOdd); + _export("isOdd", isOdd = (function (isEven) { return function (n) { return !isEven(n); diff --git a/test/fixtures/transformation/es6-modules-system/imports-default/expected.js b/test/fixtures/transformation/es6-modules-system/imports-default/expected.js index c2bd28f729..1cc8cfea3d 100644 --- a/test/fixtures/transformation/es6-modules-system/imports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-system/imports-default/expected.js @@ -1,7 +1,7 @@ -System.register("actual", ["foo"], function (_export) { +System.register("es6-modules-system/imports-default/expected", ["foo"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/imports-default/expected"; var foo; return { diff --git a/test/fixtures/transformation/es6-modules-system/imports-glob/expected.js b/test/fixtures/transformation/es6-modules-system/imports-glob/expected.js index cb6d64cc04..077c6046e1 100644 --- a/test/fixtures/transformation/es6-modules-system/imports-glob/expected.js +++ b/test/fixtures/transformation/es6-modules-system/imports-glob/expected.js @@ -1,7 +1,7 @@ -System.register("actual", ["foo"], function (_export) { +System.register("es6-modules-system/imports-glob/expected", ["foo"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/imports-glob/expected"; var foo; return { diff --git a/test/fixtures/transformation/es6-modules-system/imports-mixing/expected.js b/test/fixtures/transformation/es6-modules-system/imports-mixing/expected.js index 77c3348166..88537f6b14 100644 --- a/test/fixtures/transformation/es6-modules-system/imports-mixing/expected.js +++ b/test/fixtures/transformation/es6-modules-system/imports-mixing/expected.js @@ -1,7 +1,7 @@ -System.register("actual", ["foo"], function (_export) { +System.register("es6-modules-system/imports-mixing/expected", ["foo"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/imports-mixing/expected"; var foo, xyz; return { diff --git a/test/fixtures/transformation/es6-modules-system/imports-named/expected.js b/test/fixtures/transformation/es6-modules-system/imports-named/expected.js index 1610dafb58..0db8e3a0e5 100644 --- a/test/fixtures/transformation/es6-modules-system/imports-named/expected.js +++ b/test/fixtures/transformation/es6-modules-system/imports-named/expected.js @@ -1,7 +1,7 @@ -System.register("actual", ["foo"], function (_export) { +System.register("es6-modules-system/imports-named/expected", ["foo"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/imports-named/expected"; var bar, baz, xyz; return { diff --git a/test/fixtures/transformation/es6-modules-system/imports/expected.js b/test/fixtures/transformation/es6-modules-system/imports/expected.js index 809982b1c2..9aa94f7fe2 100644 --- a/test/fixtures/transformation/es6-modules-system/imports/expected.js +++ b/test/fixtures/transformation/es6-modules-system/imports/expected.js @@ -1,7 +1,7 @@ -System.register("actual", ["foo", "foo-bar", "./directory/foo-bar"], function (_export) { +System.register("es6-modules-system/imports/expected", ["foo", "foo-bar", "./directory/foo-bar"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/imports/expected"; return { setters: [null, null, null], diff --git a/test/fixtures/transformation/es6-modules-system/overview/expected.js b/test/fixtures/transformation/es6-modules-system/overview/expected.js index 420d145069..6cb5b97950 100644 --- a/test/fixtures/transformation/es6-modules-system/overview/expected.js +++ b/test/fixtures/transformation/es6-modules-system/overview/expected.js @@ -1,7 +1,7 @@ -System.register("actual", ["foo", "foo-bar", "./directory/foo-bar"], function (_export) { +System.register("es6-modules-system/overview/expected", ["foo", "foo-bar", "./directory/foo-bar"], function (_export) { "use strict"; - var __moduleName = "actual"; + var __moduleName = "es6-modules-system/overview/expected"; var foo, bar; var test;