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
feat: Implement SourceCode#markVariableAsUsed()
#17086
Conversation
👷 Deploy Preview for docs-eslint processing.
|
✅ Deploy Preview for docs-eslint ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
We're currently doing What's the benefit of this change, though? Whether a variable is used or not seems very context-dependent to me, more than just the static source code can know. |
This is part of the work for #16999. In order to allow ESLint to lint other languages, we need to remove anything that is JS-specific from What I'm interested in knowing about eslint-plugin-react's usage is whether or not you have an |
No, for the cases where it's a string from settings (like "React" or "createElement" or something), we have no nodes at all, and this change would presumably force us to add some visitors to locate the nodes. |
Okay, that's what I needed to know. I'll change the API to be |
lib/source-code/source-code.js
Outdated
const hasSpecialScope = this.scopeManager.isGlobalReturn() || | ||
this.scopeManager.isModule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a breaking change because custom scope managers are not required to provide these methods.
In the parseForESLint
interface specification, we require parsers to return a ScopeManager
object whose interface doesn't mention isGlobalReturn()
and lists isModule()
as deprecated and not used in ESLint:
eslint/docs/src/extend/scope-manager-interface.md
Lines 43 to 51 in f57eff2
### Deprecated members | |
Those members are defined but not used in ESLint. | |
#### isModule() | |
* **Parameters:** | |
* **Return type:** `boolean` | |
* **Description:** `true` if this program is module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the goal here is just, when the Program node is passed, to return the innermost top-level scope instead of the outermost (global) scope that getScope()
returns, so if we want to avoid analyzing configured language options, perhaps we could check the scopes directly:
const initialScope = currentScope.type === "global" && currentScope.childScopes.length > 0 && currentScope.childScopes[0].block === this.ast
? currentScope.childScopes[0]
: currentScope;
or maybe do something like this:
const initialScope = refNode === this.ast
? this.scopeManager.acquire(refNode, /* inner = */ true)
: this.getScope(refNode);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that's brilliant. I'll update the logic.
There's a merge conflict now. |
Implements `SourceCode#markVariableAsUsed()` while leaving `context.markVariableAsUsed()` alone. Refs #16999
Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
3974092
to
984ff45
Compare
Yup, updating the docs now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [eslint](https://eslint.org) ([source](https://github.com/eslint/eslint)) | devDependencies | minor | [`8.37.0` -> `8.39.0`](https://renovatebot.com/diffs/npm/eslint/8.37.0/8.39.0) | --- ### Release Notes <details> <summary>eslint/eslint</summary> ### [`v8.39.0`](https://github.com/eslint/eslint/releases/tag/v8.39.0) [Compare Source](eslint/eslint@v8.38.0...v8.39.0) #### Features - [`3f7af9f`](eslint/eslint@3f7af9f) feat: Implement `SourceCode#markVariableAsUsed()` ([#​17086](eslint/eslint#17086)) (Nicholas C. Zakas) #### Documentation - [`6987dc5`](eslint/eslint@6987dc5) docs: Fix formatting in Custom Rules docs ([#​17097](eslint/eslint#17097)) (Milos Djermanovic) - [`4ee92e5`](eslint/eslint@4ee92e5) docs: Update README (GitHub Actions Bot) - [`d8e9887`](eslint/eslint@d8e9887) docs: Custom Rules cleanup/expansion ([#​16906](eslint/eslint#16906)) (Ben Perlmutter) - [`1fea279`](eslint/eslint@1fea279) docs: Clarify how to add to tsc agenda ([#​17084](eslint/eslint#17084)) (Nicholas C. Zakas) - [`970ef1c`](eslint/eslint@970ef1c) docs: Update triage board location (Nicholas C. Zakas) - [`6d8bffd`](eslint/eslint@6d8bffd) docs: Update README (GitHub Actions Bot) #### Chores - [`60a6f26`](eslint/eslint@60a6f26) chore: upgrade [@​eslint/js](https://github.com/eslint/js)[@​8](https://github.com/8).39.0 ([#​17102](eslint/eslint#17102)) (Milos Djermanovic) - [`d5ba5c0`](eslint/eslint@d5ba5c0) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (ESLint Jenkins) - [`f57eff2`](eslint/eslint@f57eff2) ci: run tests on Node.js v20 ([#​17093](eslint/eslint#17093)) (Nitin Kumar) - [`9d1b8fc`](eslint/eslint@9d1b8fc) perf: Binary search in token store `utils.search` ([#​17066](eslint/eslint#17066)) (Francesco Trotta) - [`07a4435`](eslint/eslint@07a4435) chore: Add request for minimal repro to bug report ([#​17081](eslint/eslint#17081)) (Nicholas C. Zakas) - [`eac4943`](eslint/eslint@eac4943) refactor: remove unnecessary use of `SourceCode#getAncestors` in rules ([#​17075](eslint/eslint#17075)) (Milos Djermanovic) - [`0a7b60a`](eslint/eslint@0a7b60a) chore: update description of `SourceCode#getDeclaredVariables` ([#​17072](eslint/eslint#17072)) (Milos Djermanovic) - [`6e2df71`](eslint/eslint@6e2df71) chore: remove unnecessary references to the LICENSE file ([#​17071](eslint/eslint#17071)) (Milos Djermanovic) ### [`v8.38.0`](https://github.com/eslint/eslint/releases/tag/v8.38.0) [Compare Source](eslint/eslint@v8.37.0...v8.38.0) #### Features - [`a1d561d`](eslint/eslint@a1d561d) feat: Move getDeclaredVariables and getAncestors to SourceCode ([#​17059](eslint/eslint#17059)) (Nicholas C. Zakas) #### Bug Fixes - [`1c1ece2`](eslint/eslint@1c1ece2) fix: do not report on `RegExp(...args)` in `require-unicode-regexp` ([#​17037](eslint/eslint#17037)) (Francesco Trotta) #### Documentation - [`7162d34`](eslint/eslint@7162d34) docs: Mention new config system is complete ([#​17068](eslint/eslint#17068)) (Nicholas C. Zakas) - [`0fd6bb2`](eslint/eslint@0fd6bb2) docs: Update README (GitHub Actions Bot) - [`c83531c`](eslint/eslint@c83531c) docs: Update/remove external links, eg. point to `eslint-community` ([#​17061](eslint/eslint#17061)) (Pelle Wessman) - [`a3aa6f5`](eslint/eslint@a3aa6f5) docs: Clarify `no-div-regex` rule docs ([#​17051](eslint/eslint#17051)) (Francesco Trotta) - [`b0f11cf`](eslint/eslint@b0f11cf) docs: Update README (GitHub Actions Bot) - [`da8d52a`](eslint/eslint@da8d52a) docs: Update the second object instance for the "no-new" rule ([#​17020](eslint/eslint#17020)) (Ahmadou Waly NDIAYE) - [`518130a`](eslint/eslint@518130a) docs: switch language based on current path ([#​16687](eslint/eslint#16687)) (Percy Ma) - [`24206c4`](eslint/eslint@24206c4) docs: Update README (GitHub Actions Bot) #### Chores - [`59ed060`](eslint/eslint@59ed060) chore: upgrade [@​eslint/js](https://github.com/eslint/js)[@​8](https://github.com/8).38.0 ([#​17069](eslint/eslint#17069)) (Milos Djermanovic) - [`88c0898`](eslint/eslint@88c0898) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (ESLint Jenkins) - [`cf682d2`](eslint/eslint@cf682d2) refactor: simplify new-parens rule schema ([#​17060](eslint/eslint#17060)) (MHO) - [`0dde022`](eslint/eslint@0dde022) ci: bump actions/add-to-project from 0.4.1 to 0.5.0 ([#​17055](eslint/eslint#17055)) (dependabot\[bot]) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4zNS4xIiwidXBkYXRlZEluVmVyIjoiMzUuNTUuMSJ9--> Co-authored-by: cabr2-bot <cabr2.help@gmail.com> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1852 Reviewed-by: Epsilon_02 <epsilon_02@noreply.codeberg.org> Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org> Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[x] Add something to the core
[ ] Other, please explain:
What changes did you make? (Give an overview)
Implements
SourceCode#markVariableAsUsed()
and setscontext.markVariableAsUsed()
to use it.Refs #16999
Is there anything you'd like reviewers to focus on?
I'm not sure of how I implemented this method. I started out by passing in an
Identifier
node because we can use that to get the scope and determine if it's a declared variable. This also seemed like it would be the most developer-friendly.Based on my feedback from @ljharb, I change it to accept a string and optionally a node. I'd like some more feedback on whether this makes sense.