Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make isReferenced return false for method parameter name #11089

Conversation

brokensandals
Copy link
Contributor

Q                       A
Fixed Issues? Fixes #11087
Patch: Bug Fix? Yes
Major: Breaking Change? No
Minor: New Feature? No
Tests Added + Pass? Yes
Documentation PR Link N/A
Any Dependency Changes? No
License MIT

The isReferenced method (if I understand correctly) tries to determine if a given node is a reference to the value stored in some variable, as opposed to being e.g. a declaration of a variable or the left-hand-side of an assignment. As described in issue #11087, it currently misidentifies method parameter names as references; this fixes that.

The logic in isReferenced is based on the type of the parent node, and currently Object/ClassProperty and Object/Class(Private)Method parent nodes are handled by the same case block. That block checks for when the child node is the key of the property/method node, and for when it's part of an ObjectPattern, but otherwise returns true. This change adds a check for when the child node is part of the params list of the parent node.

@nicolo-ribaudo nicolo-ribaudo added pkg: types PR: Bug Fix 🐛 A type of pull request used for our changelog categories labels Feb 3, 2020
if (param === node) {
return false;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

What about using parent.params.indexOf(node) !== -1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yeah, that's much better. Updated.

@@ -66,6 +67,9 @@ export default function isReferenced(
if (parent.value === node) {
return !grandparent || grandparent.type !== "ObjectPattern";
}
if (parent.params && parent.params.indexOf(node) !== -1) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (parent.params && parent.params.indexOf(node) !== -1) {
if (parent.params.includes(node)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nicolo-ribaudo you asked me to remove the use of .includes for the sake of Node 6 support, but now that I check, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes indicates it's supported there. Is using .includes ok?

Copy link
Member

Choose a reason for hiding this comment

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

Oh I thought that it wasn't 😅

If it works, it's ok to use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, I checked a node 6 repl and .includes seems to work.

@jridgewell removing the check for whether parent.params is present before calling .includes, does mean an error would be thrown if we reach this line when parent is an ObjectProperty or ClassProperty. The only way that could happen is if node is neither the key nor the value of the parent Object/ClassProperty, which I think currently could only happen if it's a decorator or type annotation. I don't know whether it's important for isReferenced to be able to handle being called with non-identifier-like nodes such as Decorator.

Copy link
Member

Choose a reason for hiding this comment

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

What about refactoring the switch like this then?

case "ClassMethod":
case "ClassPrivateMethod":
case "ObjectMethod":
  check parent.params.includes(node);
  /* falls through */
case "ObjectProperty":
case "ClassProperty":
case "ClassPrivateProperty":
  // all the existing checks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That works, updated.

I'm now getting some failing tests in babel-preset-env related to "edge" being 18 instead of the fixture's expectation of 17, but I get them on master too - I'm guessing it was caused by a new version of caniuse-lite being released today.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah ignore those tests

case "ClassMethod":
case "ClassPrivateMethod":
case "ObjectMethod":
if (parent.params.includes(node)) {
Copy link
Member

Choose a reason for hiding this comment

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

May want to add that a comment that fall-through is intentional

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

Thanks!

@nicolo-ribaudo nicolo-ribaudo changed the title fix 11087: make isReferenced return false for method parameter name nodes Make isReferenced return false for method parameter name Feb 5, 2020
@nicolo-ribaudo nicolo-ribaudo merged commit 7615635 into babel:master Feb 5, 2020
rajasekarm pushed a commit to rajasekarm/babel that referenced this pull request Feb 17, 2020
* Change isReferenced to return false for object/class method parameter names.

* use indexOf instead of for-of loop

* replace `.indexOf` check with `.includes` and assume `parent.params` exists

Co-Authored-By: Justin Ridgewell <justin@ridgewell.name>

* check .params within case block for ClassMethod/ClassPrivateMethod/ObjectMethod only

* add comment clarifying that case clause fall-through is intentional

Co-authored-by: Justin Ridgewell <justin@ridgewell.name>
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 7, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: types PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

types.isReferenced incorrectly returns true for object/class method param identifiers
4 participants