eslint-visitor-keys known bugs

npm

13 known bugs in eslint-visitor-keys, with affected versions, fixes and workarounds. Sourced from upstream issue trackers.

13
bugs
Known bugs
SeverityAffectedFixed inTitleStatusSource
mediumany\u2014
`Keyword` tokens output as `Identifier`
Running this small example through astexplorer ```js async function *foo() { // async === Identifier ################ // function === Keyword var a; // var === Keyword let b; // let === Keyword const c = { // const === Keyword get d() {}, // get === Identifier ################ set e(val) {}, // set === Identifier ################ } await f; // await === Identifier ################ yield g; // yield === Keyword typeof x; // typeof === Keyword a in x; // in === Keyword } class H { // class === Keyword static i() {} // static === Keyword } if (true) {} else {} // if === Keyword // else === Keyword try {} catch {} finally {} // try === Keyword // catch === Keyword // finally === Keyword for (;;) {} // for === Keyword do { } while (true); // do === Keyword // while === Keyword for (let x of y) {} // for === Keyword // of === Identifier ################ ``` [repl](https://astexplorer.net/#/gist/64a872691c918f615302c6f6735ff84e/9229e8f142352a7aba92132bc44a22535bb640cb) It looks like there are a few keywords which are incorrectly parsed as identifiers instead of keywords. I found: - `async` - `await` - `get` - `set` - `of`
fixedgithub:428
mediumany\u2014
Question: how come function references on the global scope are not closed
https://github.com/eslint/eslint-scope/blob/dbddf14d5771b21b5da704213e4508c660ca1c64/tests/references.js#L211-L263 I'm working on trying to understand this codebase better. But I can't understand why it works this way: ```js function a() {} a(); ``` To me it seems clear that the reference that's created as part of the call should resolve directly to the function declaration, but it's not - it remains as an unresolved reference that's added to the global scope's `through` list. This would cause the `no-unused-vars` ESLint rule to error on the function declaration, were it not for [this code](https://github.com/eslint/eslint/blob/015edf6467e33c67b904db037a674d71957a6865/lib/linter/linter.js#L172-L194) in the linter. It looks like it works seemingly by chance? ESLint augments the global scope with more variables, and then forcefully resolves any `through` references against the global variable `set`, which includes the function declaration as well as the augmented variables. Is anyone able to explain why this works this way? Or a better question - when closing the global scope, why doesn't it attempt to resolve all `through` references against the variables defined in the global scope?
fixedgithub:665
mediumany\u2014
Should throw on invaid `(a = 1) = t`
This should be invalid. ```text require("espree").parse('(a = 1) = 2', {sourceType: 'module', ecmaVersion: 2019}).body[0].expression Node { type: 'AssignmentExpression', start: 0, end: 11, operator: '=', left: Node { type: 'AssignmentPattern', start: 1, end: 6, left: Node { type: 'Identifier', start: 1, end: 2, name: 'a' }, right: Node { type: 'Literal', start: 5, end: 6, value: 1, raw: '1' } }, right: Node { type: 'Literal', start: 10, end: 11, value: 2, raw: '2' } } ```
fixedgithub:470
mediumany\u2014
Should throw on `async () => await 5 ** 6;`
`espree` parse this as `await (5 ** 6)` ```text require('espree').parse('async () => await 5 ** 6', {ecmaVersion: 2017}).body[0].expression.body Node { type: 'AwaitExpression', start: 12, end: 24, argument: Node { type: 'BinaryExpression', start: 18, end: 24, left: Node { type: 'Literal', start: 18, end: 19, value: 5, raw: '5' }, operator: '**', right: Node { type: 'Literal', start: 23, end: 24, value: 6, raw: '6' } } } ```` In chrome, this is a syntax error ```js async () => await 5 ** 6 VM40:1 Uncaught SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence ``` Babel PR babel/babel#12441
fixedgithub:472
medium7.3.1\u2014
npm v7: peer mocha@">=1.18 <7" from [email protected]
when running `npm install` with npm v7. ```bash ➜ espree git:(main) npm i npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: [email protected] npm ERR! Found: [email protected] npm ERR! node_modules/mocha npm ERR! dev mocha@"^8.3.1" from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer mocha@">=1.18 <7" from [email protected] npm ERR! node_modules/leche npm ERR! dev leche@"^2.3.0" from the root project npm ERR! npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. npm ERR! npm ERR! See /home/weiran/.npm/eresolve-report.txt for a full report. npm ERR! A complete log of this run can be found in: npm ERR! /home/weiran/.npm/_logs/2021-04-13T03_23_03_200Z-debug.log ``` we have to remove leche(like in the eslint repo) - it has been unmaintained.
fixedgithub:480
mediumany\u2014
ChainExpression and others are missing in espree.Syntax
According to #331, the `espree.Syntax` object is supposed to contain all node types supported by Espree. But comparing it with ` espree.VisitorKeys`, the following node types are missing: * `ChainExpression` * `ImportExpression` * `JSXFragment` * `JSXOpeningFragment` * `JSXClosingFragment` * `PrivateIdentifier` * `PropertyDefinition` * `StaticBlock` `ExperimentalRestProperty` and `ExperimentalSpreadProperty` are also missing, but this might be intentional. For sure one could derive a list of node types from the keys of `VisitorKeys`, but what's the purpose of the `Syntax` export then? Shouldn't it be used any longer?
fixedgithub:531
medium9.5.0\u2014
remove sourcemap url
<img width="1440" alt="image" src="https://user-images.githubusercontent.com/41773861/226166008-f3396b2c-c725-4587-af90-123e0174f090.png"> version: [email protected]
fixedgithub:566
mediumany\u2014
Bug: `scope-manager` does not support the `ecmaVersion` option set to "latest."
### Which packages are affected? - [ ] `espree` - [X] `eslint-scope` - [ ] `eslint-visitor-keys` ### Environment Node version: npm version: ESLint version: Operating System: ### What did you do? Tried to set the ecmaVersion option to `lastest` in the `scope-manager`. ### What did you expect to happen? Since we selected the "latest" option, it should recognize the most recent ECMAScript version and support import declarations. ### What actually happened? Got the below error: ![image](https://github.com/user-attachments/assets/76492e59-ca0b-45d1-9aaf-4ca104b81285) ``` ImportDeclaration should appear when the mode is ES6 and in the module context. ``` https://github.com/eslint/js/blob/91d51d3da4273acaf2523a3b6d23a27a733c13cc/packages/eslint-scope/lib/scope-manager.js#L243 The above condition becomes false when the `ecmaVersion` option is set to `latest`. ### Link to Minimal Reproducible Example https://deploy-preview-31--eslint-code-explorer.netlify.app/ ### Participation - [X] I am willing to submit a pull request for this issue. ### Additional comments In [Espree](https://github.com/eslint/js/tree/main/packages/espree), the `ecmaVersion` option can be set to `"latest"` to support the most recent ECMAScript features. https://github.com/eslint/js/blob/91d51d3da4273acaf2523a3b6d23a27a733c13cc/packages/espree/lib/options.js#L50 Should we maintain consistent handling and options for `ecmaVersion` in both `Espree` and `eslint-scope`?
fixedgithub:622
medium10.8.1\u2014
Bug: `eslint-scope` requires `assert`
### Which packages are affected? - [ ] `espree` - [x] `eslint-scope` - [ ] `eslint-visitor-keys` ### Environment Node version: v20.16.0 npm version: 10.8.1 ESLint version: 8.57.0 Operating System: macOS ### What did you do? In Code Explorer, I aimed to clean up the dependencies by removing unused development and runtime dependencies. I identified the dependencies that were not being used in the repository and then removed them. ### What did you expect to happen? Code Explorer should work as expected since I removed only the unused dependencies. ### What actually happened? code explorer scope view was breaking got the below error: ![Image](https://github.com/user-attachments/assets/2ee84ea1-ef13-4493-9e88-52e42f7ef1b1) When I reviewed the scope-manager logic in response to the error, I found that it utilizes `assert`. https://github.com/eslint/js/blob/79c6e93ba93b46186ebfac111c94f44ab3b4ee27/packages/eslint-scope/lib/scope-manager.js#L187 Also `assert` package was intentionally ignored in the config. https://github.com/eslint/js/blob/79c6e93ba93b46186ebfac111c94f44ab3b4ee27/packages/eslint-scope/rollup.config.js#L3 This means the `assert` package was intentionally marked as external and is expected to be present in the environment where the package is used. Do we have a specific reason for marking `assert` as external? There might be cases where `assert` is not available in the environment where the package (scope-manager) is being used. ### Link to Minimal Reproducible Example https://deploy-preview-33--eslint-code-explorer.netlify.app ### Participation - [x] I am willing to submit a pull request for this issue. ### Additional comments _No response_
fixedgithub:625
medium20.13.1\u2014
Bug: Can't install monorepo
### Which packages are affected? - [ ] `espree` - [ ] `eslint-scope` - [x] `eslint-visitor-keys` ### Environment Node version: 20.13.1 npm version: 10.4.0 ESLint version: 9.4.0 Operating System: Windows ### What did you do? Cloned the repository and ran `npm install` ### What did you expect to happen? For the monorepo to install successfully. ### What actually happened? I received this error message: ``` npm ERR! > [email protected] build:types npm ERR! > tsc npm ERR! npm ERR! ../../node_modules/@types/node/stream/web.d.ts(469,56): error TS1005: '?' expected. npm ERR! tsconfig.json(3,13): error TS6046: Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'webworker.iterable', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asyncgenerator', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.bigint', 'es2020.promise', 'es2020.sharedmemory', 'es2020.string', 'es2020.symbol.wellknown', 'es2020.intl', 'es2021.promise', 'es2021.string', 'es2021.weakref', 'es2021.intl', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise', 'esnext.weakref'. ``` ### Link to Minimal Reproducible Example https://github.com/eslint/js ### Participation - [ ] I am willing to submit a pull request for this issue. ### Additional comments _No response_
fixedgithub:630
medium24.1.0\u2014
Bug: Visitor keys for `ExportSpecifier` are not in source code order
### Which packages are affected? - [ ] `espree` - [ ] `eslint-scope` - [x] `eslint-visitor-keys` ### Environment Node version: 24.1.0 npm version: 11.3.0 ESLint version: 9.28.0 Operating System: Mac OS 15.4.1 ### What did you do? As far as I can see, it's not documented anywhere that visitor keys are always in source code order. However, in my opinion it's what a user would naturally expect, and this expectation seems to be confirmed because it's true for every single AST node type... With only one exception: `ExportSpecifier`. ```js export { local as exported }; ``` In this case, `exported` is visited before `local`: https://github.com/eslint/js/blob/b847f35787d4bf2ec68163f45f3e4dc2d209eee8/packages/eslint-visitor-keys/lib/visitor-keys.js#L102-L105 I have opened this issue as a bug report as I *assume* that this deviation from "visit in source code order" rule is an oversight rather than intentional. But there may be some context I am missing. ### What did you expect to happen? `local` to be visited before `exported`. ### What actually happened? `exported` is visited before `local` (more like `ImportSpecifier`). ### Link to Minimal Reproducible Example <skipped> ### Participation - [x] I am willing to submit a pull request for this issue. ### Additional comments _No response_
fixedgithub:655
medium20.18.0\u2014
Bug: New version of `acorn` v8.1.5 breaks build
### Which packages are affected? - [x] `espree` - [ ] `eslint-scope` - [ ] `eslint-visitor-keys` ### Environment Node version: 20.18.0 npm version: 10.9.2 ESLint version: HEAD Operating System: Windows 11 ### What did you do? Hello, Currently the [CI build is failing](https://github.com/eslint/js/actions/runs/15529797360/job/43716117138) due to the newly released [`acorn` v8.15.0](https://github.com/acornjs/acorn/releases/tag/8.15.0), which was published about 24 hours ago. I’ve reviewed the changes between [`v8.14.1...v8.15.0`](https://github.com/acornjs/acorn/compare/8.14.1...8.15.0) and identified the source of the issue. Although this release introduces some ES2026 features, I think the bug is not related to those features. The problem comes from this change: https://github.com/acornjs/acorn/compare/8.14.1...8.15.0#diff-6a29ed00e92d69844ec35883ec62f4893f40687e70bcd87905757aeaa6fe0af5 ![Image](https://github.com/user-attachments/assets/029a7398-3649-4b98-8f4a-32d85a083489) ```diff - if (this.tok.type === tt.num && node.raw.charCodeAt(node.raw.length - 1) === 110) - node.bigint = node.raw.slice(0, -1).replace(/_/g, "") + if (this.tok.type === tt.num && node.raw.charCodeAt(node.raw.length - 1) === 110) + node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, "") ``` To reproduce the issue, you can simply reinstall packages (with the latest acorn) and run: ```sh npm run test -w packages/espree ``` --- You can simply reproduce this bug by running `npm run test -w packages/espree` after reinstalling packages with latest `acorn`. ### What did you expect to happen? Works as before. ### What actually happened? Caused errors. ### Link to Minimal Reproducible Example https://github.com/eslint/js/actions/runs/15529797360/job/43716117138 ### Participation - [x] I am willing to submit a pull request for this issue. ### Additional comments I’m not sure whether this should be fixed in `acorn`, or if it would be better to adjust some test cases or logic in `espree` instead.
fixedgithub:659
medium11.6.2\u2014
Bug: ESLint types are incompatiable with `@types/eslint-scope`
### Which packages are affected? - [ ] `espree` - [x] `eslint-scope` - [ ] `eslint-visitor-keys` ### Environment Node version: 24 npm version: 11.6.2 ESLint version: 9.39.2 Operating System: Mac OS 15.5 ### What did you do? Used the return value of `eslintScope.analyze()` as a parameter of `eslint.Scope.ScopeManager` typed value. ### What did you expect to happen? Types should be identical ### What actually happened? Types are not identical ### Link to Minimal Reproducible Example https://stackblitz.com/edit/node-isht7kjp?file=package.json,src%2Findex.ts ### Participation - [ ] I am willing to submit a pull request for this issue. ### Additional comments Coming from https://github.com/eslint-community/eslint-plugin-eslint-plugin/issues/575, seems like the type changes are actually a breaking change
fixedgithub:719
API access

Get this data programmatically \u2014 free, no authentication.

curl https://depscope.dev/api/bugs/npm/eslint-visitor-keys
eslint-visitor-keys bugs — known issues per version | DepScope | DepScope