From a05601f98f7432580136df291a90bfef89635165 Mon Sep 17 00:00:00 2001 From: Melanie Calame Date: Tue, 23 May 2023 08:18:06 +0200 Subject: [PATCH 1/9] Complete sentence documenting turning on parserOptions.project --- docs/linting/Typed_Linting.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/linting/Typed_Linting.mdx b/docs/linting/Typed_Linting.mdx index 20d694074f0f..85caefa0964f 100644 --- a/docs/linting/Typed_Linting.mdx +++ b/docs/linting/Typed_Linting.mdx @@ -47,7 +47,7 @@ You may see new rules reporting errors based on type information! The `parserOptions.project` option can be turned on with either: - `true`: to always use `tsconfig.json`s nearest to source files -- `string | string[]`: any number of glob paths to match TSConfig files relative to the +- `string | string[]`: any number of glob paths to match TSConfig files relative to `parserOptions.tsconfigRootDir`, or the CWD if that is not provided For example, if you use a specific `tsconfig.eslint.json` for linting, you'd specify: From 1533eada1c94a350276dd7f458c20b85ed25d26b Mon Sep 17 00:00:00 2001 From: Melanie Calame Date: Tue, 23 May 2023 17:32:03 +0200 Subject: [PATCH 2/9] fix: replace auto-fix with suggestion --- .../src/rules/class-literal-property-style.ts | 69 ++++++++++++------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index ed49b144e478..a98153196b11 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -4,7 +4,11 @@ import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import * as util from '../util'; type Options = ['fields' | 'getters']; -type MessageIds = 'preferFieldStyle' | 'preferGetterStyle'; +type MessageIds = + | 'preferFieldStyle' + | 'preferFieldStyleSuggestion' + | 'preferGetterStyle' + | 'preferGetterStyleSuggestion'; interface NodeWithModifiers { accessibility?: TSESTree.Accessibility; @@ -45,10 +49,13 @@ export default util.createRule({ 'Enforce that literals on classes are exposed in a consistent style', recommended: 'strict', }, - fixable: 'code', + hasSuggestions: true, messages: { preferFieldStyle: 'Literals should be exposed using readonly fields.', + preferFieldStyleSuggestion: + 'Try replacing the literals with readonly fields.', preferGetterStyle: 'Literals should be exposed using getters.', + preferGetterStyleSuggestion: 'Try replacing the literals with getters.', }, schema: [{ enum: ['fields', 'getters'] }], }, @@ -80,18 +87,23 @@ export default util.createRule({ context.report({ node: node.key, messageId: 'preferFieldStyle', - fix(fixer) { - const sourceCode = context.getSourceCode(); - const name = sourceCode.getText(node.key); - - let text = ''; - - text += printNodeModifiers(node, 'readonly'); - text += node.computed ? `[${name}]` : name; - text += ` = ${sourceCode.getText(argument)};`; - - return fixer.replaceText(node, text); - }, + suggest: [ + { + messageId: 'preferFieldStyleSuggestion', + fix(fixer) { + const sourceCode = context.getSourceCode(); + const name = sourceCode.getText(node.key); + + let text = ''; + + text += printNodeModifiers(node, 'readonly'); + text += node.computed ? `[${name}]` : name; + text += ` = ${sourceCode.getText(argument)};`; + + return fixer.replaceText(node, text); + }, + }, + ], }); }, }), @@ -110,18 +122,23 @@ export default util.createRule({ context.report({ node: node.key, messageId: 'preferGetterStyle', - fix(fixer) { - const sourceCode = context.getSourceCode(); - const name = sourceCode.getText(node.key); - - let text = ''; - - text += printNodeModifiers(node, 'get'); - text += node.computed ? `[${name}]` : name; - text += `() { return ${sourceCode.getText(value)}; }`; - - return fixer.replaceText(node, text); - }, + suggest: [ + { + messageId: 'preferGetterStyleSuggestion', + fix(fixer) { + const sourceCode = context.getSourceCode(); + const name = sourceCode.getText(node.key); + + let text = ''; + + text += printNodeModifiers(node, 'get'); + text += node.computed ? `[${name}]` : name; + text += `() { return ${sourceCode.getText(value)}; }`; + + return fixer.replaceText(node, text); + }, + }, + ], }); }, }), From 421e29bb2610b2cd6f4a5665fad3291c53595432 Mon Sep 17 00:00:00 2001 From: Melanie Calame Date: Tue, 23 May 2023 17:32:44 +0200 Subject: [PATCH 3/9] test: adapt tests to expect suggestion rather than output from auto-fix --- .../class-literal-property-style.test.ts | 244 ++++++++++++------ 1 file changed, 162 insertions(+), 82 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts b/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts index af0aa203df7d..a0715bc24d2f 100644 --- a/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts +++ b/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts @@ -185,11 +185,6 @@ class Mx { get p1() { return 'hello world'; } -} - `, - output: ` -class Mx { - readonly p1 = 'hello world'; } `, errors: [ @@ -197,6 +192,16 @@ class Mx { messageId: 'preferFieldStyle', column: 7, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + readonly p1 = 'hello world'; +} + `, + }, + ], }, ], }, @@ -206,11 +211,6 @@ class Mx { get p1() { return \`hello world\`; } -} - `, - output: ` -class Mx { - readonly p1 = \`hello world\`; } `, errors: [ @@ -218,6 +218,16 @@ class Mx { messageId: 'preferFieldStyle', column: 7, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + readonly p1 = \`hello world\`; +} + `, + }, + ], }, ], }, @@ -227,11 +237,6 @@ class Mx { static get p1() { return 'hello world'; } -} - `, - output: ` -class Mx { - static readonly p1 = 'hello world'; } `, errors: [ @@ -239,6 +244,16 @@ class Mx { messageId: 'preferFieldStyle', column: 14, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + static readonly p1 = 'hello world'; +} + `, + }, + ], }, ], }, @@ -248,11 +263,6 @@ class Mx { public static get foo() { return 1; } -} - `, - output: ` -class Mx { - public static readonly foo = 1; } `, errors: [ @@ -260,6 +270,16 @@ class Mx { messageId: 'preferFieldStyle', column: 21, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + public static readonly foo = 1; +} + `, + }, + ], }, ], }, @@ -269,11 +289,6 @@ class Mx { public get [myValue]() { return 'a literal value'; } -} - `, - output: ` -class Mx { - public readonly [myValue] = 'a literal value'; } `, errors: [ @@ -281,6 +296,16 @@ class Mx { messageId: 'preferFieldStyle', column: 15, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + public readonly [myValue] = 'a literal value'; +} + `, + }, + ], }, ], }, @@ -290,11 +315,6 @@ class Mx { public get [myValue]() { return 12345n; } -} - `, - output: ` -class Mx { - public readonly [myValue] = 12345n; } `, errors: [ @@ -302,6 +322,16 @@ class Mx { messageId: 'preferFieldStyle', column: 15, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + public readonly [myValue] = 12345n; +} + `, + }, + ], }, ], }, @@ -309,11 +339,6 @@ class Mx { code: ` class Mx { public readonly [myValue] = 'a literal value'; -} - `, - output: ` -class Mx { - public get [myValue]() { return 'a literal value'; } } `, errors: [ @@ -321,6 +346,16 @@ class Mx { messageId: 'preferGetterStyle', column: 20, line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` +class Mx { + public get [myValue]() { return 'a literal value'; } +} + `, + }, + ], }, ], options: ['getters'], @@ -329,11 +364,6 @@ class Mx { code: ` class Mx { readonly p1 = 'hello world'; -} - `, - output: ` -class Mx { - get p1() { return 'hello world'; } } `, errors: [ @@ -341,6 +371,16 @@ class Mx { messageId: 'preferGetterStyle', column: 12, line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` +class Mx { + get p1() { return 'hello world'; } +} + `, + }, + ], }, ], options: ['getters'], @@ -349,11 +389,6 @@ class Mx { code: ` class Mx { readonly p1 = \`hello world\`; -} - `, - output: ` -class Mx { - get p1() { return \`hello world\`; } } `, errors: [ @@ -361,6 +396,16 @@ class Mx { messageId: 'preferGetterStyle', column: 12, line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` +class Mx { + get p1() { return \`hello world\`; } +} + `, + }, + ], }, ], options: ['getters'], @@ -369,11 +414,6 @@ class Mx { code: ` class Mx { static readonly p1 = 'hello world'; -} - `, - output: ` -class Mx { - static get p1() { return 'hello world'; } } `, errors: [ @@ -381,6 +421,16 @@ class Mx { messageId: 'preferGetterStyle', column: 19, line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` +class Mx { + static get p1() { return 'hello world'; } +} + `, + }, + ], }, ], options: ['getters'], @@ -391,11 +441,6 @@ class Mx { protected get p1() { return 'hello world'; } -} - `, - output: ` -class Mx { - protected readonly p1 = 'hello world'; } `, errors: [ @@ -403,6 +448,16 @@ class Mx { messageId: 'preferFieldStyle', column: 17, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + protected readonly p1 = 'hello world'; +} + `, + }, + ], }, ], options: ['fields'], @@ -411,11 +466,6 @@ class Mx { code: ` class Mx { protected readonly p1 = 'hello world'; -} - `, - output: ` -class Mx { - protected get p1() { return 'hello world'; } } `, errors: [ @@ -423,6 +473,16 @@ class Mx { messageId: 'preferGetterStyle', column: 22, line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` +class Mx { + protected get p1() { return 'hello world'; } +} + `, + }, + ], }, ], options: ['getters'], @@ -433,11 +493,6 @@ class Mx { public static get p1() { return 'hello world'; } -} - `, - output: ` -class Mx { - public static readonly p1 = 'hello world'; } `, errors: [ @@ -445,6 +500,16 @@ class Mx { messageId: 'preferFieldStyle', column: 21, line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` +class Mx { + public static readonly p1 = 'hello world'; +} + `, + }, + ], }, ], }, @@ -452,11 +517,6 @@ class Mx { code: ` class Mx { public static readonly p1 = 'hello world'; -} - `, - output: ` -class Mx { - public static get p1() { return 'hello world'; } } `, errors: [ @@ -464,6 +524,16 @@ class Mx { messageId: 'preferGetterStyle', column: 26, line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` +class Mx { + public static get p1() { return 'hello world'; } +} + `, + }, + ], }, ], options: ['getters'], @@ -483,7 +553,15 @@ class Mx { } } `, - output: ` + errors: [ + { + messageId: 'preferFieldStyle', + column: 14, + line: 3, + suggestions: [ + { + messageId: 'preferFieldStyleSuggestion', + output: ` class Mx { public readonly myValue = gql\` { @@ -495,11 +573,8 @@ class Mx { \`; } `, - errors: [ - { - messageId: 'preferFieldStyle', - column: 14, - line: 3, + }, + ], }, ], }, @@ -516,7 +591,15 @@ class Mx { \`; } `, - output: ` + errors: [ + { + messageId: 'preferGetterStyle', + column: 19, + line: 3, + suggestions: [ + { + messageId: 'preferGetterStyleSuggestion', + output: ` class Mx { public get myValue() { return gql\` { @@ -528,11 +611,8 @@ class Mx { \`; } } `, - errors: [ - { - messageId: 'preferGetterStyle', - column: 19, - line: 3, + }, + ], }, ], options: ['getters'], From b66f06eabc9d3d08a4506cf7138f5f1b2fc44bf5 Mon Sep 17 00:00:00 2001 From: Melanie Calame Date: Tue, 23 May 2023 20:29:42 +0200 Subject: [PATCH 4/9] fix: add return type --- .../eslint-plugin/src/rules/class-literal-property-style.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index a98153196b11..803b662100c1 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -1,4 +1,4 @@ -import type { TSESTree } from '@typescript-eslint/utils'; +import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import * as util from '../util'; @@ -90,7 +90,7 @@ export default util.createRule({ suggest: [ { messageId: 'preferFieldStyleSuggestion', - fix(fixer) { + fix(fixer): TSESLint.RuleFix { const sourceCode = context.getSourceCode(); const name = sourceCode.getText(node.key); @@ -125,7 +125,7 @@ export default util.createRule({ suggest: [ { messageId: 'preferGetterStyleSuggestion', - fix(fixer) { + fix(fixer): TSESLint.RuleFix { const sourceCode = context.getSourceCode(); const name = sourceCode.getText(node.key); From 1d39475fdd366c5bea33b4f1034cd9fc58251151 Mon Sep 17 00:00:00 2001 From: Melanie Calame Date: Tue, 23 May 2023 21:09:16 +0200 Subject: [PATCH 5/9] Revert "Complete sentence documenting turning on parserOptions.project" This reverts commit a05601f98f7432580136df291a90bfef89635165. --- docs/linting/Typed_Linting.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/linting/Typed_Linting.mdx b/docs/linting/Typed_Linting.mdx index 85caefa0964f..20d694074f0f 100644 --- a/docs/linting/Typed_Linting.mdx +++ b/docs/linting/Typed_Linting.mdx @@ -47,7 +47,7 @@ You may see new rules reporting errors based on type information! The `parserOptions.project` option can be turned on with either: - `true`: to always use `tsconfig.json`s nearest to source files -- `string | string[]`: any number of glob paths to match TSConfig files relative to `parserOptions.tsconfigRootDir`, or the CWD if that is not provided +- `string | string[]`: any number of glob paths to match TSConfig files relative to the For example, if you use a specific `tsconfig.eslint.json` for linting, you'd specify: From b46a10ef884f1277bf2e55c18b766760c6cd4ec8 Mon Sep 17 00:00:00 2001 From: Melandra Date: Sun, 9 Jul 2023 12:25:48 +0200 Subject: [PATCH 6/9] Replace text with suggestion --- .../eslint-plugin/src/rules/class-literal-property-style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index 803b662100c1..0922fda81175 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -55,7 +55,7 @@ export default util.createRule({ preferFieldStyleSuggestion: 'Try replacing the literals with readonly fields.', preferGetterStyle: 'Literals should be exposed using getters.', - preferGetterStyleSuggestion: 'Try replacing the literals with getters.', + preferGetterStyleSuggestion: 'Replace the literals with readonly fields.', }, schema: [{ enum: ['fields', 'getters'] }], }, From fe73d6d21734700a0f124b1741cf2b01ded3edd8 Mon Sep 17 00:00:00 2001 From: Melandra Date: Sun, 9 Jul 2023 12:27:02 +0200 Subject: [PATCH 7/9] Replace both suggestion messages --- .../eslint-plugin/src/rules/class-literal-property-style.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index 0922fda81175..33ee298386e7 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -53,9 +53,9 @@ export default util.createRule({ messages: { preferFieldStyle: 'Literals should be exposed using readonly fields.', preferFieldStyleSuggestion: - 'Try replacing the literals with readonly fields.', + 'Replace the literals with readonly fields.', preferGetterStyle: 'Literals should be exposed using getters.', - preferGetterStyleSuggestion: 'Replace the literals with readonly fields.', + preferGetterStyleSuggestion: 'Replace the literals with getters.', }, schema: [{ enum: ['fields', 'getters'] }], }, From ba8be5b9db5e69f3c6ed995b6f58b2319519f343 Mon Sep 17 00:00:00 2001 From: Melandra Date: Sun, 9 Jul 2023 12:50:09 +0200 Subject: [PATCH 8/9] Formatting --- .../eslint-plugin/src/rules/class-literal-property-style.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index 33ee298386e7..6b809f66fa7e 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -52,8 +52,7 @@ export default util.createRule({ hasSuggestions: true, messages: { preferFieldStyle: 'Literals should be exposed using readonly fields.', - preferFieldStyleSuggestion: - 'Replace the literals with readonly fields.', + preferFieldStyleSuggestion:'Replace the literals with readonly fields.', preferGetterStyle: 'Literals should be exposed using getters.', preferGetterStyleSuggestion: 'Replace the literals with getters.', }, From 8fdefa1f4d5070c77e286584fa3237be7bc7007f Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 9 Jul 2023 15:35:18 -0400 Subject: [PATCH 9/9] yarn format --- .../eslint-plugin/src/rules/class-literal-property-style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index 6b809f66fa7e..d1eb4ae44703 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -52,7 +52,7 @@ export default util.createRule({ hasSuggestions: true, messages: { preferFieldStyle: 'Literals should be exposed using readonly fields.', - preferFieldStyleSuggestion:'Replace the literals with readonly fields.', + preferFieldStyleSuggestion: 'Replace the literals with readonly fields.', preferGetterStyle: 'Literals should be exposed using getters.', preferGetterStyleSuggestion: 'Replace the literals with getters.', },