From 3b5c8890408a042dad1d493f4d2629b9e40d8b86 Mon Sep 17 00:00:00 2001 From: Michael Ficarra Date: Wed, 21 Sep 2011 18:56:20 -0400 Subject: [PATCH] fixes #1722: operator precedence in unbounded slice compilation --- lib/coffee-script/nodes.js | 4 ++-- lib/coffee-script/rewriter.js | 4 ++-- src/nodes.coffee | 4 ++-- test/slicing_and_splicing.coffee | 7 +++++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index 38f6d650..08ec7cf4 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -950,9 +950,9 @@ var compiled, from, fromStr, to, toStr, _ref2; _ref2 = this.range, to = _ref2.to, from = _ref2.from; fromStr = from && from.compile(o, LEVEL_PAREN) || '0'; - compiled = to && to.compile(o, LEVEL_PAREN); + compiled = to && to.compile(o, LEVEL_ACCESS); if (to && !(!this.range.exclusive && +compiled === -1)) { - toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? (+compiled + 1).toString() : "(" + compiled + " + 1) || 9e9"); + toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? (+compiled + 1).toString() : "" + compiled + " + 1 || 9e9"); } return ".slice(" + fromStr + (toStr || '') + ")"; }; diff --git a/lib/coffee-script/rewriter.js b/lib/coffee-script/rewriter.js index 31e90e9f..578741b0 100644 --- a/lib/coffee-script/rewriter.js +++ b/lib/coffee-script/rewriter.js @@ -106,7 +106,7 @@ startIndent = 0; condition = function(token, i) { var one, tag, three, two, _ref, _ref2; - _ref = this.tokens.slice(i + 1, (i + 3 + 1) || 9e9), one = _ref[0], two = _ref[1], three = _ref[2]; + _ref = this.tokens.slice(i + 1, (i + 3) + 1 || 9e9), one = _ref[0], two = _ref[1], three = _ref[2]; if ('HERECOMMENT' === (one != null ? one[0] : void 0)) return false; tag = token[0]; return ((tag === 'TERMINATOR' || tag === 'OUTDENT') && !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':')) || (tag === ',' && one && ((_ref2 = one[0]) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT')); @@ -155,7 +155,7 @@ var callObject, current, next, prev, seenControl, seenSingle, tag, _ref, _ref2, _ref3; tag = token[0]; if (tag === 'CLASS' || tag === 'IF') noCall = true; - _ref = tokens.slice(i - 1, (i + 1 + 1) || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2]; + _ref = tokens.slice(i - 1, (i + 1) + 1 || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2]; callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0); seenSingle = false; seenControl = false; diff --git a/src/nodes.coffee b/src/nodes.coffee index 59de65f3..2f3ceadf 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -728,14 +728,14 @@ exports.Slice = class Slice extends Base compileNode: (o) -> {to, from} = @range fromStr = from and from.compile(o, LEVEL_PAREN) or '0' - compiled = to and to.compile o, LEVEL_PAREN + compiled = to and to.compile o, LEVEL_ACCESS if to and not (not @range.exclusive and +compiled is -1) toStr = ', ' + if @range.exclusive compiled else if SIMPLENUM.test compiled (+compiled + 1).toString() else - "(#{compiled} + 1) || 9e9" + "#{compiled} + 1 || 9e9" ".slice(#{ fromStr }#{ toStr or '' })" #### Obj diff --git a/test/slicing_and_splicing.coffee b/test/slicing_and_splicing.coffee index 00206367..768c8004 100644 --- a/test/slicing_and_splicing.coffee +++ b/test/slicing_and_splicing.coffee @@ -114,3 +114,10 @@ test "the return value of a splice literal should be the RHS", -> eq (ary[0..] = 3), 3 arrayEq [ary[0..0] = 0], [0] + +test "#1722: operator precedence in unbounded slice compilation", -> + list = [0..9] + n = 2 # some truthy number in `list` + arrayEq [0..n], list[..n] + arrayEq [0..n], list[..n or 0] + arrayEq [0..n], list[..if n then n else 0]