Skip to content

Commit

Permalink
refactor: use @typescript-eslint types and constants
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Apr 24, 2024
1 parent a82b143 commit e8ea5eb
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 44 deletions.
42 changes: 23 additions & 19 deletions src/rules/utils/ast-utils.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import type { AST, SourceCode } from 'eslint';
import type { Node } from 'estree';
import {
AST_NODE_TYPES,
AST_TOKEN_TYPES,
type TSESLint,
type TSESTree,
} from '@typescript-eslint/utils';

export const isTokenASemicolon = (token: AST.Token): boolean =>
token.value === ';' && token.type === 'Punctuator';
export const isTokenASemicolon = (token: TSESTree.Token): boolean =>
token.value === ';' && token.type === AST_TOKEN_TYPES.Punctuator;

export const areTokensOnSameLine = (
left: Node | AST.Token,
right: Node | AST.Token,
left: TSESTree.Node | TSESTree.Token,
right: TSESTree.Node | TSESTree.Token,
): boolean => left.loc.end.line === right.loc.start.line;

// We'll only verify nodes with these parent types
const STATEMENT_LIST_PARENTS = new Set([
'Program',
'BlockStatement',
'SwitchCase',
'SwitchStatement',
AST_NODE_TYPES.Program,
AST_NODE_TYPES.BlockStatement,
AST_NODE_TYPES.SwitchCase,
AST_NODE_TYPES.SwitchStatement,
]);

export const isValidParent = (parentType: string): boolean => {
Expand All @@ -31,9 +35,9 @@ export const isValidParent = (parentType: string): boolean => {
* ;[1, 2, 3].forEach(bar)
*/
export const getActualLastToken = (
sourceCode: SourceCode,
node: Node,
): AST.Token => {
sourceCode: TSESLint.SourceCode,
node: TSESTree.Node,
): TSESTree.Token => {
const semiToken = sourceCode.getLastToken(node);
const prevToken = sourceCode.getTokenBefore(semiToken);

Check failure on line 42 in src/rules/utils/ast-utils.ts

View workflow job for this annotation

GitHub Actions / typecheck

Argument of type 'BooleanToken | IdentifierToken | JSXIdentifierToken | JSXTextToken | KeywordToken | NullToken | ... 5 more ... | null' is not assignable to parameter of type 'Node | Token'.
const nextToken = sourceCode.getTokenAfter(semiToken);
Expand All @@ -54,19 +58,19 @@ export const getActualLastToken = (
* Comments are separators of the padding line sequences.
*/
export const getPaddingLineSequences = (
prevNode: Node,
nextNode: Node,
sourceCode: SourceCode,
): AST.Token[][] => {
const pairs: AST.Token[][] = [];
prevNode: TSESTree.Node,
nextNode: TSESTree.Node,
sourceCode: TSESLint.SourceCode,
): TSESTree.Token[][] => {
const pairs: TSESTree.Token[][] = [];
const includeComments = true;
let prevToken = getActualLastToken(sourceCode, prevNode);

if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
do {
const token = sourceCode.getTokenAfter(prevToken, {
includeComments,
}) as AST.Token;
}) as TSESTree.Token;

if (token.loc.start.line - prevToken.loc.end.line >= 2) {
pairs.push([prevToken, token]);
Expand Down
62 changes: 37 additions & 25 deletions src/rules/utils/padding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
* See: https://github.com/eslint/eslint/blob/master/lib/rules/utils/ast-utils.js
*/

import type { AST, Rule, SourceCode } from 'eslint';
import type { Node } from 'estree';
import {
AST_NODE_TYPES,
AST_TOKEN_TYPES,
type TSESLint,
type TSESTree,
} from '@typescript-eslint/utils';
import * as astUtils from './ast-utils';
import { createRule } from './misc';

Expand All @@ -33,7 +37,10 @@ export const enum StatementType {

type StatementTypes = StatementType | StatementType[];

type StatementTester = (node: Node, sourceCode: SourceCode) => boolean;
type StatementTester = (
node: TSESTree.Node,
sourceCode: TSESLint.SourceCode,
) => boolean;

// Padding type to apply between statements
export const enum PaddingType {
Expand All @@ -49,21 +56,21 @@ interface Config {
}

interface ScopeInfo {
prevNode: Node | null;
prevNode: TSESTree.Node | null;
enter: () => void;
exit: () => void;
}

interface PaddingContext {
ruleContext: Rule.RuleContext;
sourceCode: SourceCode;
ruleContext: TSESLint.RuleContext<string, unknown[]>;
sourceCode: TSESLint.SourceCode;
scopeInfo: ScopeInfo;
configs: Config[];
}

type PaddingTester = (
prevNode: Node,
nextNode: Node,
prevNode: TSESTree.Node,
nextNode: TSESTree.Node,
paddingContext: PaddingContext,
) => void;

Expand All @@ -72,23 +79,25 @@ type PaddingTester = (
// And so on...
interface Scope {
upper: Scope | null;
prevNode: Node | null;
prevNode: TSESTree.Node | null;
}

// Creates a StatementTester to test an ExpressionStatement's first token name
const createTokenTester = (tokenName: string): StatementTester => {
return (node: Node, sourceCode: SourceCode): boolean => {
return (node: TSESTree.Node, sourceCode: TSESLint.SourceCode): boolean => {
let activeNode = node;

if (activeNode.type === 'ExpressionStatement') {
if (activeNode.type === AST_NODE_TYPES.ExpressionStatement) {
// In the case of `await`, we actually care about its argument
if (activeNode.expression.type === 'AwaitExpression') {
if (activeNode.expression.type === AST_NODE_TYPES.AwaitExpression) {
activeNode = activeNode.expression.argument;
}

const token = sourceCode.getFirstToken(activeNode);

return token.type === 'Identifier' && token.value === tokenName;
return (
token.type === AST_TOKEN_TYPES.Identifier && token.value === tokenName
);
}

return false;
Expand Down Expand Up @@ -120,8 +129,8 @@ const statementTesters: { [T in StatementType]: StatementTester } = {
* trailing comments.
*/
const paddingAlwaysTester = (
prevNode: Node,
nextNode: Node,
prevNode: TSESTree.Node,
nextNode: TSESTree.Node,
paddingContext: PaddingContext,
): void => {
const { sourceCode, ruleContext } = paddingContext;
Expand All @@ -140,7 +149,7 @@ const paddingAlwaysTester = (
ruleContext.report({
node: nextNode,
message: 'Expected blank line before this statement.',
fix(fixer: Rule.RuleFixer): Rule.Fix {
fix(fixer: TSESLint.RuleFixer) {
let prevToken = astUtils.getActualLastToken(sourceCode, prevNode);
const nextToken = (sourceCode.getFirstTokenBetween(prevToken, nextNode, {
includeComments: true,
Expand All @@ -161,7 +170,7 @@ const paddingAlwaysTester = (
* // comment.
* bar();
*/
filter(token: AST.Token): boolean {
filter(token: TSESTree.Token): boolean {
if (astUtils.areTokensOnSameLine(prevToken, token)) {
prevToken = token;

Expand All @@ -170,7 +179,7 @@ const paddingAlwaysTester = (

return true;
},
}) || nextNode) as AST.Token;
}) || nextNode) as TSESTree.Token;

const insertText = astUtils.areTokensOnSameLine(prevToken, nextToken)
? '\n\n'
Expand Down Expand Up @@ -212,15 +221,15 @@ const createScopeInfo = (): ScopeInfo => {
* Check whether the given node matches the statement type
*/
const nodeMatchesType = (
node: Node,
node: TSESTree.Node,
statementType: StatementTypes,
paddingContext: PaddingContext,
): boolean => {
let innerStatementNode = node;
const { sourceCode } = paddingContext;

// Dig into LabeledStatement body until it's not that anymore
while (innerStatementNode.type === 'LabeledStatement') {
while (innerStatementNode.type === AST_NODE_TYPES.LabeledStatement) {
innerStatementNode = innerStatementNode.body;
}

Expand All @@ -240,8 +249,8 @@ const nodeMatchesType = (
* nodes
*/
const testPadding = (
prevNode: Node,
nextNode: Node,
prevNode: TSESTree.Node,
nextNode: TSESTree.Node,
paddingContext: PaddingContext,
): void => {
const { configs } = paddingContext;
Expand Down Expand Up @@ -272,7 +281,10 @@ const testPadding = (
/**
* Verify padding lines between the given node and the previous node.
*/
const verifyNode = (node: Node, paddingContext: PaddingContext): void => {
const verifyNode = (
node: TSESTree.Node,
paddingContext: PaddingContext,
): void => {
const { scopeInfo } = paddingContext;

// NOTE: ESLint types use ESTree which provides a Node type, however
Expand Down Expand Up @@ -370,8 +382,8 @@ export const createPaddingRule = (
'BlockStatement:exit': scopeInfo.exit,
SwitchStatement: scopeInfo.enter,
'SwitchStatement:exit': scopeInfo.exit,
':statement': (node: Node) => verifyNode(node, paddingContext),
SwitchCase(node: Node) {
':statement': (node: TSESTree.Node) => verifyNode(node, paddingContext),
SwitchCase(node: TSESTree.Node) {
verifyNode(node, paddingContext);
scopeInfo.enter();
},
Expand Down

0 comments on commit e8ea5eb

Please sign in to comment.