Skip to content

Commit

Permalink
fix(eslint-plugin): [no-confusing-void-expression] handle unfixable c…
Browse files Browse the repository at this point in the history
…ases (#7674)

* fix(eslint-plugin): [no-confusing-void-expression] handle unfixable cases

* Fix post-merge issues

---------

Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
  • Loading branch information
yeonjuan and JoshuaKGoldberg committed Oct 16, 2023
1 parent d475f88 commit 7e52f27
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
20 changes: 20 additions & 0 deletions packages/eslint-plugin/src/rules/no-confusing-void-expression.ts
Expand Up @@ -127,6 +127,9 @@ export default createRule<Options, MessageId>({
node,
messageId: 'invalidVoidExprArrow',
fix(fixer) {
if (!canFix(arrowFunction)) {
return null;
}
const arrowBody = arrowFunction.body;
const arrowBodyText = sourceCode.getText(arrowBody);
const newArrowBodyText = `{ ${arrowBodyText}; }`;
Expand Down Expand Up @@ -169,6 +172,9 @@ export default createRule<Options, MessageId>({
node,
messageId: 'invalidVoidExprReturnLast',
fix(fixer) {
if (!canFix(returnStmt)) {
return null;
}
const returnValue = returnStmt.argument!;
const returnValueText = sourceCode.getText(returnValue);
let newReturnStmtText = `${returnValueText};`;
Expand Down Expand Up @@ -337,5 +343,19 @@ export default createRule<Options, MessageId>({

return ['(', '[', '`'].includes(startToken.value);
}

function canFix(
node: TSESTree.ReturnStatement | TSESTree.ArrowFunctionExpression,
): boolean {
const services = getParserServices(context);

const targetNode =
node.type === AST_NODE_TYPES.ReturnStatement
? node.argument!
: node.body;

const type = getConstrainedTypeAtLocation(services, targetNode);
return tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike);
}
},
});
Expand Up @@ -199,12 +199,25 @@ function notcool(input: string) {
{
code: 'foo => foo && console.log(foo);',
errors: [{ line: 1, column: 15, messageId: 'invalidVoidExprArrow' }],
output: `foo => { foo && console.log(foo); };`,
},
{
code: '(foo: undefined) => foo && console.log(foo);',
errors: [{ line: 1, column: 28, messageId: 'invalidVoidExprArrow' }],
output: `(foo: undefined) => { foo && console.log(foo); };`,
},
{
code: 'foo => foo || console.log(foo);',
errors: [{ line: 1, column: 15, messageId: 'invalidVoidExprArrow' }],
output: `foo => { foo || console.log(foo); };`,
},
{
code: '(foo: undefined) => foo || console.log(foo);',
errors: [{ line: 1, column: 28, messageId: 'invalidVoidExprArrow' }],
output: `(foo: undefined) => { foo || console.log(foo); };`,
},
{
code: '(foo: void) => foo || console.log(foo);',
errors: [{ line: 1, column: 23, messageId: 'invalidVoidExprArrow' }],
output: `(foo: void) => { foo || console.log(foo); };`,
},
{
code: 'foo => (foo ? console.log(true) : console.log(false));',
Expand Down Expand Up @@ -310,7 +323,72 @@ function notcool(input: string) {
};
`,
},

{
code: `
const f = function () {
let num = 1;
return num ? console.log('foo') : num;
};
`,
errors: [{ line: 4, column: 24, messageId: 'invalidVoidExprReturnLast' }],
},
{
code: `
const f = function () {
let undef = undefined;
return undef ? console.log('foo') : undef;
};
`,
errors: [{ line: 4, column: 26, messageId: 'invalidVoidExprReturnLast' }],
output: `
const f = function () {
let undef = undefined;
undef ? console.log('foo') : undef;
};
`,
},
{
code: `
const f = function () {
let num = 1;
return num || console.log('foo');
};
`,
errors: [{ line: 4, column: 25, messageId: 'invalidVoidExprReturnLast' }],
},
{
code: `
const f = function () {
let bar = void 0;
return bar || console.log('foo');
};
`,
errors: [{ line: 4, column: 25, messageId: 'invalidVoidExprReturnLast' }],
output: `
const f = function () {
let bar = void 0;
bar || console.log('foo');
};
`,
},
{
code: `
let num = 1;
const foo = () => (num ? console.log('foo') : num);
`,
errors: [{ line: 3, column: 34, messageId: 'invalidVoidExprArrow' }],
},
{
code: `
let bar = void 0;
const foo = () => (bar ? console.log('foo') : bar);
`,
errors: [{ line: 3, column: 34, messageId: 'invalidVoidExprArrow' }],
output: `
let bar = void 0;
const foo = () => { bar ? console.log('foo') : bar; };
`,
},
{
options: [{ ignoreVoidOperator: true }],
code: "return console.log('foo');",
Expand Down

0 comments on commit 7e52f27

Please sign in to comment.