better circular references in amd/umd/system module formatter

This commit is contained in:
Sebastian McKenzie 2014-12-28 09:35:47 +11:00
parent 4942ba6dd7
commit 6df6652629
9 changed files with 79 additions and 41 deletions

View File

@ -2,6 +2,11 @@
Gaps between patch versions are faulty/broken releases. Gaps between patch versions are faulty/broken releases.
## 2.0.3
* Hoist function declarations in system module formatter for circular references.
* Hoist default function declarations in umd and amd module formatters for circular references.
## 2.0.2 ## 2.0.2
* Inherit comments in `for-of` transformer. * Inherit comments in `for-of` transformer.

View File

@ -169,30 +169,36 @@ DefaultFormatter.prototype._exportsAssign = function (id, init) {
DefaultFormatter.prototype.exportDeclaration = function (node, nodes) { DefaultFormatter.prototype.exportDeclaration = function (node, nodes) {
var declar = node.declaration; var declar = node.declaration;
var id = declar.id;
if (node.default) { if (node.default) {
nodes.push( id = t.identifier("default");
this._exportsAssign(t.identifier("default"), this._pushStatement(declar, nodes)) }
);
} else {
var assign;
if (t.isVariableDeclaration(declar)) { var assign;
for (var i in declar.declarations) {
var decl = declar.declarations[i];
decl.init = this._exportsAssign(decl.id, decl.init).expression; if (t.isVariableDeclaration(declar)) {
for (var i in declar.declarations) {
var decl = declar.declarations[i];
var newDeclar = t.variableDeclaration(declar.kind, [decl]); decl.init = this._exportsAssign(decl.id, decl.init).expression;
if (i === "0") t.inherits(newDeclar, declar);
nodes.push(newDeclar);
}
} else {
assign = this._exportsAssign(declar.id, declar.id);
nodes.push(t.toStatement(declar)); var newDeclar = t.variableDeclaration(declar.kind, [decl]);
nodes.push(assign); if (i === "0") t.inherits(newDeclar, declar);
nodes.push(newDeclar);
this._hoistExport(declar, assign);
} }
} else {
var ref = declar;
if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) {
ref = declar.id;
nodes.push(declar);
}
assign = this._exportsAssign(id, ref);
nodes.push(assign);
this._hoistExport(declar, assign);
} }
}; };

View File

@ -2,6 +2,7 @@ module.exports = SystemFormatter;
var DefaultFormatter = require("./_default"); var DefaultFormatter = require("./_default");
var AMDFormatter = require("./amd"); var AMDFormatter = require("./amd");
var traverse = require("../../traverse");
var util = require("../../util"); var util = require("../../util");
var t = require("../../types"); var t = require("../../types");
var _ = require("lodash"); var _ = require("lodash");
@ -74,12 +75,28 @@ SystemFormatter.prototype.transform = function (ast) {
EXECUTE: t.functionExpression(null, [], t.blockStatement(program.body)) EXECUTE: t.functionExpression(null, [], t.blockStatement(program.body))
}, true); }, true);
var handlerBody = runner.expression.arguments[2].body.body;
var returnStatement = handlerBody.pop();
// hoist up function declarations for circular references
traverse(program, {
enter: function (node, parent) {
if (t.isFunction(node)) this.stop();
if (t.isFunctionDeclaration(node) || node._blockHoist) {
handlerBody.push(node);
this.remove();
}
}
});
if (!_.isEmpty(this.ids)) { if (!_.isEmpty(this.ids)) {
var handlerBody = runner.expression.arguments[2].body.body; handlerBody.push(t.variableDeclaration("var", _.map(this.ids, function (uid) {
handlerBody.unshift(t.variableDeclaration("var", _.map(this.ids, function (uid) {
return t.variableDeclarator(uid); return t.variableDeclarator(uid);
}))); })));
} }
handlerBody.push(returnStatement);
program.body = [runner]; program.body = [runner];
}; };

View File

@ -50,11 +50,16 @@ function traverse(parent, opts, scope) {
} }
}; };
var stop = false; var stopped = false;
var removed = false;
var context = { var context = {
stop: function () { stop: function () {
stop = true; stopped = true;
},
remove: function () {
stopped = removed = true;
} }
}; };
@ -67,8 +72,13 @@ function traverse(parent, opts, scope) {
var result = opts.enter.call(context, node, parent, ourScope); var result = opts.enter.call(context, node, parent, ourScope);
maybeReplace(result); maybeReplace(result);
if (removed) {
delete obj[key];
updated = true;
}
// stop iteration // stop iteration
if (stop || result === false) return; if (stopped || result === false) return;
} }
// traverse node // traverse node

View File

@ -1,6 +1,7 @@
define(["exports"], function (exports) { define(["exports"], function (exports) {
"use strict"; "use strict";
exports["default"] = foo;
exports["default"] = 42; exports["default"] = 42;
exports["default"] = {}; exports["default"] = {};
exports["default"] = []; exports["default"] = [];
@ -10,7 +11,6 @@ define(["exports"], function (exports) {
exports["default"] = function () {}; exports["default"] = function () {};
function foo() {} function foo() {}
exports["default"] = foo;
var Foo = function Foo() {}; var Foo = function Foo() {};
exports["default"] = Foo; exports["default"] = Foo;

View File

@ -1,4 +1,7 @@
System.register("es6-modules-system/exports-default/expected", [], function (_export) { System.register("es6-modules-system/exports-default/expected", [], function (_export) {
_export("default", foo);
function foo() {}
return { return {
setters: [], setters: [],
execute: function () { execute: function () {
@ -16,12 +19,9 @@ System.register("es6-modules-system/exports-default/expected", [], function (_ex
_export("default", function () {}); _export("default", function () {});
function foo() {}
_export("default", foo);
var Foo = function Foo() {}; var Foo = function Foo() {};
_export("default", Foo); _export("default", Foo);
} }
}; };
}); });

View File

@ -1,21 +1,21 @@
System.register("es6-modules-system/exports-variable/expected", [], function (_export) { System.register("es6-modules-system/exports-variable/expected", [], function (_export) {
_export("foo7", foo7);
function foo7() {}
return { return {
setters: [], setters: [],
execute: function () { execute: function () {
"use strict"; "use strict";
_export("foo7", foo7);
var foo = _export("foo", 1); var foo = _export("foo", 1);
var foo2 = _export("foo2", function () {}); var foo2 = _export("foo2", function () {});
var foo3 = _export("foo3", undefined); var foo3 = _export("foo3", undefined);
var foo4 = _export("foo4", 2); var foo4 = _export("foo4", 2);
var foo5 = _export("foo5", undefined); var foo5 = _export("foo5", undefined);
var foo6 = _export("foo6", 3); var foo6 = _export("foo6", 3);
function foo7() {}
var foo8 = function foo8() {}; var foo8 = function foo8() {};
_export("foo8", foo8); _export("foo8", foo8);
} }
}; };
}); });

View File

@ -1,4 +1,10 @@
System.register("es6-modules-system/hoist-function-exports/expected", ["./evens"], function (_export) { System.register("es6-modules-system/hoist-function-exports/expected", ["./evens"], function (_export) {
_export("nextOdd", nextOdd);
function nextOdd(n) {
return isEven(n) ? n + 1 : n + 2;
}
var _evens; var _evens;
return { return {
setters: [function (m) { setters: [function (m) {
@ -7,13 +13,7 @@ System.register("es6-modules-system/hoist-function-exports/expected", ["./evens"
execute: function () { execute: function () {
"use strict"; "use strict";
_export("nextOdd", nextOdd);
var isEven = _evens.isEven; var isEven = _evens.isEven;
function nextOdd(n) {
return isEven(n) ? n + 1 : n + 2;
}
var isOdd = _export("isOdd", (function (isEven) { var isOdd = _export("isOdd", (function (isEven) {
return function (n) { return function (n) {
return !isEven(n); return !isEven(n);
@ -21,4 +21,4 @@ System.register("es6-modules-system/hoist-function-exports/expected", ["./evens"
})(isEven)); })(isEven));
} }
}; };
}); });

View File

@ -7,6 +7,7 @@
})(function (exports) { })(function (exports) {
"use strict"; "use strict";
exports["default"] = foo;
exports["default"] = 42; exports["default"] = 42;
exports["default"] = {}; exports["default"] = {};
exports["default"] = []; exports["default"] = [];
@ -16,7 +17,6 @@
exports["default"] = function () {}; exports["default"] = function () {};
function foo() {} function foo() {}
exports["default"] = foo;
var Foo = function Foo() {}; var Foo = function Foo() {};
exports["default"] = Foo; exports["default"] = Foo;