Merge pull request #4445 from alangpierce/upstream-fix-new-location-data
Properly update location data when setting a call to use `new`
This commit is contained in:
commit
d84c94dc6d
|
@ -1024,6 +1024,22 @@
|
|||
|
||||
Call.prototype.children = ['variable', 'args'];
|
||||
|
||||
Call.prototype.updateLocationDataIfMissing = function(locationData) {
|
||||
var base, ref3;
|
||||
if (this.locationData && this.needsUpdatedStartLocation) {
|
||||
this.locationData.first_line = locationData.first_line;
|
||||
this.locationData.first_column = locationData.first_column;
|
||||
base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
|
||||
if (base.needsUpdatedStartLocation) {
|
||||
this.variable.locationData.first_line = locationData.first_line;
|
||||
this.variable.locationData.first_column = locationData.first_column;
|
||||
base.updateLocationDataIfMissing(locationData);
|
||||
}
|
||||
delete this.needsUpdatedStartLocation;
|
||||
}
|
||||
return Call.__super__.updateLocationDataIfMissing.apply(this, arguments);
|
||||
};
|
||||
|
||||
Call.prototype.newInstance = function() {
|
||||
var base, ref3;
|
||||
base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
|
||||
|
@ -1032,6 +1048,7 @@
|
|||
} else {
|
||||
this.isNew = true;
|
||||
}
|
||||
this.needsUpdatedStartLocation = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
|
|
@ -633,6 +633,21 @@ exports.Call = class Call extends Base
|
|||
|
||||
children: ['variable', 'args']
|
||||
|
||||
# When setting the location, we sometimes need to update the start location to
|
||||
# account for a newly-discovered `new` operator to the left of us. This
|
||||
# expands the range on the left, but not the right.
|
||||
updateLocationDataIfMissing: (locationData) ->
|
||||
if @locationData and @needsUpdatedStartLocation
|
||||
@locationData.first_line = locationData.first_line
|
||||
@locationData.first_column = locationData.first_column
|
||||
base = @variable?.base or @variable
|
||||
if base.needsUpdatedStartLocation
|
||||
@variable.locationData.first_line = locationData.first_line
|
||||
@variable.locationData.first_column = locationData.first_column
|
||||
base.updateLocationDataIfMissing locationData
|
||||
delete @needsUpdatedStartLocation
|
||||
super
|
||||
|
||||
# Tag this invocation as creating a new instance.
|
||||
newInstance: ->
|
||||
base = @variable?.base or @variable
|
||||
|
@ -640,6 +655,7 @@ exports.Call = class Call extends Base
|
|||
base.newInstance()
|
||||
else
|
||||
@isNew = true
|
||||
@needsUpdatedStartLocation = true
|
||||
this
|
||||
|
||||
# Soaked chained invocations unfold into if/else ternary structures.
|
||||
|
|
|
@ -38,3 +38,43 @@ test "operator precedence for binary ? 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
|
||||
|
|
Loading…
Reference in New Issue