From bfc4324f4cda24e30b2d39d5b70f7554f2b6bf81 Mon Sep 17 00:00:00 2001 From: Taeheon Kim Date: Mon, 20 Dec 2021 11:33:23 +0900 Subject: [PATCH] fix(eslint-plugin): [padding-line-between-statements] `type` StatementTypes can't differenciate from variable (#4270) * fix: statementType keyword can't differenciate from variable * test: add test case --- .../rules/padding-line-between-statements.ts | 81 +++++++++++++------ .../padding-line-between-statements.test.ts | 7 ++ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts index 13a84c23419..f64122aaea3 100644 --- a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts +++ b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts @@ -46,15 +46,24 @@ const PADDING_LINE_SEQUENCE = new RegExp( ); /** - * Creates tester which check if a node starts with specific keyword. + * Creates tester which check if a node starts with specific keyword with the + * appropriate AST_NODE_TYPES. * @param keyword The keyword to test. * @returns the created tester. * @private */ -function newKeywordTester(keyword: string): NodeTestObject { +function newKeywordTester( + type: AST_NODE_TYPES | AST_NODE_TYPES[], + keyword: string, +): NodeTestObject { return { test(node, sourceCode): boolean { - return sourceCode.getFirstToken(node)?.value === keyword; + const isSameKeyword = sourceCode.getFirstToken(node)?.value === keyword; + const isSameType = Array.isArray(type) + ? type.some(val => val === node.type) + : type === node.type; + + return isSameKeyword && isSameType; }, }; } @@ -525,30 +534,52 @@ const StatementTypes: Record = { empty: newNodeTypeTester(AST_NODE_TYPES.EmptyStatement), function: newNodeTypeTester(AST_NODE_TYPES.FunctionDeclaration), - break: newKeywordTester('break'), - case: newKeywordTester('case'), - class: newKeywordTester('class'), - const: newKeywordTester('const'), - continue: newKeywordTester('continue'), - debugger: newKeywordTester('debugger'), - default: newKeywordTester('default'), - do: newKeywordTester('do'), - export: newKeywordTester('export'), - for: newKeywordTester('for'), - if: newKeywordTester('if'), - import: newKeywordTester('import'), - let: newKeywordTester('let'), - return: newKeywordTester('return'), - switch: newKeywordTester('switch'), - throw: newKeywordTester('throw'), - try: newKeywordTester('try'), - var: newKeywordTester('var'), - while: newKeywordTester('while'), - with: newKeywordTester('with'), + break: newKeywordTester(AST_NODE_TYPES.BreakStatement, 'break'), + case: newKeywordTester(AST_NODE_TYPES.SwitchCase, 'case'), + class: newKeywordTester(AST_NODE_TYPES.ClassDeclaration, 'class'), + const: newKeywordTester(AST_NODE_TYPES.VariableDeclaration, 'const'), + continue: newKeywordTester(AST_NODE_TYPES.ContinueStatement, 'continue'), + debugger: newKeywordTester(AST_NODE_TYPES.DebuggerStatement, 'debugger'), + default: newKeywordTester( + [AST_NODE_TYPES.SwitchCase, AST_NODE_TYPES.ExportDefaultDeclaration], + 'default', + ), + do: newKeywordTester(AST_NODE_TYPES.DoWhileStatement, 'do'), + export: newKeywordTester( + [ + AST_NODE_TYPES.ExportDefaultDeclaration, + AST_NODE_TYPES.ExportNamedDeclaration, + ], + 'export', + ), + for: newKeywordTester( + [ + AST_NODE_TYPES.ForStatement, + AST_NODE_TYPES.ForInStatement, + AST_NODE_TYPES.ForOfStatement, + ], + 'for', + ), + if: newKeywordTester(AST_NODE_TYPES.IfStatement, 'if'), + import: newKeywordTester(AST_NODE_TYPES.ImportDeclaration, 'import'), + let: newKeywordTester(AST_NODE_TYPES.VariableDeclaration, 'let'), + return: newKeywordTester(AST_NODE_TYPES.ReturnStatement, 'return'), + switch: newKeywordTester(AST_NODE_TYPES.SwitchStatement, 'switch'), + throw: newKeywordTester(AST_NODE_TYPES.ThrowStatement, 'throw'), + try: newKeywordTester(AST_NODE_TYPES.TryStatement, 'try'), + var: newKeywordTester(AST_NODE_TYPES.VariableDeclaration, 'var'), + while: newKeywordTester( + [AST_NODE_TYPES.WhileStatement, AST_NODE_TYPES.DoWhileStatement], + 'while', + ), + with: newKeywordTester(AST_NODE_TYPES.WithStatement, 'with'), // Additional Typescript constructs - interface: newKeywordTester('interface'), - type: newKeywordTester('type'), + interface: newKeywordTester( + AST_NODE_TYPES.TSInterfaceDeclaration, + 'interface', + ), + type: newKeywordTester(AST_NODE_TYPES.TSTypeAliasDeclaration, 'type'), }; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts index 8021b4a650e..4fd71fa1eec 100644 --- a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts +++ b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts @@ -642,6 +642,13 @@ ruleTester.run('padding-line-between-statements', rule, { { blankLine: 'always', prev: 'type', next: '*' }, ], }, + { + code: 'let var1, var2, type;\nvar1 = "bar";\ntype="baz";\ntype="qux";\nvar2="quux";', + options: [ + { blankLine: 'never', prev: '*', next: 'type' }, + { blankLine: 'always', prev: 'type', next: '*' }, + ], + }, //---------------------------------------------------------------------- // interface