Skip to content

Commit

Permalink
no-useless-undefined: Turn parameter with undefined default value…
Browse files Browse the repository at this point in the history
… into optional parameter (#2138)
  • Loading branch information
fisker committed May 18, 2023
1 parent 7b473aa commit 4aa7d60
Show file tree
Hide file tree
Showing 4 changed files with 313 additions and 2 deletions.
24 changes: 22 additions & 2 deletions rules/no-useless-undefined.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const {isCommaToken} = require('@eslint-community/eslint-utils');
const {replaceNodeOrTokenAndSpacesBefore} = require('./fix/index.js');
const {isUndefined} = require('./ast/index.js');
const {isUndefined, isFunction} = require('./ast/index.js');

const messageId = 'no-useless-undefined';
const messages = {
Expand Down Expand Up @@ -80,6 +80,9 @@ const isFunctionBindCall = node =>
&& node.callee.property.type === 'Identifier'
&& node.callee.property.name === 'bind';

const isTypeScriptFile = context =>
/\.(?:ts|mts|cts|tsx)$/i.test(context.getPhysicalFilename());

/** @param {import('eslint').Rule.RuleContext} context */
const create = context => {
const {sourceCode} = context;
Expand Down Expand Up @@ -179,7 +182,24 @@ const create = context => {
) {
return getProblem(
node,
fixer => fixer.removeRange([node.parent.left.range[1], node.range[1]]),
function * (fixer) {
const assignmentPattern = node.parent;
const {left} = assignmentPattern;

yield fixer.removeRange([left.range[1], node.range[1]]);
if (
(left.typeAnnotation || isTypeScriptFile(context))
&& !left.optional
&& isFunction(assignmentPattern.parent)
&& assignmentPattern.parent.params.includes(assignmentPattern)
) {
yield (
left.typeAnnotation
? fixer.insertTextBefore(left.typeAnnotation, '?')
: fixer.insertTextAfter(left, '?')
);
}
},
/* CheckFunctionReturnType */ true,
);
}
Expand Down
31 changes: 31 additions & 0 deletions test/no-useless-undefined.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,34 @@ test.snapshot({
`,
],
});

test.snapshot({
testerOptions: {
parser: parsers.typescript,
},
valid: [],
invalid: [
'function f(foo: Type = undefined) {}',
'function f(foo?: Type = undefined) {}',
'const f = function(foo: Type = undefined) {}',
'const f = (foo: Type = undefined) => {}',
'const f = {method(foo: Type = undefined){}}',
'const f = class {method(foo: Type = undefined){}}',
'function f(foo = undefined) {}',
...[
undefined,
'foo.js',
'foo.ts',
'foo.MTs',
'foo.cts',
'foo.tsx',
].map(filename => ({
code: 'function f(foo = undefined) {}',
filename,
})),
{
code: 'function a({foo} = undefined) {}',
filename: 'foo.ts',
},
],
});
260 changes: 260 additions & 0 deletions test/snapshots/no-useless-undefined.mjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,263 @@ Generated by [AVA](https://avajs.dev).
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
4 | </script>␊
`

## Invalid #1
1 | function f(foo: Type = undefined) {}

> Output
`␊
1 | function f(foo?: Type) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo: Type = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #2
1 | function f(foo?: Type = undefined) {}

> Output
`␊
1 | function f(foo?: Type) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo?: Type = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #3
1 | const f = function(foo: Type = undefined) {}

> Output
`␊
1 | const f = function(foo?: Type) {}␊
`

> Error 1/1
`␊
> 1 | const f = function(foo: Type = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #4
1 | const f = (foo: Type = undefined) => {}

> Output
`␊
1 | const f = (foo?: Type) => {}␊
`

> Error 1/1
`␊
> 1 | const f = (foo: Type = undefined) => {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #5
1 | const f = {method(foo: Type = undefined){}}

> Output
`␊
1 | const f = {method(foo?: Type){}}␊
`

> Error 1/1
`␊
> 1 | const f = {method(foo: Type = undefined){}}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #6
1 | const f = class {method(foo: Type = undefined){}}

> Output
`␊
1 | const f = class {method(foo?: Type){}}␊
`

> Error 1/1
`␊
> 1 | const f = class {method(foo: Type = undefined){}}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #7
1 | function f(foo = undefined) {}

> Output
`␊
1 | function f(foo) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #8
1 | function f(foo = undefined) {}

> Output
`␊
1 | function f(foo) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #9
1 | function f(foo = undefined) {}

> Filename
`␊
foo.js␊
`

> Output
`␊
1 | function f(foo) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #10
1 | function f(foo = undefined) {}

> Filename
`␊
foo.ts␊
`

> Output
`␊
1 | function f(foo?) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #11
1 | function f(foo = undefined) {}

> Filename
`␊
foo.MTs␊
`

> Output
`␊
1 | function f(foo?) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #12
1 | function f(foo = undefined) {}

> Filename
`␊
foo.cts␊
`

> Output
`␊
1 | function f(foo?) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #13
1 | function f(foo = undefined) {}

> Filename
`␊
foo.tsx␊
`

> Output
`␊
1 | function f(foo?) {}␊
`

> Error 1/1
`␊
> 1 | function f(foo = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`

## Invalid #14
1 | function a({foo} = undefined) {}

> Filename
`␊
foo.ts␊
`

> Output
`␊
1 | function a({foo}?) {}␊
`

> Error 1/1
`␊
> 1 | function a({foo} = undefined) {}␊
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
`
Binary file modified test/snapshots/no-useless-undefined.mjs.snap
Binary file not shown.

0 comments on commit 4aa7d60

Please sign in to comment.