From 0bbb03562fd8e94c8cc3b2424ecf9d70d068df55 Mon Sep 17 00:00:00 2001 From: Kemil Beltre Date: Tue, 1 Aug 2023 16:39:12 +0200 Subject: [PATCH 1/6] fix(eslint-plugin): remove explicit rule check for logical negation expressions --- .../src/rules/strict-boolean-expressions.ts | 11 ----------- .../tests/rules/strict-boolean-expressions.test.ts | 14 +------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 6ea73c6e299f..77cce0407660 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -710,17 +710,6 @@ export default util.createRule({ wrap: code => `${code} == null`, }), }); - } else { - // if (nullableObject) - context.report({ - node, - messageId: 'conditionErrorNullableObject', - fix: util.getWrappingFixer({ - sourceCode, - node, - wrap: code => `${code} != null`, - }), - }); } } return; diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index 65878e2d17fe..11ee293e04b1 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -1003,19 +1003,13 @@ if (y) { ...batchedSingleLineTests({ options: [{ allowNullableObject: false }], code: noFormat` - declare const x: object | null; if (x) {} (x?: { a: number }) => !x; - (x: T) => x ? 1 : 0; `, errors: [ - { messageId: 'conditionErrorNullableObject', line: 2, column: 37 }, - { messageId: 'conditionErrorNullableObject', line: 3, column: 33 }, - { messageId: 'conditionErrorNullableObject', line: 4, column: 52 }, + { messageId: 'conditionErrorNullableObject', line: 2, column: 25 }, ], output: ` - declare const x: object | null; if (x != null) {} (x?: { a: number }) => x == null; - (x: T) => (x != null) ? 1 : 0; `, }), @@ -1616,21 +1610,15 @@ if (x) { declare const obj: { x: number } | null; !obj ? 1 : 0 !obj - obj || 0 - obj && 1 || 0 `, errors: [ { messageId: 'conditionErrorNullableObject', line: 3, column: 10 }, { messageId: 'conditionErrorNullableObject', line: 4, column: 10 }, - { messageId: 'conditionErrorNullableObject', line: 5, column: 9 }, - { messageId: 'conditionErrorNullableObject', line: 6, column: 9 }, ], output: ` declare const obj: { x: number } | null; (obj == null) ? 1 : 0 obj == null - ;(obj != null) || 0 - ;(obj != null) && 1 || 0 `, }, ], From 5432e5282e8fae4a318e03237b6d2d628450acdb Mon Sep 17 00:00:00 2001 From: Kemil Beltre Date: Wed, 2 Aug 2023 15:45:00 +0200 Subject: [PATCH 2/6] feat: add null check error without fix options --- .../src/rules/strict-boolean-expressions.ts | 6 ++++++ .../rules/strict-boolean-expressions.test.ts | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 77cce0407660..f720b7dcec4f 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -710,6 +710,12 @@ export default util.createRule({ wrap: code => `${code} == null`, }), }); + } else { + // if (nullableObject) + context.report({ + node, + messageId: 'conditionErrorNullableObject', + }); } } return; diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index 11ee293e04b1..1322d91bdae5 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -1003,14 +1003,19 @@ if (y) { ...batchedSingleLineTests({ options: [{ allowNullableObject: false }], code: noFormat` + declare const x: object | null; if (x) {} (x?: { a: number }) => !x; + (x: T) => x ? 1 : 0; `, errors: [ - { messageId: 'conditionErrorNullableObject', line: 2, column: 25 }, + { messageId: 'conditionErrorNullableObject', line: 2, column: 37 }, + { messageId: 'conditionErrorNullableObject', line: 3, column: 33 }, + { messageId: 'conditionErrorNullableObject', line: 4, column: 52 }, ], output: ` + declare const x: object | null; if (x) {} (x?: { a: number }) => x == null; - `, + (x: T) => x ? 1 : 0; `, }), // nullable string in boolean context @@ -1610,15 +1615,21 @@ if (x) { declare const obj: { x: number } | null; !obj ? 1 : 0 !obj + obj || 0 + obj && 1 || 0 `, errors: [ { messageId: 'conditionErrorNullableObject', line: 3, column: 10 }, { messageId: 'conditionErrorNullableObject', line: 4, column: 10 }, + { messageId: 'conditionErrorNullableObject', line: 5, column: 9 }, + { messageId: 'conditionErrorNullableObject', line: 6, column: 9 }, ], output: ` declare const obj: { x: number } | null; (obj == null) ? 1 : 0 obj == null + obj || 0 + obj && 1 || 0 `, }, ], From 5d3b201854f42eb04aad73cf8219330cc105ca87 Mon Sep 17 00:00:00 2001 From: Kemil Beltre Date: Sun, 6 Aug 2023 01:19:23 +0200 Subject: [PATCH 3/6] refactor: add explicit null check rule suggestion --- .../src/rules/strict-boolean-expressions.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index f720b7dcec4f..c801b4fc91f3 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -715,6 +715,16 @@ export default util.createRule({ context.report({ node, messageId: 'conditionErrorNullableObject', + suggest: [ + { + messageId: 'conditionErrorNullableObject', + fix: util.getWrappingFixer({ + sourceCode, + node, + wrap: code => `${code} != null`, + }), + }, + ], }); } } From e476dcf2b6385bf4e324f3408da79b8ca4adebd0 Mon Sep 17 00:00:00 2001 From: Kemil Beltre Date: Tue, 8 Aug 2023 12:28:41 +0200 Subject: [PATCH 4/6] feat: change suggestion fix message id --- packages/eslint-plugin/src/rules/strict-boolean-expressions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index c801b4fc91f3..5f5fa9852ec2 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -717,7 +717,7 @@ export default util.createRule({ messageId: 'conditionErrorNullableObject', suggest: [ { - messageId: 'conditionErrorNullableObject', + messageId: 'conditionFixCompareNullish', fix: util.getWrappingFixer({ sourceCode, node, From 3b704463da6711a4841939ad9ec9ef02963a2b13 Mon Sep 17 00:00:00 2001 From: Kemil Beltre Date: Tue, 8 Aug 2023 12:30:39 +0200 Subject: [PATCH 5/6] test: add fix compare nullish suggestion --- .../rules/strict-boolean-expressions.test.ts | 60 +++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index 1322d91bdae5..ae62dbb53883 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -1008,9 +1008,29 @@ if (y) { (x: T) => x ? 1 : 0; `, errors: [ - { messageId: 'conditionErrorNullableObject', line: 2, column: 37 }, + { + messageId: 'conditionErrorNullableObject', + line: 2, + column: 37, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: 'declare const x: object | null; if (x != null) {}', + }, + ], + }, { messageId: 'conditionErrorNullableObject', line: 3, column: 33 }, - { messageId: 'conditionErrorNullableObject', line: 4, column: 52 }, + { + messageId: 'conditionErrorNullableObject', + line: 4, + column: 52, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: ` (x: T) => (x != null) ? 1 : 0;`, + }, + ], + }, ], output: ` declare const x: object | null; if (x) {} @@ -1621,8 +1641,40 @@ if (x) { errors: [ { messageId: 'conditionErrorNullableObject', line: 3, column: 10 }, { messageId: 'conditionErrorNullableObject', line: 4, column: 10 }, - { messageId: 'conditionErrorNullableObject', line: 5, column: 9 }, - { messageId: 'conditionErrorNullableObject', line: 6, column: 9 }, + { + messageId: 'conditionErrorNullableObject', + line: 5, + column: 9, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: ` + declare const obj: { x: number } | null; + !obj ? 1 : 0 + !obj + ;(obj != null) || 0 + obj && 1 || 0 + `, + }, + ], + }, + { + messageId: 'conditionErrorNullableObject', + line: 6, + column: 9, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: ` + declare const obj: { x: number } | null; + !obj ? 1 : 0 + !obj + obj || 0 + ;(obj != null) && 1 || 0 + `, + }, + ], + }, ], output: ` declare const obj: { x: number } | null; From 989ba1c94a5459fc3bed1f2c3bdb3619ea7483e6 Mon Sep 17 00:00:00 2001 From: Kemil Beltre Date: Tue, 8 Aug 2023 12:56:33 +0200 Subject: [PATCH 6/6] refactor: move !nullableObject to suggestions --- .../src/rules/strict-boolean-expressions.ts | 17 ++++-- .../rules/strict-boolean-expressions.test.ts | 59 ++++++++++++++----- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 5f5fa9852ec2..2eed8cdc1e82 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -703,12 +703,17 @@ export default util.createRule({ context.report({ node, messageId: 'conditionErrorNullableObject', - fix: util.getWrappingFixer({ - sourceCode, - node: node.parent, - innerNode: node, - wrap: code => `${code} == null`, - }), + suggest: [ + { + messageId: 'conditionFixCompareNullish', + fix: util.getWrappingFixer({ + sourceCode, + node: node.parent, + innerNode: node, + wrap: code => `${code} == null`, + }), + }, + ], }); } else { // if (nullableObject) diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index ae62dbb53883..9a285b70d186 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -1019,7 +1019,17 @@ if (y) { }, ], }, - { messageId: 'conditionErrorNullableObject', line: 3, column: 33 }, + { + messageId: 'conditionErrorNullableObject', + line: 3, + column: 33, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: ` (x?: { a: number }) => x == null;`, + }, + ], + }, { messageId: 'conditionErrorNullableObject', line: 4, @@ -1032,10 +1042,6 @@ if (y) { ], }, ], - output: ` - declare const x: object | null; if (x) {} - (x?: { a: number }) => x == null; - (x: T) => x ? 1 : 0; `, }), // nullable string in boolean context @@ -1639,8 +1645,40 @@ if (x) { obj && 1 || 0 `, errors: [ - { messageId: 'conditionErrorNullableObject', line: 3, column: 10 }, - { messageId: 'conditionErrorNullableObject', line: 4, column: 10 }, + { + messageId: 'conditionErrorNullableObject', + line: 3, + column: 10, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: ` + declare const obj: { x: number } | null; + (obj == null) ? 1 : 0 + !obj + obj || 0 + obj && 1 || 0 + `, + }, + ], + }, + { + messageId: 'conditionErrorNullableObject', + line: 4, + column: 10, + suggestions: [ + { + messageId: 'conditionFixCompareNullish', + output: ` + declare const obj: { x: number } | null; + !obj ? 1 : 0 + obj == null + obj || 0 + obj && 1 || 0 + `, + }, + ], + }, { messageId: 'conditionErrorNullableObject', line: 5, @@ -1676,13 +1714,6 @@ if (x) { ], }, ], - output: ` - declare const obj: { x: number } | null; - (obj == null) ? 1 : 0 - obj == null - obj || 0 - obj && 1 || 0 - `, }, ], });