From 14ec73d963587409a1465ddd33ce180b4251cfeb Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Fri, 9 Dec 2022 23:15:34 +0200 Subject: [PATCH 01/18] feat/issue5990-extend-base-block-spacing --- .../eslint-plugin/docs/rules/block-spacing.md | 12 +++ .../eslint-plugin/src/rules/block-spacing.ts | 40 ++++++++++ .../src/util/getESLintCoreRule.ts | 1 + .../tests/rules/block-spacing.test.ts | 80 +++++++++++++++++++ .../eslint-plugin/typings/eslint-rules.d.ts | 15 ++++ 5 files changed, 148 insertions(+) create mode 100644 packages/eslint-plugin/docs/rules/block-spacing.md create mode 100644 packages/eslint-plugin/src/rules/block-spacing.ts create mode 100644 packages/eslint-plugin/tests/rules/block-spacing.test.ts diff --git a/packages/eslint-plugin/docs/rules/block-spacing.md b/packages/eslint-plugin/docs/rules/block-spacing.md new file mode 100644 index 000000000000..667c8b9bc844 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/block-spacing.md @@ -0,0 +1,12 @@ +--- +description: 'Enforce consistent spacing before and after keywords.' +--- + +> 🛑 This file is source code, not the primary documentation location! 🛑 +> +> See **https://typescript-eslint.io/rules/block-spacing** for documentation. + +## Examples + +This rule extends the base [`eslint/block-spacing`](https://eslint.org/docs/rules/block-spacing) rule. +This version adds support for generic type parameters on function calls. diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts new file mode 100644 index 000000000000..523cd949eca8 --- /dev/null +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -0,0 +1,40 @@ +import type { TSESTree } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; + +import * as util from '../util'; +import { getESLintCoreRule } from '../util/getESLintCoreRule'; + +const baseRule = getESLintCoreRule('block-spacing'); + +export type Options = util.InferOptionsTypeFromRule; +export type MessageIds = util.InferMessageIdsTypeFromRule; + +export default util.createRule({ + name: 'block-spacing', + meta: { + type: 'layout', + docs: { + description: 'Enforce consistent spacing before and after keywords', + recommended: false, + extendsBaseRule: true, + }, + fixable: 'whitespace', + hasSuggestions: baseRule.meta.hasSuggestions, + schema: baseRule.meta.schema, + messages: baseRule.meta.messages, + }, + defaultOptions: ['always'], + + create(context, [whenToApplyOption]) { + const sourceCode = context.getSourceCode(); + const baseRules = baseRule.create(context); + return { + ...baseRules, + // TSInterfaceBody(node): void {}, + // TSTypeLiteral(node): void {}, + + TSInterfaceBody: baseRules.BlockStatement as never, + TSTypeLiteral: baseRules.BlockStatement as never, + }; + }, +}); diff --git a/packages/eslint-plugin/src/util/getESLintCoreRule.ts b/packages/eslint-plugin/src/util/getESLintCoreRule.ts index 1678903acd32..a4bad9c00af8 100644 --- a/packages/eslint-plugin/src/util/getESLintCoreRule.ts +++ b/packages/eslint-plugin/src/util/getESLintCoreRule.ts @@ -7,6 +7,7 @@ const isESLintV8 = semver.major(version) >= 8; interface RuleMap { /* eslint-disable @typescript-eslint/consistent-type-imports -- more concise to use inline imports */ 'arrow-parens': typeof import('eslint/lib/rules/arrow-parens'); + 'block-spacing': typeof import('eslint/lib/rules/block-spacing'); 'brace-style': typeof import('eslint/lib/rules/brace-style'); 'comma-dangle': typeof import('eslint/lib/rules/comma-dangle'); 'dot-notation': typeof import('eslint/lib/rules/dot-notation'); diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts new file mode 100644 index 000000000000..1ab625ea9c33 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -0,0 +1,80 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the spacing, which prettier will want to fix and break the tests +/* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ +/* eslint-enable eslint-comments/no-use */ +import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'; + +import type { MessageIds, Options } from '../../src/rules/block-spacing'; +import rule from '../../src/rules/block-spacing'; +import type { InvalidTestCase } from '../RuleTester'; +import { RuleTester } from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +type InvalidBlockSpacingTestCase = InvalidTestCase< + 'missing' | 'extra', + ['always' | 'never'] +>; + +const options = [['always'], ['never']] as const; +const typeDeclaration = [ + { + nodeType: AST_NODE_TYPES.TSInterfaceBody, + stringPrefix: 'interface Foo ', + }, + { + nodeType: AST_NODE_TYPES.TSTypeLiteral, + stringPrefix: 'type Foo = ', + }, +]; +const emptyBlocks = ['{}', '{ }']; +const singlePropertyBlocks = ['{bar: true}', '{ bar: true }']; + +ruleTester.run('block-spacing', rule, { + valid: [ + // Empty blocks don't apply + ...options.flatMap(options => + typeDeclaration.flatMap(typeDec => + emptyBlocks.map(blockType => ({ + code: typeDec.stringPrefix + blockType, + options, + })), + ), + ), + ], + invalid: [ + ...options.flatMap(options => + typeDeclaration.flatMap(typeDec => + singlePropertyBlocks.map( + (blockType, blockIndex) => { + return { + code: typeDec.stringPrefix + blockType, + options, + output: + typeDec.stringPrefix + singlePropertyBlocks[1 - blockIndex], + errors: [ + { + type: typeDec.nodeType, + // line: 1, + // column: 1, + messageId: 'missing', + data: { location: 'after', token: '{' }, + }, + { + type: typeDec.nodeType, + // line: 1, + // column: 8, + messageId: 'missing', + data: { location: 'before', token: '}' }, + }, + ], + }; + }, + ), + ), + ), + // .filter(_case => JSON.stringify(_case).includes('type ')), + ], +}); diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 09b54ae4a516..77ca513d1fb3 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -609,6 +609,21 @@ declare module 'eslint/lib/rules/quotes' { export = rule; } +declare module 'eslint/lib/rules/block-spacing' { + import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; + + const rule: TSESLint.RuleModule< + 'missing' | 'extra', + ['always' | 'never'], + { + BlockStatement(node: TSESTree.BlockStatement): void; + StaticBlock(node: TSESTree.StaticBlock): void; + SwitchStatement(node: TSESTree.SwitchStatement): void; + } + >; + export = rule; +} + declare module 'eslint/lib/rules/brace-style' { import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; From f39392891527842760555dc93c66ea1b17f092d5 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:02:22 +0200 Subject: [PATCH 02/18] for history --- .../eslint-plugin/src/rules/block-spacing.ts | 155 +++++++++++++++++- 1 file changed, 151 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 523cd949eca8..6d05ea22e3a5 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -28,13 +28,160 @@ export default util.createRule({ create(context, [whenToApplyOption]) { const sourceCode = context.getSourceCode(); const baseRules = baseRule.create(context); + const always = whenToApplyOption !== 'never'; + const messageId = always ? 'missing' : 'extra'; + /** + * Gets the open brace token from a given node. + * @returns The token of the open brace. + */ + function getOpenBrace( + node: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral, + ): + | TSESTree.BooleanToken + | TSESTree.IdentifierToken + | TSESTree.JSXIdentifierToken + | TSESTree.JSXTextToken + | TSESTree.KeywordToken + | TSESTree.NullToken + | TSESTree.NumericToken + | TSESTree.PunctuatorToken + | TSESTree.RegularExpressionToken + | TSESTree.StringToken + | TSESTree.TemplateToken { + if (node.type === AST_NODE_TYPES.TSInterfaceBody) { + return sourceCode.getFirstToken(node, { skip: 0 })!; + } + if (node.type === AST_NODE_TYPES.TSTypeLiteral) { + return sourceCode.getFirstToken(node, { skip: 0 })!; + } + + return sourceCode.getFirstToken(node)!; + } + + /** + * Checks whether or not: + * - given tokens are on same line. + * - there is/isn't a space between given tokens. + * @param left A token to check. + * @param right The token which is next to `left`. + * @returns + * When the option is `"always"`, `true` if there are one or more spaces between given tokens. + * When the option is `"never"`, `true` if there are not any spaces between given tokens. + * If given tokens are not on same line, it's always `true`. + */ + function isValid(left: TSESTree.Token, right: TSESTree.Token): boolean { + // console.log({ + // 'sourceCode.text,': sourceCode.text, + // 'whenToApplyOption,': whenToApplyOption, + // 'always,': always, + // 'messageId,': messageId, + // 'left,': left, + // 'right,': right, + // '!util.isTokenOnSameLine(left, right),': !util.isTokenOnSameLine(left, right), + // 'sourceCode.isSpaceBetween!(left, right) === always': sourceCode.isSpaceBetween!(left, right) === always + // }); + return ( + !util.isTokenOnSameLine(left, right) || + sourceCode.isSpaceBetween!(left, right) === always + ); + } + + /** + * Checks and reports invalid spacing style inside braces. + * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check. + * @returns + */ + function checkSpacingInsideBraces( + node: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral, + ): void { + // Gets braces and the first/last token of content. + const openBrace = getOpenBrace(node); + const closeBrace = sourceCode.getLastToken(node)!; + const firstToken = sourceCode.getTokenAfter(openBrace, { + includeComments: true, + })!; + const lastToken = sourceCode.getTokenBefore(closeBrace, { + includeComments: true, + })!; + + // Skip if the node is invalid or empty. + if ( + openBrace.type !== AST_TOKEN_TYPES.Punctuator || + openBrace.value !== '{' || + closeBrace.type !== AST_TOKEN_TYPES.Punctuator || + closeBrace.value !== '}' || + firstToken === closeBrace + ) { + return; + } + + // Skip line comments for option never + if (!always && firstToken.type === AST_TOKEN_TYPES.Line) { + return; + } + + // Check. + if (!isValid(openBrace, firstToken)) { + let loc = openBrace.loc; + + if (messageId === 'extra') { + loc = { + start: openBrace.loc.end, + end: firstToken.loc.start, + }; + } + + context.report({ + node, + loc, + messageId, + data: { + location: 'after', + token: openBrace.value, + }, + fix(fixer) { + if (always) { + return fixer.insertTextBefore(firstToken, ' '); + } + + return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); + }, + }); + } + if (!isValid(lastToken, closeBrace)) { + let loc = closeBrace.loc; + + if (messageId === 'extra') { + loc = { + start: lastToken.loc.end, + end: closeBrace.loc.start, + }; + } + context.report({ + node, + loc, + messageId, + data: { + location: 'before', + token: closeBrace.value, + }, + fix(fixer) { + if (always) { + return fixer.insertTextAfter(lastToken, ' '); + } + + return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); + }, + }); + } + } return { ...baseRules, - // TSInterfaceBody(node): void {}, - // TSTypeLiteral(node): void {}, + TSInterfaceBody: checkSpacingInsideBraces, + TSTypeLiteral: checkSpacingInsideBraces, - TSInterfaceBody: baseRules.BlockStatement as never, - TSTypeLiteral: baseRules.BlockStatement as never, + // TSInterfaceBody: baseRules.BlockStatement as never, + // TSTypeLiteral: baseRules.BlockStatement as never, }; }, }); From 0067b46e14ba2d38583fb3c51c886748d16ad558 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:03:51 +0200 Subject: [PATCH 03/18] fixes --- .../eslint-plugin/src/rules/block-spacing.ts | 159 +----------------- .../tests/rules/block-spacing.test.ts | 13 +- 2 files changed, 12 insertions(+), 160 deletions(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 6d05ea22e3a5..4a4004efed49 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -1,6 +1,3 @@ -import type { TSESTree } from '@typescript-eslint/utils'; -import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; - import * as util from '../util'; import { getESLintCoreRule } from '../util/getESLintCoreRule'; @@ -25,163 +22,13 @@ export default util.createRule({ }, defaultOptions: ['always'], - create(context, [whenToApplyOption]) { - const sourceCode = context.getSourceCode(); + create(context) { const baseRules = baseRule.create(context); - const always = whenToApplyOption !== 'never'; - const messageId = always ? 'missing' : 'extra'; - /** - * Gets the open brace token from a given node. - * @returns The token of the open brace. - */ - function getOpenBrace( - node: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral, - ): - | TSESTree.BooleanToken - | TSESTree.IdentifierToken - | TSESTree.JSXIdentifierToken - | TSESTree.JSXTextToken - | TSESTree.KeywordToken - | TSESTree.NullToken - | TSESTree.NumericToken - | TSESTree.PunctuatorToken - | TSESTree.RegularExpressionToken - | TSESTree.StringToken - | TSESTree.TemplateToken { - if (node.type === AST_NODE_TYPES.TSInterfaceBody) { - return sourceCode.getFirstToken(node, { skip: 0 })!; - } - if (node.type === AST_NODE_TYPES.TSTypeLiteral) { - return sourceCode.getFirstToken(node, { skip: 0 })!; - } - - return sourceCode.getFirstToken(node)!; - } - - /** - * Checks whether or not: - * - given tokens are on same line. - * - there is/isn't a space between given tokens. - * @param left A token to check. - * @param right The token which is next to `left`. - * @returns - * When the option is `"always"`, `true` if there are one or more spaces between given tokens. - * When the option is `"never"`, `true` if there are not any spaces between given tokens. - * If given tokens are not on same line, it's always `true`. - */ - function isValid(left: TSESTree.Token, right: TSESTree.Token): boolean { - // console.log({ - // 'sourceCode.text,': sourceCode.text, - // 'whenToApplyOption,': whenToApplyOption, - // 'always,': always, - // 'messageId,': messageId, - // 'left,': left, - // 'right,': right, - // '!util.isTokenOnSameLine(left, right),': !util.isTokenOnSameLine(left, right), - // 'sourceCode.isSpaceBetween!(left, right) === always': sourceCode.isSpaceBetween!(left, right) === always - // }); - return ( - !util.isTokenOnSameLine(left, right) || - sourceCode.isSpaceBetween!(left, right) === always - ); - } - - /** - * Checks and reports invalid spacing style inside braces. - * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check. - * @returns - */ - function checkSpacingInsideBraces( - node: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral, - ): void { - // Gets braces and the first/last token of content. - const openBrace = getOpenBrace(node); - const closeBrace = sourceCode.getLastToken(node)!; - const firstToken = sourceCode.getTokenAfter(openBrace, { - includeComments: true, - })!; - const lastToken = sourceCode.getTokenBefore(closeBrace, { - includeComments: true, - })!; - - // Skip if the node is invalid or empty. - if ( - openBrace.type !== AST_TOKEN_TYPES.Punctuator || - openBrace.value !== '{' || - closeBrace.type !== AST_TOKEN_TYPES.Punctuator || - closeBrace.value !== '}' || - firstToken === closeBrace - ) { - return; - } - - // Skip line comments for option never - if (!always && firstToken.type === AST_TOKEN_TYPES.Line) { - return; - } - - // Check. - if (!isValid(openBrace, firstToken)) { - let loc = openBrace.loc; - - if (messageId === 'extra') { - loc = { - start: openBrace.loc.end, - end: firstToken.loc.start, - }; - } - - context.report({ - node, - loc, - messageId, - data: { - location: 'after', - token: openBrace.value, - }, - fix(fixer) { - if (always) { - return fixer.insertTextBefore(firstToken, ' '); - } - - return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); - }, - }); - } - if (!isValid(lastToken, closeBrace)) { - let loc = closeBrace.loc; - - if (messageId === 'extra') { - loc = { - start: lastToken.loc.end, - end: closeBrace.loc.start, - }; - } - context.report({ - node, - loc, - messageId, - data: { - location: 'before', - token: closeBrace.value, - }, - fix(fixer) { - if (always) { - return fixer.insertTextAfter(lastToken, ' '); - } - - return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); - }, - }); - } - } return { ...baseRules, - TSInterfaceBody: checkSpacingInsideBraces, - TSTypeLiteral: checkSpacingInsideBraces, - // TSInterfaceBody: baseRules.BlockStatement as never, - // TSTypeLiteral: baseRules.BlockStatement as never, + TSInterfaceBody: baseRules.BlockStatement as never, + TSTypeLiteral: baseRules.BlockStatement as never, }; }, }); diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 1ab625ea9c33..b2394b5e8148 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -47,8 +47,14 @@ ruleTester.run('block-spacing', rule, { invalid: [ ...options.flatMap(options => typeDeclaration.flatMap(typeDec => - singlePropertyBlocks.map( + singlePropertyBlocks.flatMap( (blockType, blockIndex) => { + if ( + (options[0] === 'always' && blockType.startsWith('{ ')) || + (options[0] === 'never' && blockType.startsWith('{bar')) + ) { + return []; + } return { code: typeDec.stringPrefix + blockType, options, @@ -59,14 +65,14 @@ ruleTester.run('block-spacing', rule, { type: typeDec.nodeType, // line: 1, // column: 1, - messageId: 'missing', + messageId: options[0] === 'always' ? 'missing' : 'extra', data: { location: 'after', token: '{' }, }, { type: typeDec.nodeType, // line: 1, // column: 8, - messageId: 'missing', + messageId: options[0] === 'always' ? 'missing' : 'extra', data: { location: 'before', token: '}' }, }, ], @@ -75,6 +81,5 @@ ruleTester.run('block-spacing', rule, { ), ), ), - // .filter(_case => JSON.stringify(_case).includes('type ')), ], }); From 7e8b5403d0c48b3b7beb6f0a81993ee8c942e636 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:28:50 +0200 Subject: [PATCH 04/18] cleanup --- .../tests/rules/block-spacing.test.ts | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index b2394b5e8148..4935f715bea4 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -1,12 +1,7 @@ -/* eslint-disable eslint-comments/no-use */ -// this rule tests the spacing, which prettier will want to fix and break the tests -/* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ -/* eslint-enable eslint-comments/no-use */ -import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import type { MessageIds, Options } from '../../src/rules/block-spacing'; import rule from '../../src/rules/block-spacing'; -import type { InvalidTestCase } from '../RuleTester'; +import type { InvalidTestCase, ValidTestCase } from '../RuleTester'; import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ @@ -18,7 +13,7 @@ type InvalidBlockSpacingTestCase = InvalidTestCase< ['always' | 'never'] >; -const options = [['always'], ['never']] as const; +const options = ['always', 'never'] as const; const typeDeclaration = [ { nodeType: AST_NODE_TYPES.TSInterfaceBody, @@ -35,44 +30,41 @@ const singlePropertyBlocks = ['{bar: true}', '{ bar: true }']; ruleTester.run('block-spacing', rule, { valid: [ // Empty blocks don't apply - ...options.flatMap(options => + ...options.flatMap(option => typeDeclaration.flatMap(typeDec => - emptyBlocks.map(blockType => ({ + emptyBlocks.map>(blockType => ({ code: typeDec.stringPrefix + blockType, - options, + options: [option], })), ), ), ], invalid: [ - ...options.flatMap(options => + ...options.flatMap(option => typeDeclaration.flatMap(typeDec => singlePropertyBlocks.flatMap( (blockType, blockIndex) => { + // These are actually valid, so filter them out if ( - (options[0] === 'always' && blockType.startsWith('{ ')) || - (options[0] === 'never' && blockType.startsWith('{bar')) + (option === 'always' && blockType.startsWith('{ ')) || + (option === 'never' && blockType.startsWith('{bar')) ) { return []; } return { code: typeDec.stringPrefix + blockType, - options, + options: [option], output: typeDec.stringPrefix + singlePropertyBlocks[1 - blockIndex], errors: [ { type: typeDec.nodeType, - // line: 1, - // column: 1, - messageId: options[0] === 'always' ? 'missing' : 'extra', + messageId: option === 'always' ? 'missing' : 'extra', data: { location: 'after', token: '{' }, }, { type: typeDec.nodeType, - // line: 1, - // column: 8, - messageId: options[0] === 'always' ? 'missing' : 'extra', + messageId: option === 'always' ? 'missing' : 'extra', data: { location: 'before', token: '}' }, }, ], From 3cd0d6f96f5ce0725f98e1500f6b54469c74827f Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:30:58 +0200 Subject: [PATCH 05/18] with a comment for the option --- .../eslint-plugin/tests/rules/block-spacing.test.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 4935f715bea4..162a3791b473 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -51,11 +51,17 @@ ruleTester.run('block-spacing', rule, { ) { return []; } + const code = + typeDec.stringPrefix + blockType + `; /* ${option} */`; + const output = + typeDec.stringPrefix + + singlePropertyBlocks[1 - blockIndex] + + `; /* ${option} */`; + return { - code: typeDec.stringPrefix + blockType, + code, options: [option], - output: - typeDec.stringPrefix + singlePropertyBlocks[1 - blockIndex], + output, errors: [ { type: typeDec.nodeType, From 590d9f893174c03e6d6c3d6a957a24fe61ad82c6 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:49:45 +0200 Subject: [PATCH 06/18] support enums as well --- .../eslint-plugin/src/rules/block-spacing.ts | 133 +++++++++++++++++- .../tests/rules/block-spacing.test.ts | 25 +++- 2 files changed, 150 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 4a4004efed49..1a8d074e6d9a 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -1,3 +1,6 @@ +import type { TSESTree } from '@typescript-eslint/utils'; +import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; + import * as util from '../util'; import { getESLintCoreRule } from '../util/getESLintCoreRule'; @@ -22,13 +25,141 @@ export default util.createRule({ }, defaultOptions: ['always'], - create(context) { + create(context, [whenToApplyOption]) { + const sourceCode = context.getSourceCode(); const baseRules = baseRule.create(context); + const always = whenToApplyOption !== 'never'; + const messageId = always ? 'missing' : 'extra'; + /** + * Gets the open brace token from a given node. + * @returns The token of the open brace. + */ + function getOpenBrace( + node: TSESTree.TSEnumDeclaration, + ): TSESTree.PunctuatorToken { + // guaranteed for enums + // This is the only change made here from the base rule + return sourceCode.getFirstToken(node, { + filter: token => + token.type === AST_TOKEN_TYPES.Punctuator && token.value == '{', + }) as TSESTree.PunctuatorToken; + } + + /** + * Checks whether or not: + * - given tokens are on same line. + * - there is/isn't a space between given tokens. + * @param left A token to check. + * @param right The token which is next to `left`. + * @returns + * When the option is `"always"`, `true` if there are one or more spaces between given tokens. + * When the option is `"never"`, `true` if there are not any spaces between given tokens. + * If given tokens are not on same line, it's always `true`. + */ + function isValid(left: TSESTree.Token, right: TSESTree.Token): boolean { + return ( + !util.isTokenOnSameLine(left, right) || + sourceCode.isSpaceBetween!(left, right) === always + ); + } + + /** + * Checks and reports invalid spacing style inside braces. + * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check. + * @returns + */ + function checkSpacingInsideBraces(node: TSESTree.TSEnumDeclaration): void { + // Gets braces and the first/last token of content. + const openBrace = getOpenBrace(node); + const closeBrace = sourceCode.getLastToken(node)!; + const firstToken = sourceCode.getTokenAfter(openBrace, { + includeComments: true, + })!; + const lastToken = sourceCode.getTokenBefore(closeBrace, { + includeComments: true, + })!; + + // Skip if the node is invalid or empty. + if ( + openBrace.type !== AST_TOKEN_TYPES.Punctuator || + openBrace.value !== '{' || + closeBrace.type !== AST_TOKEN_TYPES.Punctuator || + closeBrace.value !== '}' || + firstToken === closeBrace + ) { + return; + } + + // Skip line comments for option never + if (!always && firstToken.type === AST_TOKEN_TYPES.Line) { + return; + } + + // Check. + if (!isValid(openBrace, firstToken)) { + let loc = openBrace.loc; + + if (messageId === 'extra') { + loc = { + start: openBrace.loc.end, + end: firstToken.loc.start, + }; + } + + context.report({ + node, + loc, + messageId, + data: { + location: 'after', + token: openBrace.value, + }, + fix(fixer) { + if (always) { + return fixer.insertTextBefore(firstToken, ' '); + } + + return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); + }, + }); + } + if (!isValid(lastToken, closeBrace)) { + let loc = closeBrace.loc; + + if (messageId === 'extra') { + loc = { + start: lastToken.loc.end, + end: closeBrace.loc.start, + }; + } + context.report({ + node, + loc, + messageId, + data: { + location: 'before', + token: closeBrace.value, + }, + fix(fixer) { + if (always) { + return fixer.insertTextAfter(lastToken, ' '); + } + + return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); + }, + }); + } + } return { ...baseRules, + // This code worked "out of the box" for interface and type literal + // Enums were very close to match as well, the only reason they it not is that was that enums don't have a body node in the parser + // So the opening brace punctuator starts in the middle of the node + // `getFirstToken` in the base rule did not filter for the first opening brace punctuator TSInterfaceBody: baseRules.BlockStatement as never, TSTypeLiteral: baseRules.BlockStatement as never, + TSEnumDeclaration: checkSpacingInsideBraces, }; }, }); diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 162a3791b473..2471939f3726 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -23,6 +23,14 @@ const typeDeclaration = [ nodeType: AST_NODE_TYPES.TSTypeLiteral, stringPrefix: 'type Foo = ', }, + { + nodeType: AST_NODE_TYPES.TSEnumDeclaration, + stringPrefix: 'enum Foo ', + }, + { + nodeType: AST_NODE_TYPES.TSEnumDeclaration, + stringPrefix: 'const enum Foo ', + }, ]; const emptyBlocks = ['{}', '{ }']; const singlePropertyBlocks = ['{bar: true}', '{ bar: true }']; @@ -41,8 +49,8 @@ ruleTester.run('block-spacing', rule, { ], invalid: [ ...options.flatMap(option => - typeDeclaration.flatMap(typeDec => - singlePropertyBlocks.flatMap( + typeDeclaration.flatMap(typeDec => { + return singlePropertyBlocks.flatMap( (blockType, blockIndex) => { // These are actually valid, so filter them out if ( @@ -51,12 +59,15 @@ ruleTester.run('block-spacing', rule, { ) { return []; } - const code = - typeDec.stringPrefix + blockType + `; /* ${option} */`; - const output = + let code = typeDec.stringPrefix + blockType + `; /* ${option} */`; + let output = typeDec.stringPrefix + singlePropertyBlocks[1 - blockIndex] + `; /* ${option} */`; + if (typeDec.nodeType === AST_NODE_TYPES.TSEnumDeclaration) { + output = output.replace(':', '='); + code = code.replace(':', '='); + } return { code, @@ -76,8 +87,8 @@ ruleTester.run('block-spacing', rule, { ], }; }, - ), - ), + ); + }), ), ], }); From ab64e29abe3ec0b8483294ea2cf0d5951f1df02a Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:53:03 +0200 Subject: [PATCH 07/18] template string --- packages/eslint-plugin/tests/rules/block-spacing.test.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 2471939f3726..c5f4dd223166 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -59,11 +59,9 @@ ruleTester.run('block-spacing', rule, { ) { return []; } - let code = typeDec.stringPrefix + blockType + `; /* ${option} */`; - let output = - typeDec.stringPrefix + - singlePropertyBlocks[1 - blockIndex] + - `; /* ${option} */`; + const reverseBlockType = singlePropertyBlocks[1 - blockIndex]; + let code = `${typeDec.stringPrefix}${blockType}; /* ${option} */`; + let output = `${typeDec.stringPrefix}${reverseBlockType}; /* ${option} */`; if (typeDec.nodeType === AST_NODE_TYPES.TSEnumDeclaration) { output = output.replace(':', '='); code = code.replace(':', '='); From 65fa0e6f4bd498c90e27505f16f09ad4c3dd685e Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 00:58:57 +0200 Subject: [PATCH 08/18] fix doc --- packages/eslint-plugin/docs/rules/block-spacing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/block-spacing.md b/packages/eslint-plugin/docs/rules/block-spacing.md index 667c8b9bc844..d4e25bafe45d 100644 --- a/packages/eslint-plugin/docs/rules/block-spacing.md +++ b/packages/eslint-plugin/docs/rules/block-spacing.md @@ -9,4 +9,4 @@ description: 'Enforce consistent spacing before and after keywords.' ## Examples This rule extends the base [`eslint/block-spacing`](https://eslint.org/docs/rules/block-spacing) rule. -This version adds support for generic type parameters on function calls. +This version adds support for typescript related blocks (interfaces, object type literals and enums). From d38b80e5dd9e830466a64387ca5d0de35057dd9e Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 01:00:21 +0200 Subject: [PATCH 09/18] fix doc --- packages/eslint-plugin/src/rules/block-spacing.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 1a8d074e6d9a..3224afb8337d 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -14,7 +14,8 @@ export default util.createRule({ meta: { type: 'layout', docs: { - description: 'Enforce consistent spacing before and after keywords', + description: + 'Disallow or enforce spaces inside of blocks after opening block and before closing block', recommended: false, extendsBaseRule: true, }, From dbe273ccf4a5e0ec62b386106845201832ac0937 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 01:13:46 +0200 Subject: [PATCH 10/18] typescript -> TypeScript --- packages/eslint-plugin/docs/rules/block-spacing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/block-spacing.md b/packages/eslint-plugin/docs/rules/block-spacing.md index d4e25bafe45d..e0d59fd8284f 100644 --- a/packages/eslint-plugin/docs/rules/block-spacing.md +++ b/packages/eslint-plugin/docs/rules/block-spacing.md @@ -9,4 +9,4 @@ description: 'Enforce consistent spacing before and after keywords.' ## Examples This rule extends the base [`eslint/block-spacing`](https://eslint.org/docs/rules/block-spacing) rule. -This version adds support for typescript related blocks (interfaces, object type literals and enums). +This version adds support for TypeScript related blocks (interfaces, object type literals and enums). From 2496815c002016966b3b5b857730f0cc1a2a99ab Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 10 Dec 2022 02:10:30 +0200 Subject: [PATCH 11/18] add missing things --- packages/eslint-plugin/docs/rules/block-spacing.md | 2 +- packages/eslint-plugin/src/configs/all.ts | 2 ++ packages/eslint-plugin/src/rules/index.ts | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/block-spacing.md b/packages/eslint-plugin/docs/rules/block-spacing.md index e0d59fd8284f..6a902214bbb4 100644 --- a/packages/eslint-plugin/docs/rules/block-spacing.md +++ b/packages/eslint-plugin/docs/rules/block-spacing.md @@ -1,5 +1,5 @@ --- -description: 'Enforce consistent spacing before and after keywords.' +description: 'Disallow or enforce spaces inside of blocks after opening block and before closing block.' --- > 🛑 This file is source code, not the primary documentation location! 🛑 diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index 20ea892f581d..a7e246de2d3c 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -11,6 +11,8 @@ export = { '@typescript-eslint/ban-ts-comment': 'error', '@typescript-eslint/ban-tslint-comment': 'error', '@typescript-eslint/ban-types': 'error', + 'block-spacing': 'off', + '@typescript-eslint/block-spacing': 'error', 'brace-style': 'off', '@typescript-eslint/brace-style': 'error', '@typescript-eslint/class-literal-property-style': 'error', diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 8a3c2bbf4371..468c60954a13 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -4,6 +4,7 @@ import awaitThenable from './await-thenable'; import banTsComment from './ban-ts-comment'; import banTslintComment from './ban-tslint-comment'; import banTypes from './ban-types'; +import blockSpacing from './block-spacing'; import braceStyle from './brace-style'; import classLiteralPropertyStyle from './class-literal-property-style'; import commaDangle from './comma-dangle'; @@ -135,6 +136,7 @@ export default { 'ban-ts-comment': banTsComment, 'ban-tslint-comment': banTslintComment, 'ban-types': banTypes, + 'block-spacing': blockSpacing, 'brace-style': braceStyle, 'class-literal-property-style': classLiteralPropertyStyle, 'comma-dangle': commaDangle, From 21a44faacee36a128ff20433e618170ab1d522a1 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 17 Dec 2022 01:03:51 +0200 Subject: [PATCH 12/18] CR: remove jsdoc types --- packages/eslint-plugin/src/rules/block-spacing.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 3224afb8337d..224dec2a119d 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -66,8 +66,6 @@ export default util.createRule({ /** * Checks and reports invalid spacing style inside braces. - * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check. - * @returns */ function checkSpacingInsideBraces(node: TSESTree.TSEnumDeclaration): void { // Gets braces and the first/last token of content. @@ -96,7 +94,6 @@ export default util.createRule({ return; } - // Check. if (!isValid(openBrace, firstToken)) { let loc = openBrace.loc; From 82ec70db405a8435919a16429e2df91c5aa897c4 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 17 Dec 2022 01:18:25 +0200 Subject: [PATCH 13/18] rename typeDeclaration -> typeDeclarations --- packages/eslint-plugin/tests/rules/block-spacing.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index c5f4dd223166..9674e91797b8 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -14,7 +14,7 @@ type InvalidBlockSpacingTestCase = InvalidTestCase< >; const options = ['always', 'never'] as const; -const typeDeclaration = [ +const typeDeclarations = [ { nodeType: AST_NODE_TYPES.TSInterfaceBody, stringPrefix: 'interface Foo ', @@ -39,7 +39,7 @@ ruleTester.run('block-spacing', rule, { valid: [ // Empty blocks don't apply ...options.flatMap(option => - typeDeclaration.flatMap(typeDec => + typeDeclarations.flatMap(typeDec => emptyBlocks.map>(blockType => ({ code: typeDec.stringPrefix + blockType, options: [option], @@ -49,7 +49,7 @@ ruleTester.run('block-spacing', rule, { ], invalid: [ ...options.flatMap(option => - typeDeclaration.flatMap(typeDec => { + typeDeclarations.flatMap(typeDec => { return singlePropertyBlocks.flatMap( (blockType, blockIndex) => { // These are actually valid, so filter them out From cef520c561356bc021cfc59ab8be30eb45663d27 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 17 Dec 2022 01:20:13 +0200 Subject: [PATCH 14/18] more valid cases with comments --- .../tests/rules/block-spacing.test.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 9674e91797b8..be16269f2a60 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -46,6 +46,28 @@ ruleTester.run('block-spacing', rule, { })), ), ), + ...typeDeclarations.flatMap>( + typeDec => { + const property = + typeDec.nodeType === AST_NODE_TYPES.TSEnumDeclaration + ? 'bar = 1' + : 'bar: true;'; + return [ + { + code: `${typeDec.stringPrefix}{ /* comment */ ${property} /* comment */ } // always`, + options: ['always'], + }, + { + code: `${typeDec.stringPrefix}{/* comment */ ${property} /* comment */} // never`, + options: ['never'], + }, + { + code: `${typeDec.stringPrefix}{ //comment\n ${property}}`, + options: ['never'], + }, + ]; + }, + ), ], invalid: [ ...options.flatMap(option => From 415733a51ad2736d9c869a8e158b493b19af5dbd Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 17 Dec 2022 01:27:49 +0200 Subject: [PATCH 15/18] invalid cases with block comments --- .../tests/rules/block-spacing.test.ts | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index be16269f2a60..64840461adba 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -110,5 +110,49 @@ ruleTester.run('block-spacing', rule, { ); }), ), + + // With block comments + ...typeDeclarations.flatMap(typeDec => { + const property = + typeDec.nodeType === AST_NODE_TYPES.TSEnumDeclaration + ? 'bar = 1' + : 'bar: true;'; + return [ + { + code: `${typeDec.stringPrefix}{ /* comment */ ${property} /* comment */ } /* never */`, + output: `${typeDec.stringPrefix}{/* comment */ ${property} /* comment */} /* never */`, + options: ['never'], + errors: [ + { + type: typeDec.nodeType, + messageId: 'extra', + data: { location: 'after', token: '{' }, + }, + { + type: typeDec.nodeType, + messageId: 'extra', + data: { location: 'before', token: '}' }, + }, + ], + }, + { + code: `${typeDec.stringPrefix}{/* comment */ ${property} /* comment */} /* always */`, + output: `${typeDec.stringPrefix}{ /* comment */ ${property} /* comment */ } /* always */`, + options: ['always'], + errors: [ + { + type: typeDec.nodeType, + messageId: 'missing', + data: { location: 'after', token: '{' }, + }, + { + type: typeDec.nodeType, + messageId: 'missing', + data: { location: 'before', token: '}' }, + }, + ], + }, + ]; + }), ], }); From 725d8a9bae5181b955145ca08a0334cc6da58e2c Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Sat, 17 Dec 2022 01:42:23 +0200 Subject: [PATCH 16/18] more concise --- .../tests/rules/block-spacing.test.ts | 73 ++++++++----------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 64840461adba..49578b8c0618 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -34,6 +34,7 @@ const typeDeclarations = [ ]; const emptyBlocks = ['{}', '{ }']; const singlePropertyBlocks = ['{bar: true}', '{ bar: true }']; +const blockComment = '/* comment */'; ruleTester.run('block-spacing', rule, { valid: [ @@ -110,49 +111,35 @@ ruleTester.run('block-spacing', rule, { ); }), ), - // With block comments - ...typeDeclarations.flatMap(typeDec => { - const property = - typeDec.nodeType === AST_NODE_TYPES.TSEnumDeclaration - ? 'bar = 1' - : 'bar: true;'; - return [ - { - code: `${typeDec.stringPrefix}{ /* comment */ ${property} /* comment */ } /* never */`, - output: `${typeDec.stringPrefix}{/* comment */ ${property} /* comment */} /* never */`, - options: ['never'], - errors: [ - { - type: typeDec.nodeType, - messageId: 'extra', - data: { location: 'after', token: '{' }, - }, - { - type: typeDec.nodeType, - messageId: 'extra', - data: { location: 'before', token: '}' }, - }, - ], - }, - { - code: `${typeDec.stringPrefix}{/* comment */ ${property} /* comment */} /* always */`, - output: `${typeDec.stringPrefix}{ /* comment */ ${property} /* comment */ } /* always */`, - options: ['always'], - errors: [ - { - type: typeDec.nodeType, - messageId: 'missing', - data: { location: 'after', token: '{' }, - }, - { - type: typeDec.nodeType, - messageId: 'missing', - data: { location: 'before', token: '}' }, - }, - ], - }, - ]; - }), + ...options.flatMap(option => + typeDeclarations.flatMap(typeDec => { + const property = + typeDec.nodeType === AST_NODE_TYPES.TSEnumDeclaration + ? 'bar = 1' + : 'bar: true;'; + const alwaysSpace = option === 'always' ? '' : ' '; + const neverSpace = option === 'always' ? ' ' : ''; + return [ + { + code: `${typeDec.stringPrefix}{${alwaysSpace}${blockComment}${property}${blockComment}${alwaysSpace}} /* ${option} */`, + output: `${typeDec.stringPrefix}{${neverSpace}${blockComment}${property}${blockComment}${neverSpace}} /* ${option} */`, + options: [option], + errors: [ + { + type: typeDec.nodeType, + messageId: option === 'always' ? 'missing' : 'extra', + data: { location: 'after', token: '{' }, + }, + { + type: typeDec.nodeType, + messageId: option === 'always' ? 'missing' : 'extra', + data: { location: 'before', token: '}' }, + }, + ], + }, + ]; + }), + ), ], }); From 6fd6ffbc4cca5b388c8408439300c86caef957c4 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Thu, 22 Dec 2022 07:14:48 +0200 Subject: [PATCH 17/18] fix comment --- packages/eslint-plugin/src/rules/block-spacing.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 224dec2a119d..45e6eb2bfd5e 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -152,9 +152,9 @@ export default util.createRule({ ...baseRules, // This code worked "out of the box" for interface and type literal - // Enums were very close to match as well, the only reason they it not is that was that enums don't have a body node in the parser - // So the opening brace punctuator starts in the middle of the node - // `getFirstToken` in the base rule did not filter for the first opening brace punctuator + // Enums were very close to match as well, the only reason they are not is that was that enums don't have a body node in the parser + // So the opening brace punctuator starts in the middle of the node - `getFirstToken` in + // the base rule did not filter for the first opening brace punctuator TSInterfaceBody: baseRules.BlockStatement as never, TSTypeLiteral: baseRules.BlockStatement as never, TSEnumDeclaration: checkSpacingInsideBraces, From b6b1140b3ff246a1d8c3dbb233be67c5b43820b8 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Tue, 7 Feb 2023 22:15:42 +0200 Subject: [PATCH 18/18] fix lint error --- packages/eslint-plugin/src/rules/block-spacing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 45e6eb2bfd5e..745132978f77 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -42,7 +42,7 @@ export default util.createRule({ // This is the only change made here from the base rule return sourceCode.getFirstToken(node, { filter: token => - token.type === AST_TOKEN_TYPES.Punctuator && token.value == '{', + token.type === AST_TOKEN_TYPES.Punctuator && token.value === '{', }) as TSESTree.PunctuatorToken; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy