Skip to content

Conversation

@alangpierce
Copy link
Contributor

This is an upstream port of decaffeinate#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.

This is an upstream port of decaffeinate#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.

assertColumnRange assign, 0, 15
assertColumnRange outerCall, 4, 15
assertColumnRange innerValue, 4, 12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 12 here? (I'm having a bit of a difficulty mapping outerCall, innerValue and innerCall to the corresponding parts of source.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outerCall is new B().c(d)
innerValue is new B().c
innerCall is new B()

All three of these needed to have their locations updated by this change, since previously they ignored the new on the left.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks like I got those right after all. And when counting again, I get it to 12, too. False alarm!

Copy link
Collaborator

@lydell lydell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lydell lydell merged commit d84c94d into jashkenas:master Feb 17, 2017
@GeoffreyBooth
Copy link
Collaborator

@alangpierce I’ve merged this into the 2 branch and it’s caused some broken tests over there. Do you mind please taking a look?

@alangpierce
Copy link
Contributor Author

@GeoffreyBooth ok, I looked into it and put up #4447.

@alangpierce alangpierce deleted the upstream-fix-new-location-data branch February 18, 2017 17:36
EsrefDurna added a commit to EsrefDurna/coffeescript that referenced this pull request Nov 12, 2025
…ocation-data

Properly update location data when setting a call to use `new`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants