From 6a735e142ef67f3af6497f922cf83706867eb6b7 Mon Sep 17 00:00:00 2001 From: Omri Luzon Date: Tue, 15 Nov 2022 18:27:49 +0200 Subject: [PATCH] feat(eslint-plugin): [keyword-spacing] Support spacing in import-type syntax (#5977) * feat/issue5362-keyword-spacing---support-import-type-syntax * uncomment * Update packages/eslint-plugin/tests/rules/keyword-spacing.test.ts Co-authored-by: Josh Goldberg --- .../src/rules/keyword-spacing.ts | 32 ++++++++++++++++ .../tests/rules/keyword-spacing.test.ts | 38 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/packages/eslint-plugin/src/rules/keyword-spacing.ts b/packages/eslint-plugin/src/rules/keyword-spacing.ts index bcb90573836..6af42e5c2fb 100644 --- a/packages/eslint-plugin/src/rules/keyword-spacing.ts +++ b/packages/eslint-plugin/src/rules/keyword-spacing.ts @@ -1,3 +1,4 @@ +import type { TSESTree } from '@typescript-eslint/utils'; import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; import * as util from '../util'; @@ -50,6 +51,37 @@ export default util.createRule({ // make sure to reset the type afterward so we don't permanently mutate the AST asToken.type = oldTokenType; }, + 'ImportDeclaration[importKind=type]'( + node: TSESTree.ImportDeclaration, + ): void { + const typeToken = sourceCode.getFirstToken(node, { skip: 1 })!; + const punctuatorToken = sourceCode.getTokenAfter(typeToken)!; + const spacesBetweenTypeAndPunctuator = + punctuatorToken.range[0] - typeToken.range[1]; + if (context.options[0].after && spacesBetweenTypeAndPunctuator === 0) { + context.report({ + loc: punctuatorToken.loc, + messageId: 'expectedBefore', + data: { value: punctuatorToken.value }, + fix(fixer) { + return fixer.insertTextBefore(punctuatorToken, ' '); + }, + }); + } + if (!context.options[0].after && spacesBetweenTypeAndPunctuator > 0) { + context.report({ + loc: punctuatorToken.loc, + messageId: 'unexpectedBefore', + data: { value: punctuatorToken.value }, + fix(fixer) { + return fixer.removeRange([ + typeToken.range[1], + typeToken.range[1] + spacesBetweenTypeAndPunctuator, + ]); + }, + }); + } + }, }; }, }); diff --git a/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts b/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts index c2694829b35..b8a1a72d2ca 100644 --- a/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts @@ -114,6 +114,16 @@ ruleTester.run('keyword-spacing', rule, { options: [{ overrides: { as: {} } }], parserOptions: { ecmaVersion: 6, sourceType: 'module' }, }, + { + code: 'import type { foo } from "foo";', + options: [{ overrides: { as: {} } }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, + { + code: "import type * as Foo from 'foo'", + options: [{ overrides: { as: {} } }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + }, ], invalid: [ //---------------------------------------------------------------------- @@ -152,5 +162,33 @@ ruleTester.run('keyword-spacing', rule, { parserOptions: { ecmaVersion: 6, sourceType: 'module' }, errors: expectedAfter('as'), }, + { + code: 'import type{ foo } from "foo";', + output: 'import type { foo } from "foo";', + options: [{ after: true, before: true }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [{ messageId: 'expectedBefore', data: { value: '{' } }], + }, + { + code: 'import type { foo } from"foo";', + output: 'import type{ foo } from"foo";', + options: [{ after: false, before: true }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [{ messageId: 'unexpectedBefore', data: { value: '{' } }], + }, + { + code: 'import type* as foo from "foo";', + output: 'import type * as foo from "foo";', + options: [{ after: true, before: true }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [{ messageId: 'expectedBefore', data: { value: '*' } }], + }, + { + code: 'import type * as foo from"foo";', + output: 'import type* as foo from"foo";', + options: [{ after: false, before: true }], + parserOptions: { ecmaVersion: 6, sourceType: 'module' }, + errors: [{ messageId: 'unexpectedBefore', data: { value: '*' } }], + }, ], });