diff --git a/lib/nodes.js b/lib/nodes.js index a41acd6f..7aa45dda 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1322,6 +1322,7 @@ return While; }(); exports.Op = Op = function() { + var CONVERSIONS, INVERSIONS; function Op(op, first, second, flip) { if (op === 'in') { return new In(first, second); @@ -1334,18 +1335,18 @@ first = new Parens(first); } } - this.operator = this.CONVERSIONS[op] || op; + this.operator = CONVERSIONS[op] || op; this.first = first; this.second = second; this.flip = !!flip; } __extends(Op, Base); - Op.prototype.CONVERSIONS = { + CONVERSIONS = { '==': '===', '!=': '!==', 'of': 'in' }; - Op.prototype.INVERSIONS = { + INVERSIONS = { '!==': '===', '===': '!==', '>': '<=', @@ -1362,12 +1363,14 @@ return (_ref = this.operator) === '<' || _ref === '>' || _ref === '>=' || _ref === '<=' || _ref === '===' || _ref === '!=='; }; Op.prototype.invert = function() { - var op; - if (op = this.INVERSIONS[this.operator]) { + var fst, op, _ref; + if (op = INVERSIONS[this.operator]) { this.operator = op; return this; } else if (this.second) { return new Parens(this).invert(); + } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref = fst.operator) === '!' || _ref === 'in' || _ref === 'instanceof')) { + return fst; } else { return new Op('!', this); } diff --git a/src/nodes.coffee b/src/nodes.coffee index 31d2c6fc..0e31105f 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1047,19 +1047,19 @@ exports.Op = class Op extends Base if op is 'new' return first.newInstance() if first instanceof Call first = new Parens first if first instanceof Code and first.bound - @operator = @CONVERSIONS[op] or op + @operator = CONVERSIONS[op] or op @first = first @second = second @flip = !!flip # The map of conversions from CoffeeScript to JavaScript symbols. - CONVERSIONS: + CONVERSIONS = '==': '===' '!=': '!==' 'of': 'in' # The map of invertible operators. - INVERSIONS: + INVERSIONS = '!==': '===' '===': '!==' '>': '<=' @@ -1078,11 +1078,14 @@ exports.Op = class Op extends Base @operator in ['<', '>', '>=', '<=', '===', '!=='] invert: -> - if op = @INVERSIONS[@operator] + if op = INVERSIONS[@operator] @operator = op this else if @second new Parens(this).invert() + else if @operator is '!' and (fst = @first.unwrap()) instanceof Op and + fst.operator in ['!', 'in', 'instanceof'] + fst else new Op '!', this diff --git a/test/test_switch.coffee b/test/test_switch.coffee index 79616e20..bf48580b 100644 --- a/test/test_switch.coffee +++ b/test/test_switch.coffee @@ -54,11 +54,17 @@ ok result # Should be able to handle switches sans-condition. result = switch - when null then 1 - when 'truthful string' then 2 - else 3 + when null then 0 + when !1 then 1 + when '' not of {''} then 2 + when [] not instanceof Array then 3 + when true is false then 4 + when 'x' < 'y' > 'z' then 5 + when 'a' in ['b', 'c'] then 6 + when 'd' in (['e', 'f']) then 7 + else ok -ok result is 2 +eq result, ok # Should be able to use "@properties" within the switch clause.