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
  • Loading branch information
yeonjuan committed Sep 21, 2023
1 parent d467e14 commit 22f78d9
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 3 deletions.
25 changes: 25 additions & 0 deletions packages/eslint-plugin/src/rules/no-confusing-void-expression.ts
Expand Up @@ -118,6 +118,9 @@ export default util.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 @@ -160,6 +163,9 @@ export default util.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 @@ -334,5 +340,24 @@ export default util.createRule<Options, MessageId>({

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

function canFix(node: TSESTree.Node): boolean {
const services = util.getParserServices(context);

let targetNode: TSESTree.Node | null = null;

if (node.type === AST_NODE_TYPES.ReturnStatement) {
targetNode = node.argument;
} else if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) {
targetNode = node.body;
}

if (targetNode) {
const type = util.getConstrainedTypeAtLocation(services, targetNode);
return tsutils.isTypeFlagSet(type, ts.TypeFlags.VoidLike);
}

return true;
}
},
});
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 22f78d9

Please sign in to comment.