mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
merging #1353
This commit is contained in:
28
lib/nodes.js
28
lib/nodes.js
@@ -1271,7 +1271,10 @@
|
||||
Assign.prototype.compileConditional = function(o) {
|
||||
var left, rite, _ref2;
|
||||
_ref2 = this.variable.cacheReference(o), left = _ref2[0], rite = _ref2[1];
|
||||
return new Op(this.context.slice(0, -1), left, new Assign(rite, this.value, '='), void 0, __indexOf.call(this.context, "?") >= 0).compile(o);
|
||||
if (__indexOf.call(this.context, "?") >= 0) {
|
||||
o.isExistentialEquals = true;
|
||||
}
|
||||
return new Op(this.context.slice(0, -1), left, new Assign(rite, this.value, '=')).compile(o);
|
||||
};
|
||||
Assign.prototype.compileSplice = function(o) {
|
||||
var code, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
|
||||
@@ -1569,9 +1572,8 @@
|
||||
exports.Op = Op = (function() {
|
||||
var CONVERSIONS, INVERSIONS;
|
||||
__extends(Op, Base);
|
||||
function Op(op, first, second, flip, isExistentialEquals) {
|
||||
function Op(op, first, second, flip) {
|
||||
var call;
|
||||
this.isExistentialEquals = isExistentialEquals;
|
||||
if (op === 'in') {
|
||||
return new In(first, second);
|
||||
}
|
||||
@@ -1688,15 +1690,9 @@
|
||||
fst = this.first;
|
||||
ref = fst;
|
||||
}
|
||||
if (this.isExistentialEquals) {
|
||||
return new If(new Existence(fst).invert(), this.second, {
|
||||
type: 'if'
|
||||
}).addElse(fst).compile(o);
|
||||
} else {
|
||||
return new If(new Existence(fst), ref, {
|
||||
type: 'if'
|
||||
}).addElse(this.second).compile(o);
|
||||
}
|
||||
return new If(new Existence(fst), ref, {
|
||||
type: 'if'
|
||||
}).addElse(this.second).compile(o);
|
||||
};
|
||||
Op.prototype.compileUnary = function(o) {
|
||||
var op, parts;
|
||||
@@ -2158,8 +2154,14 @@
|
||||
}
|
||||
};
|
||||
If.prototype.compileStatement = function(o) {
|
||||
var body, child, cond, ifPart;
|
||||
var body, child, cond, exeq, ifPart;
|
||||
child = del(o, 'chainChild');
|
||||
exeq = del(o, 'isExistentialEquals');
|
||||
if (exeq) {
|
||||
return new If(this.condition.invert(), this.elseBodyNode(), {
|
||||
type: 'if'
|
||||
}).compile(o);
|
||||
}
|
||||
cond = this.condition.compile(o, LEVEL_PAREN);
|
||||
o.indent += TAB;
|
||||
body = this.ensureBlock(this.body).compile(o);
|
||||
|
||||
@@ -1020,7 +1020,8 @@ exports.Assign = class Assign extends Base
|
||||
# more than once.
|
||||
compileConditional: (o) ->
|
||||
[left, rite] = @variable.cacheReference o
|
||||
new Op(@context.slice(0, -1), left, new Assign(rite, @value, '='), undefined, "?" in @context ).compile o
|
||||
if "?" in @context then o.isExistentialEquals = true
|
||||
new Op(@context.slice(0, -1), left, new Assign(rite, @value, '=') ).compile o
|
||||
|
||||
# Compile the assignment from an array splice literal, using JavaScript's
|
||||
# `Array#splice` method.
|
||||
@@ -1229,8 +1230,7 @@ exports.While = class While extends Base
|
||||
# Simple Arithmetic and logical operations. Performs some conversion from
|
||||
# CoffeeScript operations into their JavaScript equivalents.
|
||||
exports.Op = class Op extends Base
|
||||
|
||||
constructor: (op, first, second, flip, @isExistentialEquals ) ->
|
||||
constructor: (op, first, second, flip ) ->
|
||||
return new In first, second if op is 'in'
|
||||
if op is 'do'
|
||||
call = new Call first, first.params or []
|
||||
@@ -1328,10 +1328,7 @@ exports.Op = class Op extends Base
|
||||
else
|
||||
fst = @first
|
||||
ref = fst
|
||||
if @isExistentialEquals
|
||||
new If(new Existence(fst).invert(), @second, type: 'if').addElse(fst).compile o
|
||||
else
|
||||
new If(new Existence(fst), ref, type: 'if').addElse(@second).compile o
|
||||
new If(new Existence(fst), ref, type: 'if').addElse(@second).compile o
|
||||
|
||||
# Compile a unary **Op**.
|
||||
compileUnary: (o) ->
|
||||
@@ -1676,6 +1673,11 @@ exports.If = class If extends Base
|
||||
# force inner *else* bodies into statement form.
|
||||
compileStatement: (o) ->
|
||||
child = del o, 'chainChild'
|
||||
exeq = del o, 'isExistentialEquals'
|
||||
|
||||
if exeq
|
||||
return new If(@condition.invert(), @elseBodyNode(), type: 'if').compile o
|
||||
|
||||
cond = @condition.compile o, LEVEL_PAREN
|
||||
o.indent += TAB
|
||||
body = @ensureBlock(@body).compile o
|
||||
|
||||
@@ -269,8 +269,20 @@ test "existential assignment", ->
|
||||
d ?= nonce
|
||||
eq nonce, d
|
||||
|
||||
test "#1348, #1216: existential assignment comilation", ->
|
||||
test "#1348, #1216: existential assignment compilation", ->
|
||||
nonce = {}
|
||||
a = nonce
|
||||
b = (a ?= 0)
|
||||
eq nonce, b
|
||||
#the first ?= compiles into a statement; the second ?= compiles to a ternary expression
|
||||
eq a ?= b ?= 1, nonce
|
||||
|
||||
e ?= f ?= g ?= 1
|
||||
eq e + g, 2
|
||||
|
||||
#need to ensure the two vars are not defined, hence the strange names;
|
||||
# broke earlier when using c ?= d ?= 1 because `d` is declared elsewhere
|
||||
eq und1_1348 ?= und2_1348 ?= 1, 1
|
||||
|
||||
if a then a ?= 2 else a = 3
|
||||
eq a, nonce
|
||||
|
||||
Reference in New Issue
Block a user