clean up system module formatter

This commit is contained in:
Sebastian McKenzie
2014-12-27 19:12:31 +11:00
parent 987dc0692f
commit 22851cd1ac
14 changed files with 137 additions and 169 deletions

View File

@@ -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);
}
}
}
}

View File

@@ -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];
};

View File

@@ -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);
}
};
});

View File

@@ -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);

View File

@@ -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: [],

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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],

View File

@@ -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;