From 377ad4c32ec3ee75d4b76455c848aaf3c1bb2344 Mon Sep 17 00:00:00 2001 From: Knutas Date: Wed, 3 Mar 2021 15:04:18 +0100 Subject: [PATCH 1/4] fix(eslint-plugin): [type-annotation-spacing] handle space after ? --- .../src/rules/type-annotation-spacing.ts | 19 +++++ .../rules/type-annotation-spacing.test.ts | 78 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 985e008c16d..7f547d68640 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -177,6 +177,25 @@ export default util.createRule({ const { before, after } = getRules(ruleSet, typeAnnotation); if (type === ':' && previousToken.value === '?') { + if ( + !before && + sourceCode.isSpaceBetween!(previousToken, punctuatorTokenStart) + ) { + context.report({ + node: punctuatorTokenStart, + messageId: 'unexpectedSpaceBefore', + data: { + type, + }, + fix(fixer) { + return fixer.removeRange([ + previousToken.range[1], + punctuatorTokenStart.range[0], + ]); + }, + }); + } + // shift the start to the ? type = '?:'; punctuatorTokenStart = previousToken; diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index de714cff43f..aec5a115feb 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -314,6 +314,10 @@ type Foo = { code: 'function foo(a : string) {}', options: [{ after: true, before: true }], }, + { + code: 'function foo(a ? : string) {}', + options: [{ after: true, before: true }], + }, { code: ` class Foo { @@ -4593,6 +4597,54 @@ type Bar = Record }, ], }, + { + code: 'function foo(a? : string) {}', + output: 'function foo(a?: string) {}', + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, + line: 1, + column: 17, + }, + ], + }, + { + code: 'function foo(a ? : string) {}', + output: 'function foo(a?: string) {}', + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, + line: 1, + column: 16, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, + line: 1, + column: 18, + }, + ], + }, + { + code: 'function foo(a ? : string) {}', + output: 'function foo(a?: string) {}', + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, + line: 1, + column: 16, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, + line: 1, + column: 19, + }, + ], + }, { code: ` class Foo { @@ -4635,6 +4687,32 @@ class Foo { }, { code: ` +class Foo { + constructor(message ? : string); +} + `, + output: ` +class Foo { + constructor(message?: string); +} + `, + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, + line: 3, + column: 25, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, + line: 3, + column: 27, + }, + ], + }, + { + code: ` class Foo { greet(name ?: string) : string { return name; } } From e3a545daf5b6ee6cb2f0418f0ac4d2c1376775f1 Mon Sep 17 00:00:00 2001 From: Knutas Date: Wed, 3 Mar 2021 18:56:10 +0100 Subject: [PATCH 2/4] fix: skip before flag and add test for interface --- .../src/rules/type-annotation-spacing.ts | 5 +--- .../rules/type-annotation-spacing.test.ts | 30 ++++++++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 7f547d68640..815b5292c93 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -177,10 +177,7 @@ export default util.createRule({ const { before, after } = getRules(ruleSet, typeAnnotation); if (type === ':' && previousToken.value === '?') { - if ( - !before && - sourceCode.isSpaceBetween!(previousToken, punctuatorTokenStart) - ) { + if (sourceCode.isSpaceBetween!(previousToken, punctuatorTokenStart)) { context.report({ node: punctuatorTokenStart, messageId: 'unexpectedSpaceBefore', diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index aec5a115feb..33e7de48303 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -314,10 +314,6 @@ type Foo = { code: 'function foo(a : string) {}', options: [{ after: true, before: true }], }, - { - code: 'function foo(a ? : string) {}', - options: [{ after: true, before: true }], - }, { code: ` class Foo { @@ -4759,6 +4755,32 @@ interface Foo { }, { code: ` +interface Foo { + name ? : string; +} + `, + output: ` +interface Foo { + name?: string; +} + `, + errors: [ + { + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, + line: 3, + column: 10, + }, + { + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, + line: 3, + column: 12, + }, + ], + }, + { + code: ` interface Foo { greet(name ?: string) : string; } From 4c4d93b682a748fa92dd7dcc111899f2ecdf9aa3 Mon Sep 17 00:00:00 2001 From: Knutas Date: Mon, 22 Mar 2021 10:52:25 +0100 Subject: [PATCH 3/4] fix: add new message --- .../src/rules/type-annotation-spacing.ts | 8 ++++++-- .../rules/type-annotation-spacing.test.ts | 20 +++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 815b5292c93..d31ac80a88f 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -35,7 +35,8 @@ type MessageIds = | 'expectedSpaceAfter' | 'expectedSpaceBefore' | 'unexpectedSpaceAfter' - | 'unexpectedSpaceBefore'; + | 'unexpectedSpaceBefore' + | 'unexpectedSpaceBetween'; const definition = { type: 'object', @@ -122,6 +123,8 @@ export default util.createRule({ expectedSpaceBefore: "Expected a space before the '{{type}}'.", unexpectedSpaceAfter: "Unexpected space after the '{{type}}'.", unexpectedSpaceBefore: "Unexpected space before the '{{type}}'.", + unexpectedSpaceBetween: + "Unexpected space between the '{{previousToken}}' and the '{{type}}'.", }, schema: [ { @@ -180,9 +183,10 @@ export default util.createRule({ if (sourceCode.isSpaceBetween!(previousToken, punctuatorTokenStart)) { context.report({ node: punctuatorTokenStart, - messageId: 'unexpectedSpaceBefore', + messageId: 'unexpectedSpaceBetween', data: { type, + previousToken: previousToken.value, }, fix(fixer) { return fixer.removeRange([ diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 33e7de48303..19349a80889 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -4598,8 +4598,8 @@ type Bar = Record output: 'function foo(a?: string) {}', errors: [ { - messageId: 'unexpectedSpaceBefore', - data: { type: ':' }, + messageId: 'unexpectedSpaceBetween', + data: { type: ':', previousToken: '?' }, line: 1, column: 17, }, @@ -4616,8 +4616,8 @@ type Bar = Record column: 16, }, { - messageId: 'unexpectedSpaceBefore', - data: { type: ':' }, + messageId: 'unexpectedSpaceBetween', + data: { type: ':', previousToken: '?' }, line: 1, column: 18, }, @@ -4634,8 +4634,8 @@ type Bar = Record column: 16, }, { - messageId: 'unexpectedSpaceBefore', - data: { type: ':' }, + messageId: 'unexpectedSpaceBetween', + data: { type: ':', previousToken: '?' }, line: 1, column: 19, }, @@ -4700,8 +4700,8 @@ class Foo { column: 25, }, { - messageId: 'unexpectedSpaceBefore', - data: { type: ':' }, + messageId: 'unexpectedSpaceBetween', + data: { type: ':', previousToken: '?' }, line: 3, column: 27, }, @@ -4772,8 +4772,8 @@ interface Foo { column: 10, }, { - messageId: 'unexpectedSpaceBefore', - data: { type: ':' }, + messageId: 'unexpectedSpaceBetween', + data: { type: ':', previousToken: '?' }, line: 3, column: 12, }, From ae1372e39615741d4ea1b1da1be44e5e0bdcde74 Mon Sep 17 00:00:00 2001 From: Knutas Date: Mon, 22 Mar 2021 11:02:21 +0100 Subject: [PATCH 4/4] fix: use isSpaceBetweenTokens to support older ESLint --- packages/eslint-plugin/src/rules/type-annotation-spacing.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index d31ac80a88f..0cf3e34b8b8 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -180,7 +180,9 @@ export default util.createRule({ const { before, after } = getRules(ruleSet, typeAnnotation); if (type === ':' && previousToken.value === '?') { - if (sourceCode.isSpaceBetween!(previousToken, punctuatorTokenStart)) { + if ( + sourceCode.isSpaceBetweenTokens(previousToken, punctuatorTokenStart) + ) { context.report({ node: punctuatorTokenStart, messageId: 'unexpectedSpaceBetween',