jashkenas/coffeescript

Bug: wrong code is transpiled for function call without parentheses

rayzorben opened this issue · 2 comments

In this code, the first line compiles incorrectly and returns undefined, where in the 2nd it works and returns true. The only difference is omitting the parentheses around word(0) and word(1)

String::word = (n) -> @.split(' ')[n] ? undefined if @.length > 0
    
    wasLooking: (command) ->
        command?.word 0 in "look".getSubsets() and command?.word 1 in _lookDirections
        command?.word(0) in "look".getSubsets() and command?.word(1) in _lookDirections
      wasLooking(command) {
        var ref, ref1;
        if (command != null) {
          command.word(indexOf.call("look".getSubsets(), 0) >= 0 && (command != null ? command.word(indexOf.call(_lookDirections, 1) >= 0) : void 0));
        }
        return (ref = command != null ? command.word(0) : void 0, indexOf.call("look".getSubsets(), ref) >= 0) && (ref1 = command != null ? command.word(1) : void 0, indexOf.call(_lookDirections, ref1) >= 0);
      }

This is not a bug, but a precedence issue. Your first example is parsed as

command?.word(0 in "look".getSubsets() and command?.word 1 in _lookDirections)

Generally, implicit function calls have low precedence, in particular lower than in.

Makes sense, i've been preferring using parentheses for anything more than function arg anyway as it reads cleaner and probably prevents issues like this.