Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import globals from 'globals';
import xo from 'eslint-config-xo';
import eslintPlugin from 'eslint-plugin-eslint-plugin';
import jsdoc from 'eslint-plugin-jsdoc';
import nodeStyleTextConfig from 'node-style-text/eslint-config';
import internalRules from './scripts/internal-rules/index.js';
import unicorn from './index.js';

const config = [
...xo,
unicorn.configs.recommended,
nodeStyleTextConfig,
internalRules,
{
languageOptions: {
Expand Down
34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,58 +58,58 @@
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
"@eslint-community/eslint-utils": "^4.9.0",
"@eslint/plugin-kit": "^0.3.5",
"@eslint/plugin-kit": "^0.4.0",
"change-case": "^5.4.4",
"ci-info": "^4.3.0",
"ci-info": "^4.3.1",
"clean-regexp": "^1.0.0",
"core-js-compat": "^3.45.1",
"core-js-compat": "^3.46.0",
"esquery": "^1.6.0",
"find-up-simple": "^1.0.1",
"globals": "^16.3.0",
"globals": "^16.4.0",
"indent-string": "^5.0.0",
"is-builtin-module": "^5.0.0",
"jsesc": "^3.1.0",
"pluralize": "^8.0.0",
"regexp-tree": "^0.1.27",
"regjsparser": "^0.12.0",
"semver": "^7.7.2",
"strip-indent": "^4.0.0"
"regjsparser": "^0.13.0",
"semver": "^7.7.3",
"strip-indent": "^4.1.1"
},
"devDependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/core": "^7.28.4",
"@babel/eslint-parser": "^7.28.4",
"@eslint/eslintrc": "^3.3.1",
"@lubien/fixture-beta-package": "^1.0.0-beta.1",
"@typescript-eslint/parser": "^8.43.0",
"@typescript-eslint/parser": "^8.46.1",
"ava": "^6.4.1",
"c8": "^10.1.3",
"enquirer": "^2.4.1",
"eslint": "^9.35.0",
"eslint": "^9.37.0",
"eslint-ava-rule-tester": "^5.0.1",
"eslint-config-xo": "^0.49.0",
"eslint-doc-generator": "^2.2.2",
"eslint-doc-generator": "^2.3.0",
"eslint-plugin-eslint-plugin": "^7.0.0",
"eslint-plugin-jsdoc": "^55.0.3",
"eslint-plugin-jsdoc": "^61.1.2",
"eslint-remote-tester": "^4.0.3",
"eslint-remote-tester-repositories": "^2.0.2",
"espree": "^10.4.0",
"listr2": "^9.0.3",
"listr2": "^9.0.4",
"lodash-es": "^4.17.21",
"markdownlint-cli": "^0.45.0",
"nano-spawn": "^1.0.3",
"node-style-text": "^1.0.0",
"nano-spawn": "^2.0.0",
"node-style-text": "^2.1.2",
"npm-package-json-lint": "^9.0.0",
"npm-run-all2": "^8.0.4",
"open-editor": "^5.1.0",
"outdent": "^0.8.0",
"pretty-ms": "^9.2.0",
"typescript": "^5.9.2",
"pretty-ms": "^9.3.0",
"typescript": "^5.9.3",
"vue-eslint-parser": "^10.2.0",
"yaml": "^2.8.1"
},
"peerDependencies": {
"eslint": ">=9.35.0"
"eslint": ">=9.37.0"
},
"ava": {
"files": [
Expand Down
9 changes: 5 additions & 4 deletions rules/no-useless-undefined.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {isCommaToken} from '@eslint-community/eslint-utils';
import {replaceNodeOrTokenAndSpacesBefore} from './fix/index.js';
import {isUndefined, isFunction} from './ast/index.js';
import {getParenthesizedRange} from './utils/index.js';

const messageId = 'no-useless-undefined';
const messages = {
Expand Down Expand Up @@ -257,16 +258,16 @@ const create = context => {
end: sourceCode.getLoc(lastUndefined).end,
},
fix(fixer) {
let [start] = sourceCode.getRange(firstUndefined);
let [, end] = sourceCode.getRange(lastUndefined);
let [start] = getParenthesizedRange(firstUndefined, sourceCode);
let [, end] = getParenthesizedRange(lastUndefined, sourceCode);

const previousArgument = argumentNodes[argumentNodes.length - undefinedArguments.length - 1];

if (previousArgument) {
[, start] = sourceCode.getRange(previousArgument);
[, start] = getParenthesizedRange(previousArgument, sourceCode);
} else {
// If all arguments removed, and there is trailing comma, we need remove it.
const tokenAfter = sourceCode.getTokenAfter(lastUndefined);
const tokenAfter = sourceCode.getTokenBefore(sourceCode.getLastToken(node));
if (isCommaToken(tokenAfter)) {
[, end] = sourceCode.getRange(tokenAfter);
}
Expand Down
31 changes: 17 additions & 14 deletions test/integration/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,27 @@ export default [
],
},
],
{
repository: 'https://github.com/gatsbyjs/gatsby',
ignore: [
// These files use `flow`
'**/*.js',
'packages/gatsby-cli/src/reporter/__tests__',
],
},
[
{
repository: 'https://github.com/gatsbyjs/gatsby',
ignore: [
// These files use `flow`
'**/*.js',
'packages/gatsby-cli/src/reporter/__tests__',
],
},
{
repository: 'https://github.com/webpack/webpack',
ignore: ['test/**/*'],
},
],
{
repository: 'https://github.com/vercel/next.js',
ignore: [
'examples/**',

// These files use `>` in jsx
'test/integration/**',

// Contains Flow syntax
'test/e2e/babel/fixture/**',
'test/**',
'**/tests/**',
'**/compiled/**',
],
},
// #903
Expand Down
7 changes: 6 additions & 1 deletion test/integration/run-eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ async function runEslint(project) {
],
fix: true,
errorOnUnmatchedPattern: false,
/*
TODO: Try to figure out how to make it work, currently it throws error
"The option "overrideConfig" cannot be cloned. When concurrency is enabled, all options must be cloneable values (JSON values). Remove uncloneable options or use an options module."
*/
// concurrency: 'auto',
});

const startTime = process.hrtime.bigint();
Expand All @@ -145,7 +150,7 @@ async function runEslint(project) {
const fixableWarningCount = sum(results, 'fixableWarningCount');
console.log();
console.log(outdent`
${styleText.green.bold.underline(`[${project.name}]`)} ${results.length} files linted:
${styleText.green.bold.underline`[${project.name}]`} ${results.length} files linted:
- error: ${styleText.gray(String(errorCount))}
- warning: ${styleText.gray(String(warningCount))}
- fixable error: ${styleText.gray(String(fixableErrorCount))}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function printEslintError(error) {

console.log();
console.error(
styleText.red.bold.underline(`[${project.name}]`),
styleText.red.bold.underline`[${project.name}]`,
message,
);

Expand Down
10 changes: 10 additions & 0 deletions test/no-useless-undefined.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,16 @@ test.snapshot({
'foo.bind?.(bar, undefined)',
'foo[bind](bar, undefined)',
'foo.notBind(bar, undefined)',
// https://github.com/webpack/webpack/blob/0f84d1e3bf69915dc060f23ced9dfa468a884a42/lib/wasm-sync/WasmFinalizeExportsPlugin.js#L49
outdent`
const referencedExports =
compilation.getDependencyReferencedExports(
/** @type {Dependency} */ (connection.dependency),
undefined
);
`,
'foo( ((a)), ((undefined)), ((undefined)), )',
'foo( ((undefined)), ((undefined)), )',
],
});

Expand Down
74 changes: 74 additions & 0 deletions test/snapshots/no-useless-undefined.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,80 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## invalid(13): const referencedExports = compilation.getDependencyReferencedExports( /** @type {Dependency} */ (connection.dependency), undefined );

> Input

`␊
1 | const referencedExports =␊
2 | compilation.getDependencyReferencedExports(␊
3 | /** @type {Dependency} */ (connection.dependency),␊
4 | undefined␊
5 | );␊
`

> Output

`␊
1 | const referencedExports =␊
2 | compilation.getDependencyReferencedExports(␊
3 | /** @type {Dependency} */ (connection.dependency)␊
4 | );␊
`

> Error 1/1

`␊
1 | const referencedExports =␊
2 | compilation.getDependencyReferencedExports(␊
3 | /** @type {Dependency} */ (connection.dependency),␊
> 4 | undefined␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
5 | );␊
`

## invalid(14): foo( ((a)), ((undefined)), ((undefined)), )

> Input

`␊
1 | foo( ((a)), ((undefined)), ((undefined)), )␊
`

> Output

`␊
1 | foo( ((a)), )␊
`

> Error 1/1

`␊
> 1 | foo( ((a)), ((undefined)), ((undefined)), )␊
| ^^^^^^^^^^^^^^^^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## invalid(15): foo( ((undefined)), ((undefined)), )

> Input

`␊
1 | foo( ((undefined)), ((undefined)), )␊
`

> Output

`␊
1 | foo( )␊
`

> Error 1/1

`␊
> 1 | foo( ((undefined)), ((undefined)), )␊
| ^^^^^^^^^^^^^^^^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## invalid(1): <script> import {nextTick} from 'vue'; const foo = nextTick(undefined); </script>

> Input
Expand Down
Binary file modified test/snapshots/no-useless-undefined.js.snap
Binary file not shown.
Loading