From 5612a59b30cb06d6230d571f4ada741bdec5bc95 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sun, 13 Jun 2010 01:13:52 -0400 Subject: [PATCH] allowing implicit returns to be pushed down into each branch of computation, even when there's an explicit return nested more deeply. Issue #401 --- lib/nodes.js | 23 +++++++++++++---------- src/nodes.coffee | 5 ++++- test/test_returns.coffee | 13 ++++++++++++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index d4b19e91..28111258 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -151,23 +151,24 @@ }).call(this).join(''); }; BaseNode.prototype.eachChild = function(func) { - var _b, _c, _d, _e, _f, _g, attr, child; + var _b, _c, _d, _e, _f, _g, _h, attr, child; if (!(this.children)) { return null; } - _c = this.children; - for (_b = 0, _d = _c.length; _b < _d; _b++) { - attr = _c[_b]; + _b = []; _d = this.children; + for (_c = 0, _e = _d.length; _c < _e; _c++) { + attr = _d[_c]; if (this[attr]) { - _f = flatten([this[attr]]); - for (_e = 0, _g = _f.length; _e < _g; _e++) { - child = _f[_e]; + _g = flatten([this[attr]]); + for (_f = 0, _h = _g.length; _f < _h; _f++) { + child = _g[_f]; if (func(child) === false) { return null; } } } } + return _b; }; BaseNode.prototype.collectChildren = function() { var nodes; @@ -253,9 +254,8 @@ if (!last || last instanceof ReturnNode) { return this; } - if (!(last.containsPureStatement())) { - this.expressions[idx] = last.makeReturn(); - } + this.expressions[idx] = last.makeReturn(); + // unless last.containsPureStatement() return this; }; // An **Expressions** is the only node that can serve as the root. @@ -378,6 +378,9 @@ ReturnNode.prototype.topSensitive = function() { return true; }; + ReturnNode.prototype.makeReturn = function() { + return this; + }; ReturnNode.prototype.compileNode = function(o) { var expr; expr = this.expression.makeReturn(); diff --git a/src/nodes.coffee b/src/nodes.coffee index 08fb8cea..54c632c5 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -179,7 +179,7 @@ exports.Expressions: class Expressions extends BaseNode last: @expressions[idx] last: @expressions[idx: - 1] if last instanceof CommentNode return this if not last or last instanceof ReturnNode - @expressions[idx]: last.makeReturn() unless last.containsPureStatement() + @expressions[idx]: last.makeReturn() this # An **Expressions** is the only node that can serve as the root. @@ -264,6 +264,9 @@ exports.ReturnNode: class ReturnNode extends BaseNode topSensitive: -> true + makeReturn: -> + this + compileNode: (o) -> expr: @expression.makeReturn() return expr.compile(o) unless expr instanceof ReturnNode diff --git a/test/test_returns.coffee b/test/test_returns.coffee index dd3f3a4d..e074f8e9 100644 --- a/test/test_returns.coffee +++ b/test/test_returns.coffee @@ -10,4 +10,15 @@ third: -> ok first().join(' ') is 'do do do' ok second()[0].join(' ') is 're re re' -ok third().join(' ') is 'mi mi mi' \ No newline at end of file +ok third().join(' ') is 'mi mi mi' + + +# Testing returns with multiple branches. +func: -> + if false + for a in b + return c if d + else + "word" + +ok func() is 'word' \ No newline at end of file