mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
fbc77f7445
This is an upstream port of https://github.com/decaffeinate/coffeescript/pull/24 In a case like `new A().b(c)`, the jison structure ends up being different from the resulting AST. To the jison parser, this is the `new` unary operator applied to the expression `A().b(c)`. When the unary operator is applied, the `Call.prototype.newInstance` function traverses into the leftmost function call and sets the `isNew` flag to true, and the `Op` constructor returns the `Call` node so that the call is used in place of the unary operator. However, the code wasn't updating the node location data, so this commit fixes that. It's sort of hard to get the location data in `newInstance`, so we set a flag on every affected node in `newInstance` and override `updateLocationDataIfMissing` (which is called with the location data after the fact) so that it updates just the starting position.
80 lines
2.3 KiB
CoffeeScript
80 lines
2.3 KiB
CoffeeScript
# Parser
|
|
# ---------
|
|
|
|
test "operator precedence for logical operators", ->
|
|
source = '''
|
|
a or b and c
|
|
'''
|
|
block = CoffeeScript.nodes source
|
|
[expression] = block.expressions
|
|
eq expression.first.base.value, 'a'
|
|
eq expression.operator, '||'
|
|
eq expression.second.first.base.value, 'b'
|
|
eq expression.second.operator, '&&'
|
|
eq expression.second.second.base.value, 'c'
|
|
|
|
test "operator precedence for bitwise operators", ->
|
|
source = '''
|
|
a | b ^ c & d
|
|
'''
|
|
block = CoffeeScript.nodes source
|
|
[expression] = block.expressions
|
|
eq expression.first.base.value, 'a'
|
|
eq expression.operator, '|'
|
|
eq expression.second.first.base.value, 'b'
|
|
eq expression.second.operator, '^'
|
|
eq expression.second.second.first.base.value, 'c'
|
|
eq expression.second.second.operator, '&'
|
|
eq expression.second.second.second.base.value, 'd'
|
|
|
|
test "operator precedence for binary ? operator", ->
|
|
source = '''
|
|
a ? b and c
|
|
'''
|
|
block = CoffeeScript.nodes source
|
|
[expression] = block.expressions
|
|
eq expression.first.base.value, 'a'
|
|
eq expression.operator, '?'
|
|
eq expression.second.first.base.value, 'b'
|
|
eq expression.second.operator, '&&'
|
|
eq expression.second.second.base.value, 'c'
|
|
|
|
test "new calls have a range including the new", ->
|
|
source = '''
|
|
a = new B().c(d)
|
|
'''
|
|
block = CoffeeScript.nodes source
|
|
|
|
assertColumnRange = (node, firstColumn, lastColumn) ->
|
|
eq node.locationData.first_line, 0
|
|
eq node.locationData.first_column, firstColumn
|
|
eq node.locationData.last_line, 0
|
|
eq node.locationData.last_column, lastColumn
|
|
|
|
[assign] = block.expressions
|
|
outerCall = assign.value
|
|
innerValue = outerCall.variable
|
|
innerCall = innerValue.base
|
|
|
|
assertColumnRange assign, 0, 15
|
|
assertColumnRange outerCall, 4, 15
|
|
assertColumnRange innerValue, 4, 12
|
|
assertColumnRange innerCall, 4, 10
|
|
|
|
test "location data is properly set for nested `new`", ->
|
|
source = '''
|
|
new new A()()
|
|
'''
|
|
block = CoffeeScript.nodes source
|
|
|
|
assertColumnRange = (node, firstColumn, lastColumn) ->
|
|
eq node.locationData.first_line, 0
|
|
eq node.locationData.first_column, firstColumn
|
|
eq node.locationData.last_line, 0
|
|
eq node.locationData.last_column, lastColumn
|
|
|
|
[outerCall] = block.expressions
|
|
innerCall = outerCall.variable
|
|
|
|
assertColumnRange outerCall, 0, 12
|
|
assertColumnRange innerCall, 4, 10
|