mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Fixing first part of #614 -- improperly cached existential operator, when first operand is a function call.
This commit is contained in:
parent
1d6eca76f8
commit
c90a75ebc5
3 changed files with 22 additions and 18 deletions
21
lib/nodes.js
21
lib/nodes.js
|
@ -1305,17 +1305,16 @@
|
||||||
o.scope.find(first);
|
o.scope.find(first);
|
||||||
}
|
}
|
||||||
if (this.operator === '?=') {
|
if (this.operator === '?=') {
|
||||||
return ("" + (first) + " = " + (ExistenceNode.compileTest(o, literal(firstVar))) + " ? " + (firstVar) + " : " + (second));
|
return ("" + (first) + " = " + (ExistenceNode.compileTest(o, literal(firstVar))[0]) + " ? " + (firstVar) + " : " + (second));
|
||||||
}
|
}
|
||||||
return "" + (first) + " = " + (firstVar) + " " + (this.operator.substr(0, 2)) + " " + (second);
|
return "" + (first) + " = " + (firstVar) + " " + (this.operator.substr(0, 2)) + " " + (second);
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileExistence = function(o) {
|
OpNode.prototype.compileExistence = function(o) {
|
||||||
var _b, first, second, test;
|
var _b, ref, test;
|
||||||
_b = [this.first.compile(o), this.second.compile(o)];
|
_b = ExistenceNode.compileTest(o, this.first);
|
||||||
first = _b[0];
|
test = _b[0];
|
||||||
second = _b[1];
|
ref = _b[1];
|
||||||
test = ExistenceNode.compileTest(o, this.first);
|
return "" + (test) + " ? " + (ref) + " : " + (this.second.compile(o));
|
||||||
return "" + (test) + " ? " + (first) + " : " + (second);
|
|
||||||
};
|
};
|
||||||
OpNode.prototype.compileUnary = function(o) {
|
OpNode.prototype.compileUnary = function(o) {
|
||||||
var parts, space;
|
var parts, space;
|
||||||
|
@ -1439,14 +1438,16 @@
|
||||||
ExistenceNode.prototype["class"] = 'ExistenceNode';
|
ExistenceNode.prototype["class"] = 'ExistenceNode';
|
||||||
ExistenceNode.prototype.children = ['expression'];
|
ExistenceNode.prototype.children = ['expression'];
|
||||||
ExistenceNode.prototype.compileNode = function(o) {
|
ExistenceNode.prototype.compileNode = function(o) {
|
||||||
return ExistenceNode.compileTest(o, this.expression);
|
return ExistenceNode.compileTest(o, this.expression)[0];
|
||||||
};
|
};
|
||||||
ExistenceNode.compileTest = function(o, variable) {
|
ExistenceNode.compileTest = function(o, variable) {
|
||||||
var _b, first, second;
|
var _b, first, second;
|
||||||
_b = variable.compileReference(o);
|
_b = variable.compileReference(o, {
|
||||||
|
precompile: true
|
||||||
|
});
|
||||||
first = _b[0];
|
first = _b[0];
|
||||||
second = _b[1];
|
second = _b[1];
|
||||||
return "(typeof " + (first.compile(o)) + " !== \"undefined\" && " + (second.compile(o)) + " !== null)";
|
return [("(typeof " + (first) + " !== \"undefined\" && " + (second) + " !== null)"), second];
|
||||||
};
|
};
|
||||||
return ExistenceNode;
|
return ExistenceNode;
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
|
@ -1114,15 +1114,14 @@ exports.OpNode = class OpNode extends BaseNode
|
||||||
second = @second.compile o
|
second = @second.compile o
|
||||||
second = "(#{second})" if @second instanceof OpNode
|
second = "(#{second})" if @second instanceof OpNode
|
||||||
o.scope.find(first) if first.match(IDENTIFIER)
|
o.scope.find(first) if first.match(IDENTIFIER)
|
||||||
return "#{first} = #{ ExistenceNode.compileTest(o, literal(firstVar)) } ? #{firstVar} : #{second}" if @operator is '?='
|
return "#{first} = #{ ExistenceNode.compileTest(o, literal(firstVar))[0] } ? #{firstVar} : #{second}" if @operator is '?='
|
||||||
"#{first} = #{firstVar} #{ @operator.substr(0, 2) } #{second}"
|
"#{first} = #{firstVar} #{ @operator.substr(0, 2) } #{second}"
|
||||||
|
|
||||||
# If this is an existence operator, we delegate to `ExistenceNode.compileTest`
|
# If this is an existence operator, we delegate to `ExistenceNode.compileTest`
|
||||||
# to give us the safe references for the variables.
|
# to give us the safe references for the variables.
|
||||||
compileExistence: (o) ->
|
compileExistence: (o) ->
|
||||||
[first, second] = [@first.compile(o), @second.compile(o)]
|
[test, ref] = ExistenceNode.compileTest(o, @first)
|
||||||
test = ExistenceNode.compileTest(o, @first)
|
"#{test} ? #{ref} : #{ @second.compile(o) }"
|
||||||
"#{test} ? #{first} : #{second}"
|
|
||||||
|
|
||||||
# Compile a unary **OpNode**.
|
# Compile a unary **OpNode**.
|
||||||
compileUnary: (o) ->
|
compileUnary: (o) ->
|
||||||
|
@ -1215,14 +1214,14 @@ exports.ExistenceNode = class ExistenceNode extends BaseNode
|
||||||
constructor: (@expression) ->
|
constructor: (@expression) ->
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
ExistenceNode.compileTest(o, @expression)
|
ExistenceNode.compileTest(o, @expression)[0]
|
||||||
|
|
||||||
# The meat of the **ExistenceNode** is in this static `compileTest` method
|
# The meat of the **ExistenceNode** is in this static `compileTest` method
|
||||||
# because other nodes like to check the existence of their variables as well.
|
# because other nodes like to check the existence of their variables as well.
|
||||||
# Be careful not to double-evaluate anything.
|
# Be careful not to double-evaluate anything.
|
||||||
@compileTest: (o, variable) ->
|
@compileTest: (o, variable) ->
|
||||||
[first, second] = variable.compileReference o
|
[first, second] = variable.compileReference o, precompile: yes
|
||||||
"(typeof #{first.compile(o)} !== \"undefined\" && #{second.compile(o)} !== null)"
|
["(typeof #{first} !== \"undefined\" && #{second} !== null)", second]
|
||||||
|
|
||||||
#### ParentheticalNode
|
#### ParentheticalNode
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,13 @@ ok a is 10 and b is 10
|
||||||
# The existential operator.
|
# The existential operator.
|
||||||
z = null
|
z = null
|
||||||
x = z ? "EX"
|
x = z ? "EX"
|
||||||
|
|
||||||
ok z is null and x is "EX"
|
ok z is null and x is "EX"
|
||||||
|
|
||||||
|
i = 9
|
||||||
|
func = -> i += 1
|
||||||
|
result = func() ? 101
|
||||||
|
ok result is 10
|
||||||
|
|
||||||
|
|
||||||
# Only evaluate once.
|
# Only evaluate once.
|
||||||
counter = 0
|
counter = 0
|
||||||
|
|
Loading…
Add table
Reference in a new issue