mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-04-11 03:00:13 -04:00
moving the contains-a-pure-statement-means-no-closure logic into ClosureNode.wrap itself.
This commit is contained in:
19
lib/nodes.js
19
lib/nodes.js
@@ -67,9 +67,7 @@
|
|||||||
del(this.options, 'operation');
|
del(this.options, 'operation');
|
||||||
}
|
}
|
||||||
top = this.top_sensitive() ? this.options.top : del(this.options, 'top');
|
top = this.top_sensitive() ? this.options.top : del(this.options, 'top');
|
||||||
closure = this.is_statement() && !this.is_pure_statement() && !top && !this.options.returns && !(this instanceof CommentNode) && !this.contains(function(node) {
|
closure = this.is_statement() && !this.is_pure_statement() && !top && !this.options.returns && !(this instanceof CommentNode);
|
||||||
return node.is_pure_statement();
|
|
||||||
});
|
|
||||||
return closure ? this.compile_closure(this.options) : this.compile_node(this.options);
|
return closure ? this.compile_closure(this.options) : this.compile_node(this.options);
|
||||||
};
|
};
|
||||||
// Statements converted into expressions via closure-wrapping share a scope
|
// Statements converted into expressions via closure-wrapping share a scope
|
||||||
@@ -1346,11 +1344,11 @@
|
|||||||
}
|
}
|
||||||
set_result = rvar ? this.idt() + rvar + ' = []; ' : this.idt();
|
set_result = rvar ? this.idt() + rvar + ' = []; ' : this.idt();
|
||||||
return_result = rvar || '';
|
return_result = rvar || '';
|
||||||
top_level && !this.contains(function(n) {
|
if (top_level && body.contains(function(n) {
|
||||||
return n.is_pure_statement();
|
|
||||||
}) && this.contains(function(n) {
|
|
||||||
return n instanceof CodeNode;
|
return n instanceof CodeNode;
|
||||||
}) ? (body = ClosureNode.wrap(body, true)) : null;
|
})) {
|
||||||
|
body = ClosureNode.wrap(body, true);
|
||||||
|
}
|
||||||
if (!(top_level)) {
|
if (!(top_level)) {
|
||||||
body = PushNode.wrap(rvar, body);
|
body = PushNode.wrap(rvar, body);
|
||||||
}
|
}
|
||||||
@@ -1542,8 +1540,15 @@
|
|||||||
//### ClosureNode
|
//### ClosureNode
|
||||||
// A faux-node used to wrap an expressions body in a closure.
|
// A faux-node used to wrap an expressions body in a closure.
|
||||||
ClosureNode = (exports.ClosureNode = {
|
ClosureNode = (exports.ClosureNode = {
|
||||||
|
// Wrap the expressions body, unless it contains a pure statement,
|
||||||
|
// in which case, no dice.
|
||||||
wrap: function wrap(expressions, statement) {
|
wrap: function wrap(expressions, statement) {
|
||||||
var call, func;
|
var call, func;
|
||||||
|
if (expressions.contains(function(n) {
|
||||||
|
return n.is_pure_statement();
|
||||||
|
})) {
|
||||||
|
return expressions;
|
||||||
|
}
|
||||||
func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])));
|
func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])));
|
||||||
call = new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')]);
|
call = new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')]);
|
||||||
return statement ? Expressions.wrap([call]) : call;
|
return statement ? Expressions.wrap([call]) : call;
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ exports.BaseNode: class BaseNode
|
|||||||
del @options, 'operation' unless this instanceof ValueNode
|
del @options, 'operation' unless this instanceof ValueNode
|
||||||
top: if @top_sensitive() then @options.top else del @options, 'top'
|
top: if @top_sensitive() then @options.top else del @options, 'top'
|
||||||
closure: @is_statement() and not @is_pure_statement() and not top and
|
closure: @is_statement() and not @is_pure_statement() and not top and
|
||||||
not @options.returns and not (this instanceof CommentNode) and
|
not @options.returns and not (this instanceof CommentNode)
|
||||||
not @contains (node) -> node.is_pure_statement()
|
|
||||||
if closure then @compile_closure(@options) else @compile_node(@options)
|
if closure then @compile_closure(@options) else @compile_node(@options)
|
||||||
|
|
||||||
# Statements converted into expressions via closure-wrapping share a scope
|
# Statements converted into expressions via closure-wrapping share a scope
|
||||||
@@ -1024,8 +1023,7 @@ exports.ForNode: class ForNode extends BaseNode
|
|||||||
for_part: "$ivar = 0, $lvar = ${svar}.length; $ivar < $lvar; $step_part"
|
for_part: "$ivar = 0, $lvar = ${svar}.length; $ivar < $lvar; $step_part"
|
||||||
set_result: if rvar then @idt() + rvar + ' = []; ' else @idt()
|
set_result: if rvar then @idt() + rvar + ' = []; ' else @idt()
|
||||||
return_result: rvar or ''
|
return_result: rvar or ''
|
||||||
if top_level and not @contains((n) -> n.is_pure_statement()) and @contains((n) -> n instanceof CodeNode)
|
body: ClosureNode.wrap(body, true) if top_level and body.contains (n) -> n instanceof CodeNode
|
||||||
body: ClosureNode.wrap(body, true)
|
|
||||||
body: PushNode.wrap(rvar, body) unless top_level
|
body: PushNode.wrap(rvar, body) unless top_level
|
||||||
if o.returns
|
if o.returns
|
||||||
return_result: 'return ' + return_result
|
return_result: 'return ' + return_result
|
||||||
@@ -1172,7 +1170,10 @@ PushNode: exports.PushNode: {
|
|||||||
# A faux-node used to wrap an expressions body in a closure.
|
# A faux-node used to wrap an expressions body in a closure.
|
||||||
ClosureNode: exports.ClosureNode: {
|
ClosureNode: exports.ClosureNode: {
|
||||||
|
|
||||||
|
# Wrap the expressions body, unless it contains a pure statement,
|
||||||
|
# in which case, no dice.
|
||||||
wrap: (expressions, statement) ->
|
wrap: (expressions, statement) ->
|
||||||
|
return expressions if expressions.contains (n) -> n.is_pure_statement()
|
||||||
func: new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
|
func: new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
|
||||||
call: new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')])
|
call: new CallNode(new ValueNode(func, [new AccessorNode(literal('call'))]), [literal('this')])
|
||||||
if statement then Expressions.wrap([call]) else call
|
if statement then Expressions.wrap([call]) else call
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
# Test with break at the top level.
|
# Test with break at the top level.
|
||||||
a: [1,2,3]
|
array: [1,2,3]
|
||||||
call_with_lambda: (l) -> null
|
call_with_lambda: (l) -> null
|
||||||
for i in a
|
for i in array
|
||||||
a: call_with_lambda(->)
|
result: call_with_lambda(->)
|
||||||
if i == 2
|
if i == 2
|
||||||
puts "i = 2"
|
puts "i = 2"
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
|
|
||||||
ok a is null
|
ok result is null
|
||||||
|
|
||||||
|
|
||||||
# Test with break *not* at the top level.
|
# Test with break *not* at the top level.
|
||||||
some_func: (input) ->
|
some_func: (input) ->
|
||||||
takes_lambda: (l) -> null
|
takes_lambda: (l) -> null
|
||||||
for i in [1,2]
|
for i in [1,2]
|
||||||
arbitraty_var: takes_lambda(->)
|
result: takes_lambda(->)
|
||||||
if input == 1
|
if input == 1
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user