diff --git a/src/babel/transformation/modules/_default.js b/src/babel/transformation/modules/_default.js index 3c64c498f2..d77e8d9983 100644 --- a/src/babel/transformation/modules/_default.js +++ b/src/babel/transformation/modules/_default.js @@ -1,81 +1,9 @@ -module.exports = DefaultFormatter; - var messages = require("../../messages"); var extend = require("lodash/object/extend"); var object = require("../../helpers/object"); var util = require("../../util"); var t = require("../../types"); -function DefaultFormatter(file) { - this.scope = file.scope; - this.file = file; - this.ids = object(); - - this.hasNonDefaultExports = false; - - this.hasLocalExports = false; - this.hasLocalImports = false; - - this.localImportOccurences = object(); - this.localExports = object(); - this.localImports = object(); - - this.getLocalExports(); - this.getLocalImports(); - - this.remapAssignments(); -} - -DefaultFormatter.prototype.doDefaultExportInterop = function (node) { - return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports; -}; - -DefaultFormatter.prototype.bumpImportOccurences = function (node) { - var source = node.source.value; - var occurs = this.localImportOccurences; - occurs[source] ||= 0; - occurs[source] += node.specifiers.length; -}; - -var exportsVisitor = { - enter(node, parent, scope, formatter) { - var declar = node && node.declaration; - if (t.isExportDeclaration(node)) { - formatter.hasLocalImports = true; - - if (declar && t.isStatement(declar)) { - extend(formatter.localExports, t.getBindingIdentifiers(declar)); - } - - if (!node.default) { - formatter.hasNonDefaultExports = true; - } - - if (node.source) { - formatter.bumpImportOccurences(node); - } - } - } -}; - -DefaultFormatter.prototype.getLocalExports = function () { - this.file.scope.traverse(this.file.ast, exportsVisitor, this); -}; - -var importsVisitor = { - enter(node, parent, scope, formatter) { - if (t.isImportDeclaration(node)) { - formatter.hasLocalImports = true; - extend(formatter.localImports, t.getBindingIdentifiers(node)); - formatter.bumpImportOccurences(node); - } - } -}; - -DefaultFormatter.prototype.getLocalImports = function () { - this.file.scope.traverse(this.file.ast, importsVisitor, this); -}; - var remapVisitor = { enter(node, parent, scope, formatter) { if (t.isUpdateExpression(node) && formatter.isLocalReference(node.argument, scope)) { @@ -113,181 +41,253 @@ var remapVisitor = { } }; -DefaultFormatter.prototype.remapAssignments = function () { - if (this.hasLocalImports) { - this.file.scope.traverse(this.file.ast, remapVisitor, this); - } -}; - -DefaultFormatter.prototype.isLocalReference = function (node) { - var localImports = this.localImports; - return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node; -}; - -DefaultFormatter.prototype.remapExportAssignment = function (node) { - return t.assignmentExpression( - "=", - node.left, - t.assignmentExpression( - node.operator, - t.memberExpression(t.identifier("exports"), node.left), - node.right - ) - ); -}; - -DefaultFormatter.prototype.isLocalReference = function (node, scope) { - var localExports = this.localExports; - var name = node.name; - return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name); -}; - -DefaultFormatter.prototype.getModuleName = function () { - var opts = this.file.opts; - if (opts.moduleId) return opts.moduleId; - - var filenameRelative = opts.filenameRelative; - var moduleName = ""; - - if (opts.moduleRoot) { - moduleName = opts.moduleRoot + "/"; - } - - if (!opts.filenameRelative) { - return moduleName + opts.filename.replace(/^\//, ""); - } - - if (opts.sourceRoot) { - // remove sourceRoot from filename - var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?"); - filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); - } - - if (!opts.keepModuleIdExtensions) { - // remove extension - filenameRelative = filenameRelative.replace(/\.(\w*?)$/, ""); - } - - moduleName += filenameRelative; - - // normalize path separators - moduleName = moduleName.replace(/\\/g, "/"); - - return moduleName; -}; - -DefaultFormatter.prototype._pushStatement = function (ref, nodes) { - if (t.isClass(ref) || t.isFunction(ref)) { - if (ref.id) { - nodes.push(t.toStatement(ref)); - ref = ref.id; +var importsVisitor = { + enter(node, parent, scope, formatter) { + if (t.isImportDeclaration(node)) { + formatter.hasLocalImports = true; + extend(formatter.localImports, t.getBindingIdentifiers(node)); + formatter.bumpImportOccurences(node); } } - - return ref; }; -DefaultFormatter.prototype._hoistExport = function (declar, assign, priority) { - if (t.isFunctionDeclaration(declar)) { - assign._blockHoist = priority || 2; - } +var exportsVisitor = { + enter(node, parent, scope, formatter) { + var declar = node && node.declaration; + if (t.isExportDeclaration(node)) { + formatter.hasLocalImports = true; - return assign; -}; - -DefaultFormatter.prototype.getExternalReference = function (node, nodes) { - var ids = this.ids; - var id = node.source.value; - - if (ids[id]) { - return ids[id]; - } else { - return this.ids[id] = this._getExternalReference(node, nodes); - } -}; - -DefaultFormatter.prototype.checkExportIdentifier = function (node) { - if (t.isIdentifier(node, { name: "__esModule" })) { - throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name)); - } -}; - -DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { - if (node.source) { - var ref = this.getExternalReference(node, nodes); - - if (t.isExportBatchSpecifier(specifier)) { - // export * from "foo"; - nodes.push(this.buildExportsWildcard(ref, node)); - } else { - if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) { - // importing a default so we need to normalize it - ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); - } else { - ref = t.memberExpression(ref, t.getSpecifierId(specifier)); + if (declar && t.isStatement(declar)) { + extend(formatter.localExports, t.getBindingIdentifiers(declar)); } - // export { foo } from "test"; - nodes.push(this.buildExportsAssignment( - t.getSpecifierName(specifier), - ref, - node - )); + if (!node.default) { + formatter.hasNonDefaultExports = true; + } + + if (node.source) { + formatter.bumpImportOccurences(node); + } } - } else { - // export { foo }; - nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), specifier.id, node)); } }; -DefaultFormatter.prototype.buildExportsWildcard = function (objectIdentifier) { - return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [ - t.identifier("exports"), - t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier]) - ])); -}; +export default class DefaultFormatter { + constructor(file) { + this.scope = file.scope; + this.file = file; + this.ids = object(); -DefaultFormatter.prototype.buildExportsAssignment = function (id, init) { - this.checkExportIdentifier(id); - return util.template("exports-assign", { - VALUE: init, - KEY: id - }, true); -}; + this.hasNonDefaultExports = false; -DefaultFormatter.prototype.exportDeclaration = function (node, nodes) { - var declar = node.declaration; + this.hasLocalExports = false; + this.hasLocalImports = false; - var id = declar.id; + this.localImportOccurences = object(); + this.localExports = object(); + this.localImports = object(); - if (node.default) { - id = t.identifier("default"); + this.getLocalExports(); + this.getLocalImports(); + + this.remapAssignments(); } - var assign; - - if (t.isVariableDeclaration(declar)) { - for (var i = 0; i < declar.declarations.length; i++) { - var decl = declar.declarations[i]; - - decl.init = this.buildExportsAssignment(decl.id, decl.init, node).expression; - - var newDeclar = t.variableDeclaration(declar.kind, [decl]); - if (i === 0) t.inherits(newDeclar, declar); - nodes.push(newDeclar); - } - } else { - var ref = declar; - - if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) { - ref = declar.id; - nodes.push(declar); - } - - assign = this.buildExportsAssignment(id, ref, node); - - nodes.push(assign); - - this._hoistExport(declar, assign); + doDefaultExportInterop(node) { + return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports; } -}; + + bumpImportOccurences(node) { + var source = node.source.value; + var occurs = this.localImportOccurences; + occurs[source] ||= 0; + occurs[source] += node.specifiers.length; + } + + getLocalExports() { + this.file.scope.traverse(this.file.ast, exportsVisitor, this); + } + + getLocalImports() { + this.file.scope.traverse(this.file.ast, importsVisitor, this); + } + + remapAssignments() { + if (this.hasLocalImports) { + this.file.scope.traverse(this.file.ast, remapVisitor, this); + } + } + + isLocalReference(node) { + var localImports = this.localImports; + return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node; + } + + remapExportAssignment(node) { + return t.assignmentExpression( + "=", + node.left, + t.assignmentExpression( + node.operator, + t.memberExpression(t.identifier("exports"), node.left), + node.right + ) + ); + } + + isLocalReference(node, scope) { + var localExports = this.localExports; + var name = node.name; + return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name); + } + + getModuleName() { + var opts = this.file.opts; + if (opts.moduleId) return opts.moduleId; + + var filenameRelative = opts.filenameRelative; + var moduleName = ""; + + if (opts.moduleRoot) { + moduleName = opts.moduleRoot + "/"; + } + + if (!opts.filenameRelative) { + return moduleName + opts.filename.replace(/^\//, ""); + } + + if (opts.sourceRoot) { + // remove sourceRoot from filename + var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?"); + filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); + } + + if (!opts.keepModuleIdExtensions) { + // remove extension + filenameRelative = filenameRelative.replace(/\.(\w*?)$/, ""); + } + + moduleName += filenameRelative; + + // normalize path separators + moduleName = moduleName.replace(/\\/g, "/"); + + return moduleName; + } + + _pushStatement(ref, nodes) { + if (t.isClass(ref) || t.isFunction(ref)) { + if (ref.id) { + nodes.push(t.toStatement(ref)); + ref = ref.id; + } + } + + return ref; + } + + _hoistExport(declar, assign, priority) { + if (t.isFunctionDeclaration(declar)) { + assign._blockHoist = priority || 2; + } + + return assign; + } + + getExternalReference(node, nodes) { + var ids = this.ids; + var id = node.source.value; + + if (ids[id]) { + return ids[id]; + } else { + return this.ids[id] = this._getExternalReference(node, nodes); + } + } + + checkExportIdentifier(node) { + if (t.isIdentifier(node, { name: "__esModule" })) { + throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name)); + } + } + + exportSpecifier(specifier, node, nodes) { + if (node.source) { + var ref = this.getExternalReference(node, nodes); + + if (t.isExportBatchSpecifier(specifier)) { + // export * from "foo"; + nodes.push(this.buildExportsWildcard(ref, node)); + } else { + if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) { + // importing a default so we need to normalize it + ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); + } else { + ref = t.memberExpression(ref, t.getSpecifierId(specifier)); + } + + // export { foo } from "test"; + nodes.push(this.buildExportsAssignment( + t.getSpecifierName(specifier), + ref, + node + )); + } + } else { + // export { foo }; + nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), specifier.id, node)); + } + } + + buildExportsWildcard(objectIdentifier) { + return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [ + t.identifier("exports"), + t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier]) + ])); + } + + buildExportsAssignment(id, init) { + this.checkExportIdentifier(id); + return util.template("exports-assign", { + VALUE: init, + KEY: id + }, true); + } + + exportDeclaration(node, nodes) { + var declar = node.declaration; + + var id = declar.id; + + if (node.default) { + id = t.identifier("default"); + } + + var assign; + + if (t.isVariableDeclaration(declar)) { + for (var i = 0; i < declar.declarations.length; i++) { + var decl = declar.declarations[i]; + + decl.init = this.buildExportsAssignment(decl.id, decl.init, node).expression; + + var newDeclar = t.variableDeclaration(declar.kind, [decl]); + if (i === 0) t.inherits(newDeclar, declar); + nodes.push(newDeclar); + } + } else { + var ref = declar; + + if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) { + ref = declar.id; + nodes.push(declar); + } + + assign = this.buildExportsAssignment(id, ref, node); + + nodes.push(assign); + + this._hoistExport(declar, assign); + } + } +} diff --git a/src/babel/transformation/modules/amd.js b/src/babel/transformation/modules/amd.js index dea023dedf..a0bc14092e 100644 --- a/src/babel/transformation/modules/amd.js +++ b/src/babel/transformation/modules/amd.js @@ -1,5 +1,3 @@ -module.exports = AMDFormatter; - var DefaultFormatter = require("./_default"); var CommonFormatter = require("./common"); var includes = require("lodash/collection/includes"); @@ -7,100 +5,96 @@ var values = require("lodash/object/values"); var util = require("../../util"); var t = require("../../types"); -function AMDFormatter() { - CommonFormatter.apply(this, arguments); +export default class AMDFormatter extends DefaultFormatter { + init = CommonFormatter.prototype.init; + + buildDependencyLiterals() { + var names = []; + for (var name in this.ids) { + names.push(t.literal(name)); + } + return names; + } + + /** + * Wrap the entire body in a `define` wrapper. + */ + + transform(program) { + var body = program.body; + + // build an array of module names + + var names = [t.literal("exports")]; + if (this.passModuleArg) names.push(t.literal("module")); + names = names.concat(this.buildDependencyLiterals()); + names = t.arrayExpression(names); + + // build up define container + + var params = values(this.ids); + if (this.passModuleArg) params.unshift(t.identifier("module")); + params.unshift(t.identifier("exports")); + + var container = t.functionExpression(null, params, t.blockStatement(body)); + + var defineArgs = [names, container]; + var moduleName = this.getModuleName(); + if (moduleName) defineArgs.unshift(t.literal(moduleName)); + + var call = t.callExpression(t.identifier("define"), defineArgs); + + program.body = [t.expressionStatement(call)]; + } + + /** + * Get the AMD module name that we'll prepend to the wrapper + * to define this module + */ + + getModuleName() { + if (this.file.opts.moduleIds) { + return DefaultFormatter.prototype.getModuleName.apply(this, arguments); + } else { + return null; + } + } + + _getExternalReference(node) { + return this.scope.generateUidIdentifier(node.source.value); + } + + importDeclaration(node) { + this.getExternalReference(node); + } + + importSpecifier(specifier, node, nodes) { + var key = t.getSpecifierName(specifier); + var ref = this.getExternalReference(node); + + if (includes(this.file.dynamicImportedNoDefault, node)) { + // Prevent unnecessary renaming of dynamic imports. + this.ids[node.source.value] = ref; + } else if (t.isImportBatchSpecifier(specifier)) { + // import * as bar from "foo"; + } else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) { + // import foo from "foo"; + ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); + } else { + // import {foo} from "foo"; + ref = t.memberExpression(ref, t.getSpecifierId(specifier), false); + } + + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(key, ref) + ])); + } + + exportDeclaration(node) { + if (this.doDefaultExportInterop(node)) { + this.passModuleArg = true; + } + + CommonFormatter.prototype.exportDeclaration.apply(this, arguments); + } } - -util.inherits(AMDFormatter, DefaultFormatter); - -AMDFormatter.prototype.init = CommonFormatter.prototype.init; - -AMDFormatter.prototype.buildDependencyLiterals = function () { - var names = []; - for (var name in this.ids) { - names.push(t.literal(name)); - } - return names; -}; - -/** - * Wrap the entire body in a `define` wrapper. - */ - -AMDFormatter.prototype.transform = function (program) { - var body = program.body; - - // build an array of module names - - var names = [t.literal("exports")]; - if (this.passModuleArg) names.push(t.literal("module")); - names = names.concat(this.buildDependencyLiterals()); - names = t.arrayExpression(names); - - // build up define container - - var params = values(this.ids); - if (this.passModuleArg) params.unshift(t.identifier("module")); - params.unshift(t.identifier("exports")); - - var container = t.functionExpression(null, params, t.blockStatement(body)); - - var defineArgs = [names, container]; - var moduleName = this.getModuleName(); - if (moduleName) defineArgs.unshift(t.literal(moduleName)); - - var call = t.callExpression(t.identifier("define"), defineArgs); - - program.body = [t.expressionStatement(call)]; -}; - -/** - * Get the AMD module name that we'll prepend to the wrapper - * to define this module - */ - -AMDFormatter.prototype.getModuleName = function () { - if (this.file.opts.moduleIds) { - return DefaultFormatter.prototype.getModuleName.apply(this, arguments); - } else { - return null; - } -}; - -AMDFormatter.prototype._getExternalReference = function (node) { - return this.scope.generateUidIdentifier(node.source.value); -}; - -AMDFormatter.prototype.importDeclaration = function (node) { - this.getExternalReference(node); -}; - -AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) { - var key = t.getSpecifierName(specifier); - var ref = this.getExternalReference(node); - - if (includes(this.file.dynamicImportedNoDefault, node)) { - // Prevent unnecessary renaming of dynamic imports. - this.ids[node.source.value] = ref; - } else if (t.isImportBatchSpecifier(specifier)) { - // import * as bar from "foo"; - } else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) { - // import foo from "foo"; - ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); - } else { - // import {foo} from "foo"; - ref = t.memberExpression(ref, t.getSpecifierId(specifier), false); - } - - nodes.push(t.variableDeclaration("var", [ - t.variableDeclarator(key, ref) - ])); -}; - -AMDFormatter.prototype.exportDeclaration = function (node) { - if (this.doDefaultExportInterop(node)) { - this.passModuleArg = true; - } - - CommonFormatter.prototype.exportDeclaration.apply(this, arguments); -}; diff --git a/src/babel/transformation/modules/common.js b/src/babel/transformation/modules/common.js index 4f28454084..a5b2f8b8ee 100644 --- a/src/babel/transformation/modules/common.js +++ b/src/babel/transformation/modules/common.js @@ -1,104 +1,98 @@ -module.exports = CommonJSFormatter; - var DefaultFormatter = require("./_default"); var includes = require("lodash/collection/includes"); var util = require("../../util"); var t = require("../../types"); -function CommonJSFormatter() { - DefaultFormatter.apply(this, arguments); -} +export default class CommonJSFormatter extends DefaultFormatter { + init() { + var file = this.file; + var scope = file.scope; -util.inherits(CommonJSFormatter, DefaultFormatter); + scope.rename("module"); -CommonJSFormatter.prototype.init = function () { - var file = this.file; - var scope = file.scope; - - scope.rename("module"); - - if (!this.noInteropRequireImport && this.hasNonDefaultExports) { - var templateName = "exports-module-declaration"; - if (this.file.isLoose("es6.modules")) templateName += "-loose"; - file.ast.program.body.push(util.template(templateName, true)); - } -}; - -CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) { - var variableName = t.getSpecifierName(specifier); - - var ref = this.getExternalReference(node, nodes); - - // import foo from "foo"; - if (t.isSpecifierDefault(specifier)) { - if (!includes(this.file.dynamicImportedNoDefault, node)) { - if (this.noInteropRequireImport || includes(this.file.dynamicImported, node)) { - ref = t.memberExpression(ref, t.identifier("default")); - } else { - ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); - } + if (!this.noInteropRequireImport && this.hasNonDefaultExports) { + var templateName = "exports-module-declaration"; + if (this.file.isLoose("es6.modules")) templateName += "-loose"; + file.ast.program.body.push(util.template(templateName, true)); } - nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)])); - } else { - if (specifier.type === "ImportBatchSpecifier") { + }; - if (!this.noInteropRequireImport) { - ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]); + importSpecifier(specifier, node, nodes) { + var variableName = t.getSpecifierName(specifier); + + var ref = this.getExternalReference(node, nodes); + + // import foo from "foo"; + if (t.isSpecifierDefault(specifier)) { + if (!includes(this.file.dynamicImportedNoDefault, node)) { + if (this.noInteropRequireImport || includes(this.file.dynamicImported, node)) { + ref = t.memberExpression(ref, t.identifier("default")); + } else { + ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); + } } - - // import * as bar from "foo"; - nodes.push(t.variableDeclaration("var", [ - t.variableDeclarator(variableName, ref) - ])); + nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)])); } else { - // import { foo } from "foo"; + if (specifier.type === "ImportBatchSpecifier") { + + if (!this.noInteropRequireImport) { + ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]); + } + + // import * as bar from "foo"; + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(variableName, ref) + ])); + } else { + // import { foo } from "foo"; + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator( + variableName, + t.memberExpression(ref, t.getSpecifierId(specifier)) + ) + ])); + } + } + } + + importDeclaration(node, nodes) { + // import "foo"; + nodes.push(util.template("require", { + MODULE_NAME: node.source + }, true)); + } + + exportDeclaration(node, nodes) { + if (this.doDefaultExportInterop(node)) { + var declar = node.declaration; + var assign = util.template("exports-default-assign", { + VALUE: this._pushStatement(declar, nodes) + }, true); + + if (t.isFunctionDeclaration(declar)) { + // we can hoist this assignment to the top of the file + assign._blockHoist = 3; + } + + nodes.push(assign); + return; + } + + DefaultFormatter.prototype.exportDeclaration.apply(this, arguments); + } + + _getExternalReference(node, nodes) { + var source = node.source.value; + var call = t.callExpression(t.identifier("require"), [node.source]); + + if (this.localImportOccurences[source] > 1) { + var uid = this.scope.generateUidIdentifier(source); nodes.push(t.variableDeclaration("var", [ - t.variableDeclarator( - variableName, - t.memberExpression(ref, t.getSpecifierId(specifier)) - ) + t.variableDeclarator(uid, call) ])); + return uid; + } else { + return call; } } -}; - -CommonJSFormatter.prototype.importDeclaration = function (node, nodes) { - // import "foo"; - nodes.push(util.template("require", { - MODULE_NAME: node.source - }, true)); -}; - -CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) { - if (this.doDefaultExportInterop(node)) { - var declar = node.declaration; - var assign = util.template("exports-default-assign", { - VALUE: this._pushStatement(declar, nodes) - }, true); - - if (t.isFunctionDeclaration(declar)) { - // we can hoist this assignment to the top of the file - assign._blockHoist = 3; - } - - nodes.push(assign); - return; - } - - DefaultFormatter.prototype.exportDeclaration.apply(this, arguments); -}; - -CommonJSFormatter.prototype._getExternalReference = function (node, nodes) { - var source = node.source.value; - var call = t.callExpression(t.identifier("require"), [node.source]); - - if (this.localImportOccurences[source] > 1) { - var uid = this.scope.generateUidIdentifier(source); - nodes.push(t.variableDeclaration("var", [ - t.variableDeclarator(uid, call) - ])); - return uid; - } else { - return call; - } -}; +} diff --git a/src/babel/transformation/modules/ignore.js b/src/babel/transformation/modules/ignore.js index 3753440eed..6c50fce28f 100644 --- a/src/babel/transformation/modules/ignore.js +++ b/src/babel/transformation/modules/ignore.js @@ -1,18 +1,12 @@ -module.exports = IgnoreFormatter; - var t = require("../../types"); -function IgnoreFormatter() { +export default class IgnoreFormatter { + exportDeclaration(node, nodes) { + var declar = t.toStatement(node.declaration, true); + if (declar) nodes.push(t.inherits(declar, node)); + } + importDeclaration() {} + importSpecifier() {} + exportSpecifier() {} } - -IgnoreFormatter.prototype.exportDeclaration = function (node, nodes) { - var declar = t.toStatement(node.declaration, true); - if (declar) nodes.push(t.inherits(declar, node)); -}; - -IgnoreFormatter.prototype.importDeclaration = -IgnoreFormatter.prototype.importSpecifier = -IgnoreFormatter.prototype.exportSpecifier = function () { - -}; diff --git a/src/babel/transformation/modules/system.js b/src/babel/transformation/modules/system.js index fc468cfbc1..65dd0dd333 100644 --- a/src/babel/transformation/modules/system.js +++ b/src/babel/transformation/modules/system.js @@ -1,5 +1,3 @@ -module.exports = SystemFormatter; - var DefaultFormatter = require("./_default"); var AMDFormatter = require("./amd"); var util = require("../../util"); @@ -8,98 +6,6 @@ var each = require("lodash/collection/each"); var map = require("lodash/collection/map"); var t = require("../../types"); -function SystemFormatter(file) { - this.exportIdentifier = file.scope.generateUidIdentifier("export"); - this.noInteropRequireExport = true; - this.noInteropRequireImport = true; - - DefaultFormatter.apply(this, arguments); -} - -util.inherits(SystemFormatter, AMDFormatter); - -SystemFormatter.prototype.init = function () {}; - -SystemFormatter.prototype._addImportSource = function (node, exportNode) { - node._importSource = exportNode.source && exportNode.source.value; - return node; -}; - -SystemFormatter.prototype.buildExportsWildcard = function (objectIdentifier, node) { - var leftIdentifier = this.scope.generateUidIdentifier("key"); - var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true); - - var left = t.variableDeclaration("var", [ - t.variableDeclarator(leftIdentifier) - ]); - - var right = objectIdentifier; - - var block = t.blockStatement([ - t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier)) - ]); - - return this._addImportSource(t.forInStatement(left, right, block), node); -}; - -SystemFormatter.prototype.buildExportsAssignment = function (id, init, node) { - var call = this.buildExportCall(t.literal(id.name), init, true); - return this._addImportSource(call, node); -}; - -SystemFormatter.prototype.remapExportAssignment = function (node) { - return this.buildExportCall(t.literal(node.left.name), node); -}; - -SystemFormatter.prototype.buildExportCall = function (id, init, isStatement) { - var call = t.callExpression(this.exportIdentifier, [id, init]); - if (isStatement) { - return t.expressionStatement(call); - } else { - return call; - } -}; - -SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) { - AMDFormatter.prototype.importSpecifier.apply(this, arguments); - this._addImportSource(last(nodes), node); -}; - -var runnerSettersVisitor = { - enter(node, parent, scope, state) { - if (node._importSource === state.source) { - if (t.isVariableDeclaration(node)) { - each(node.declarations, function (declar) { - state.hoistDeclarators.push(t.variableDeclarator(declar.id)); - state.nodes.push(t.expressionStatement( - t.assignmentExpression("=", declar.id, declar.init) - )); - }); - } else { - state.nodes.push(node); - } - - this.remove(); - } - } -}; - -SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators) { - var scope = this.file.scope; - - return t.arrayExpression(map(this.ids, function (uid, source) { - var state = { - source: source, - nodes: [], - hoistDeclarators: hoistDeclarators - }; - - scope.traverse(block, runnerSettersVisitor, state); - - return t.functionExpression(null, [uid], t.blockStatement(state.nodes)); - })); -}; - var hoistVariablesVisitor = { enter(node, parent, scope, hoistDeclarators) { if (t.isFunction(node)) { @@ -156,39 +62,131 @@ var hoistFunctionsVisitor = { } }; -SystemFormatter.prototype.transform = function (program) { - var hoistDeclarators = []; - var moduleName = this.getModuleName(); - var moduleNameLiteral = t.literal(moduleName); +var runnerSettersVisitor = { + enter(node, parent, scope, state) { + if (node._importSource === state.source) { + if (t.isVariableDeclaration(node)) { + each(node.declarations, function (declar) { + state.hoistDeclarators.push(t.variableDeclarator(declar.id)); + state.nodes.push(t.expressionStatement( + t.assignmentExpression("=", declar.id, declar.init) + )); + }); + } else { + state.nodes.push(node); + } - var block = t.blockStatement(program.body); + this.remove(); + } + } +}; - var runner = util.template("system", { - MODULE_NAME: moduleNameLiteral, - MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()), - EXPORT_IDENTIFIER: this.exportIdentifier, - SETTERS: this.buildRunnerSetters(block, hoistDeclarators), - EXECUTE: t.functionExpression(null, [], block) - }, true); +export default class SystemFormatter extends AMDFormatter { + constructor(file) { + this.exportIdentifier = file.scope.generateUidIdentifier("export"); + this.noInteropRequireExport = true; + this.noInteropRequireImport = true; - var handlerBody = runner.expression.arguments[2].body.body; - if (!moduleName) runner.expression.arguments.shift(); - - var returnStatement = handlerBody.pop(); - - // hoist up all variable declarations - this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators); - - if (hoistDeclarators.length) { - var hoistDeclar = t.variableDeclaration("var", hoistDeclarators); - hoistDeclar._blockHoist = true; - handlerBody.unshift(hoistDeclar); + DefaultFormatter.apply(this, arguments); } - // hoist up function declarations for circular references - this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody); + init() {} - handlerBody.push(returnStatement); + _addImportSource(node, exportNode) { + node._importSource = exportNode.source && exportNode.source.value; + return node; + } - program.body = [runner]; -}; + buildExportsWildcard(objectIdentifier, node) { + var leftIdentifier = this.scope.generateUidIdentifier("key"); + var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true); + + var left = t.variableDeclaration("var", [ + t.variableDeclarator(leftIdentifier) + ]); + + var right = objectIdentifier; + + var block = t.blockStatement([ + t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier)) + ]); + + return this._addImportSource(t.forInStatement(left, right, block), node); + } + + buildExportsAssignment(id, init, node) { + var call = this.buildExportCall(t.literal(id.name), init, true); + return this._addImportSource(call, node); + } + + remapExportAssignment(node) { + return this.buildExportCall(t.literal(node.left.name), node); + } + + buildExportCall(id, init, isStatement) { + var call = t.callExpression(this.exportIdentifier, [id, init]); + if (isStatement) { + return t.expressionStatement(call); + } else { + return call; + } + } + + importSpecifier(specifier, node, nodes) { + AMDFormatter.prototype.importSpecifier.apply(this, arguments); + this._addImportSource(last(nodes), node); + } + + buildRunnerSetters(block, hoistDeclarators) { + var scope = this.file.scope; + + return t.arrayExpression(map(this.ids, function (uid, source) { + var state = { + source: source, + nodes: [], + hoistDeclarators: hoistDeclarators + }; + + scope.traverse(block, runnerSettersVisitor, state); + + return t.functionExpression(null, [uid], t.blockStatement(state.nodes)); + })); + } + + transform(program) { + var hoistDeclarators = []; + var moduleName = this.getModuleName(); + var moduleNameLiteral = t.literal(moduleName); + + var block = t.blockStatement(program.body); + + var runner = util.template("system", { + MODULE_NAME: moduleNameLiteral, + MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()), + EXPORT_IDENTIFIER: this.exportIdentifier, + SETTERS: this.buildRunnerSetters(block, hoistDeclarators), + EXECUTE: t.functionExpression(null, [], block) + }, true); + + var handlerBody = runner.expression.arguments[2].body.body; + if (!moduleName) runner.expression.arguments.shift(); + + var returnStatement = handlerBody.pop(); + + // hoist up all variable declarations + this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators); + + if (hoistDeclarators.length) { + var hoistDeclar = t.variableDeclaration("var", hoistDeclarators); + hoistDeclar._blockHoist = true; + handlerBody.unshift(hoistDeclar); + } + + // hoist up function declarations for circular references + this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody); + + handlerBody.push(returnStatement); + + program.body = [runner]; + } +} diff --git a/src/babel/transformation/modules/umd.js b/src/babel/transformation/modules/umd.js index 1f91714a19..81378512d5 100644 --- a/src/babel/transformation/modules/umd.js +++ b/src/babel/transformation/modules/umd.js @@ -1,71 +1,65 @@ -module.exports = UMDFormatter; - var AMDFormatter = require("./amd"); +var values = require("lodash/object/values"); var util = require("../../util"); var t = require("../../types"); -var values = require("lodash/object/values"); -function UMDFormatter() { - AMDFormatter.apply(this, arguments); -} +export default class UMDFormatter extends AMDFormatter { + transform(program) { + var body = program.body; -util.inherits(UMDFormatter, AMDFormatter); + // build an array of module names -UMDFormatter.prototype.transform = function (program) { - var body = program.body; + var names = []; + for (var name in this.ids) { + names.push(t.literal(name)); + } - // build an array of module names + // factory - var names = []; - for (var name in this.ids) { - names.push(t.literal(name)); + var ids = values(this.ids); + var args = [t.identifier("exports")]; + if (this.passModuleArg) args.push(t.identifier("module")); + args = args.concat(ids); + + var factory = t.functionExpression(null, args, t.blockStatement(body)); + + // amd + + var defineArgs = [t.literal("exports")]; + if (this.passModuleArg) defineArgs.push(t.literal("module")); + defineArgs = defineArgs.concat(names); + defineArgs = [t.arrayExpression(defineArgs)]; + + // common + + var testExports = util.template("test-exports"); + var testModule = util.template("test-module"); + var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports; + + var commonArgs = [t.identifier("exports")]; + if (this.passModuleArg) commonArgs.push(t.identifier("module")); + commonArgs = commonArgs.concat(names.map(function (name) { + return t.callExpression(t.identifier("require"), [name]); + })); + + // globals + + //var umdArgs = []; + + // + + var moduleName = this.getModuleName(); + if (moduleName) defineArgs.unshift(t.literal(moduleName)); + + var runner = util.template("umd-runner-body", { + AMD_ARGUMENTS: defineArgs, + COMMON_TEST: commonTests, + COMMON_ARGUMENTS: commonArgs + }); + + // + + var call = t.callExpression(runner, [factory]); + program.body = [t.expressionStatement(call)]; } - - // factory - - var ids = values(this.ids); - var args = [t.identifier("exports")]; - if (this.passModuleArg) args.push(t.identifier("module")); - args = args.concat(ids); - - var factory = t.functionExpression(null, args, t.blockStatement(body)); - - // amd - - var defineArgs = [t.literal("exports")]; - if (this.passModuleArg) defineArgs.push(t.literal("module")); - defineArgs = defineArgs.concat(names); - defineArgs = [t.arrayExpression(defineArgs)]; - - // common - - var testExports = util.template("test-exports"); - var testModule = util.template("test-module"); - var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports; - - var commonArgs = [t.identifier("exports")]; - if (this.passModuleArg) commonArgs.push(t.identifier("module")); - commonArgs = commonArgs.concat(names.map(function (name) { - return t.callExpression(t.identifier("require"), [name]); - })); - - // globals - - //var umdArgs = []; - - // - - var moduleName = this.getModuleName(); - if (moduleName) defineArgs.unshift(t.literal(moduleName)); - - var runner = util.template("umd-runner-body", { - AMD_ARGUMENTS: defineArgs, - COMMON_TEST: commonTests, - COMMON_ARGUMENTS: commonArgs - }); - - // - - var call = t.callExpression(runner, [factory]); - program.body = [t.expressionStatement(call)]; -}; +}