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

linting: disallow t.identifier("undefined") in plugins #6096

Merged
merged 2 commits into from
Aug 24, 2017

Conversation

noahlemen
Copy link
Member

Q                       A
Fixed Issues
Patch: Bug Fix?
Major: Breaking Change?
Minor: New Feature?
Tests Added/Pass?
Spec Compliancy?
License MIT
Doc PR
Any Dependency Changes?

@hzoo mentioned the idea to lint to disallow t.identifier("undefined") in #6076 (comment)

this PR implements a basic eslint rule to enforce this, as well as changes the remaining instances to use buildUndefinedNode()

questions:

  1. the current rule is not very robust, but seems to cover the existing instances in the code -- is it worth spending the time to make this better? (mostly asking bc i'm a noob at writing eslint rules and figured it'd be good to start this conversation before i spend too much time on it)
    • if a variable is assigned to t.identifier and the function is called via that variable it will not be caught
    • if a variable equals "undefined" and passed to t.identifier, this will not be caught (e: const foo = "undefined"; t.identifier(foo))
  2. the descriptor for the rule is currently "prefer path.scope.buildUndefinedNode() to creating an undefined identifier directly" -- any recommendations for a better one?
  3. where should the rule go? it is currently placed in a eslint_rules/ directory at root
  4. should tests be added for the rule? if so, where?
  5. currently only applies this rule to files in packages/babel-plugin-* -- should this be applied more broadly?

thanks for reading! hope this is helpful 😄

@xtuc
Copy link
Member

xtuc commented Aug 14, 2017

Nice. We could create a separate project from this and publish it (babel-linter?).

@existentialism
Copy link
Member

eslint-plugin-babel?

@hzoo
Copy link
Member

hzoo commented Aug 14, 2017

I don't really want us to maintain another project lol, if we wanted it should go in existing package or we just use it internally until it makes more sense to use elsewhere. And regarding the robustness, may need to check eslint's api otherwise it's easy to do the same thing in a babel transform

@noahlemen
Copy link
Member Author

@hzoo to clarify, the proposed babel transform would replace instances of undefined with the result of scope.buildUndefinedNode()?

@hzoo
Copy link
Member

hzoo commented Aug 14, 2017

it would either be a codemod or it would just throw like a linting rule (this is just if you aren't able to implement the same functionality with eslint, otherwise can just use what you have which covered a bunch of cases we have in the codebase already)

@noahlemen
Copy link
Member Author

@hzoo ok, cool. i think it should be doable with eslint. gonna spend a bit more time in it, will update here when i do

@hzoo
Copy link
Member

hzoo commented Aug 14, 2017

Doesn't have to be in this pr either because it already provides a benefit

@noahlemen
Copy link
Member Author

okay! well, if this gets deemed ready-to-merge i'll submit improvements in a followup PR

) {
context.report(
node,
"prefer path.scope.buildUndefinedNode() to creating an undefined identifier directly"
Copy link
Member

@xtuc xtuc Aug 14, 2017

Choose a reason for hiding this comment

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

to creating -> to create (please correct me if i'm wrong)

Copy link
Member Author

Choose a reason for hiding this comment

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

hmm, i think the wording i chose here might be strange

perhaps "to" -> "instead of" ?

Copy link
Member

Choose a reason for hiding this comment

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

I would say:

t.identifier("undefined") is prohibited, please use path.scope.buildUndefinedNode() instead.

It's not really prohibited but I think it's clear enought

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 I agree with that

also, maybe "restricted" instead of "prohibited"? that seems to be what the core eslint rules use in phrases like this

Copy link
Member

Choose a reason for hiding this comment

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

yes, it sounds great

Copy link
Member

Choose a reason for hiding this comment

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

Maybe just:

Use path.scope.buildUndefinedNode() to create an undefined identifier directly.

@nicolo-ribaudo
Copy link
Member

Question: is this rule autofixable?

@noahlemen
Copy link
Member Author

@nicolo-ribaudo unfortunately, i think it's not always easily autofixable.

for example, in https://github.com/babel/babel/pull/6076/files#diff-c560784a38cbcda22571f3ccc9511964R32 t.identifier("undefined") was used in a function outside of the visitor itself and therefore had to have path.scope passed to it

@jridgewell
Copy link
Member

#5971 should fix this.

@noahlemen
Copy link
Member Author

gonna close this, assuming that #5971 fixes this as mentioned above

feel free to reopen if there's any value in adding this rule anyway

@noahlemen noahlemen closed this Aug 17, 2017
@noahlemen noahlemen deleted the no-undefined-identifier branch August 17, 2017 16:27
@hzoo
Copy link
Member

hzoo commented Aug 17, 2017

@kedromelon #5971 shouldn't fix the t.identfier('undefined') issue though? otherwise we would have to update the places where your linting rule already caught issues? If anything should at least change those files if not add the rule anyway

@noahlemen
Copy link
Member Author

oh, okay. perhaps i misunderstood that PR -- how does #5971 relate here then? i'm not sure i follow

@jridgewell
Copy link
Member

I was incorrect, we don't forbid it in #5971. I thought we had a UndefinedLiteral, but got it mixed up with Scope#buildUndefinedNode

@noahlemen noahlemen restored the no-undefined-identifier branch August 17, 2017 19:02
@noahlemen
Copy link
Member Author

@jridgewell gotcha, thanks for clarifying!

@noahlemen noahlemen reopened this Aug 17, 2017
@hzoo hzoo added the PR: Internal 🏠 A type of pull request used for our changelog categories label Aug 22, 2017
@noahlemen
Copy link
Member Author

wasn't able to figure out improvements to robustness -- skimmed the eslint docs and also checked out some common plugins with similar rules (mocha and lodash had a few that seemed applicable), seems like this is the most we're able to get out of eslint

(if anyone has some insight to drop though on how we could accomplish this, please let me know)

next i'll look into doing it via a babel transform instead, if that still seems like a good alternative

@jridgewell jridgewell merged commit 2db0c3a into babel:7.0 Aug 24, 2017
@noahlemen noahlemen deleted the no-undefined-identifier branch August 24, 2017 20:07
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 6, 2019
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 PR: Internal 🏠 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants