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
New: Allow parsers to supply Visitor Keys/Fallback (fixes #8392) #8582
Conversation
LGTM |
@soda0289, thanks for your PR! By analyzing the history of the files in this pull request, we identified @nzakas, @mysticatea and @roadhump to be potential reviewers. |
Thanks for working on this! I'm fine with this implementation. I'd like to re-evaluate the current monkeypatching of type annotations In light of the changes being made in this PR. Since we don't support parsing of types by default, I wonder if it might actually make more sense to revert the monkeypatching I added and have parsers that support types supply VisitorKeys instead. That way the responsibility for types isn't split between the monkeypatched estraverse.VisitorKeys and the parser-supplied VisitorKeys. We could still update core rules to account for types should they exist (as we do with JSX nodes), since there is an official ESTree extension for them. @eslint/eslint-team Thoughts? If we decide we want to revert the monkeypatching I think we should do so soon, since we're stilll doing alpha releases of v4. |
@kaicataldo I also believe we should remove type annotations from being traversed. Type annotations are not defined as a node by ESTree only where they should be and each parser may do things differently. So it makes sense for a parser to define its own visitor keys for type annotations. A parser may also have type annotations in places that ESLint would never traverse anyway. I think it might conflict with #8465 but since it only runs once when the traverser is initialized it should be. |
Made a PR reverting my previous commits so that we can discuss: #8584 |
My position is:
|
@mysticatea You are correct that this change is not enough to allow new node types to be scoped but it still reduces number incorrect errors rules likes Currently you can not write rules for decorators, type annotations, or type parameters because they are children of known nodes. This would be fixed by this change. The visitor fallback that we currently use will traverse every single property of unknown nodes this causes eslint-scope to mark code like the following as failing: interface Foo {
bar: string;
} It complains that Even when we update eslint-scope there are still parts of code-path-analysis that would need to be updated to handle unknown nodes as well. I think trying to update everything at once would be to difficult and should be done separately. Improvements can be made by this change alone. Finally I think this change is breaking since rule authors would now need to write rules that could traverse any child of a known node instead of the predefined VisitorKeys. Although I think we have made changes to VisitorKeys before which were not considered breaking changes. I don't think updating eslint-scope or code-path-analysis, to accept new node types, would be a breaking change for eslint, since rules would behave the same way, and would allow us to update these at a later time. |
Thank you for the details. Hmm, but I'm not sure who use visitor keys for eslint-scope because The |
I do not like the idea of monkey patching I could support having the parsers expose their own scope analysis tool but they would be exact forks of I can but some more thought into a solution for |
Sure.
Is it true?
I think those are separated matters.
I don't think good if parsers return the all options of the scope analyzer because the options will increase for each found problems. |
I didn't realize a monkey patch was required to set options such as I think having parser create their own fork would work well, and makes sense given the current situation. I have patches for I still think its possible to create one version of |
Should we discuss this at the next TSC meeting? Sounds like we have some concrete ideas and have to decide on a path forward. |
We discussed this in the 2017-06-01 TSC meeting and had two questions:
If the answer to both of those questions is yes, then we can accept this! |
Yes, this PR adds
I have not tested performance so its difficult for me to say what result would occur. I can see a positive performance gain coming from adding |
In fact, we had been using |
@mysticatea I can run some performance tests but I'm guessing it will be related to the number of keys I pass in. We could submit a PR to estraverse to allow the VisitorKeys to be replaced, with some new option, instead of merged with the defaults. I think we should avoid overriding the exported VisitorKeys since it is used by other applications. |
Friendly ping |
I realized some problems, so I made another PR: #8755.
|
@mysticatea Thanks for looking into this! I'll take a look at your PR. |
Should this be closed in favor of #8755? |
Yes, I think so. Thanks @soda0289 for getting this started! |
What is the purpose of this pull request? (put an "X" next to item)
[ X ] Add something to the core
Still need to write tests just need feedback on implementation. This would allow for typescript-eslint-parser to fix issues with the
no-undef
rule and allow rules to traverse decorators and type parameters.What changes did you make? (Give an overview)
Modified the Traverser class to accept an optional VisitorKey object and VisitorFallback function. These are then passed into eslint-scope and estravese.
Updated the parseForESLint function to have two extra options:
These values are passed into the Traverser constructor.
Is there anything you'd like reviewers to focus on?
Currently the visitorKeys passed into eslint, with the
parseForESLint()
, modifies the VisitorKeys by replacing a key. This is the default behavior of both estraverse and eslint-scope. I think this should be fine as it allows parsers to both add and delete visitor properties but maybe there is better way.Both VisitorKeys and VisitorFallback are passed into Traverser but it could be its own class that wraps them both.