From bf91a01c09794756088663f1b61cfd56ddd5d1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Wed, 6 Oct 2021 01:31:18 +0200 Subject: [PATCH] feat(experimental-utils): extract `isTokenOfTypeWithConditions` out of `ast-utils`' `predicates` --- .../src/ast-utils/helpers.ts | 27 +++++++++++++++-- .../src/ast-utils/predicates.ts | 29 +++++++++---------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/packages/experimental-utils/src/ast-utils/helpers.ts b/packages/experimental-utils/src/ast-utils/helpers.ts index 5d917df603a..f2a4ac2e244 100644 --- a/packages/experimental-utils/src/ast-utils/helpers.ts +++ b/packages/experimental-utils/src/ast-utils/helpers.ts @@ -1,4 +1,7 @@ -import { AST_NODE_TYPES, TSESTree } from '../ts-estree'; +import { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from '../ts-estree'; + +type ObjectEntry = [keyof BaseType, BaseType[keyof BaseType]]; +type ObjectEntries = Array>; export const isNodeOfType = (nodeType: NodeType) => @@ -14,8 +17,6 @@ export const isNodeOfTypes = ): node is TSESTree.Node & { type: NodeTypes[number] } => !!node && nodeTypes.includes(node.type); -type ObjectEntry = [keyof BaseType, BaseType[keyof BaseType]]; -type ObjectEntries = Array>; export const isNodeOfTypeWithConditions = < NodeType extends AST_NODE_TYPES, Conditions extends Partial, @@ -35,3 +36,23 @@ export const isNodeOfTypeWithConditions = < node?.type === nodeType && entries.every(([key, value]) => node[key] === value); }; + +export const isTokenOfTypeWithConditions = < + TokenType extends AST_TOKEN_TYPES, + Conditions extends Partial, +>( + tokenType: TokenType, + conditions: Conditions, +): (( + token: TSESTree.Token | null | undefined, +) => token is TSESTree.Token & { type: TokenType } & Conditions) => { + const entries = Object.entries(conditions) as ObjectEntries< + TSESTree.Token & { type: TokenType } + >; + + return ( + token: TSESTree.Token | null | undefined, + ): token is TSESTree.Token & { type: TokenType } & Conditions => + token?.type === tokenType && + entries.every(([key, value]) => token[key] === value); +}; diff --git a/packages/experimental-utils/src/ast-utils/predicates.ts b/packages/experimental-utils/src/ast-utils/predicates.ts index 985c6e97623..0038f092bbe 100644 --- a/packages/experimental-utils/src/ast-utils/predicates.ts +++ b/packages/experimental-utils/src/ast-utils/predicates.ts @@ -4,13 +4,14 @@ import { isNodeOfType, isNodeOfTypes, isNodeOfTypeWithConditions, + isTokenOfTypeWithConditions, } from './helpers'; -function isOptionalChainPunctuator( - token: TSESTree.Token, -): token is TSESTree.PunctuatorToken & { value: '?.' } { - return token.type === AST_TOKEN_TYPES.Punctuator && token.value === '?.'; -} +const isOptionalChainPunctuator = isTokenOfTypeWithConditions( + AST_TOKEN_TYPES.Punctuator, + { value: '?.' }, +); + function isNotOptionalChainPunctuator( token: TSESTree.Token, ): token is Exclude< @@ -20,11 +21,11 @@ function isNotOptionalChainPunctuator( return !isOptionalChainPunctuator(token); } -function isNonNullAssertionPunctuator( - token: TSESTree.Token, -): token is TSESTree.PunctuatorToken & { value: '!' } { - return token.type === AST_TOKEN_TYPES.Punctuator && token.value === '!'; -} +const isNonNullAssertionPunctuator = isTokenOfTypeWithConditions( + AST_TOKEN_TYPES.Punctuator, + { value: '!' }, +); + function isNotNonNullAssertionPunctuator( token: TSESTree.Token, ): token is Exclude { @@ -138,11 +139,9 @@ const isAwaitExpression = isNodeOfType(AST_NODE_TYPES.AwaitExpression); /** * Checks if a possible token is the `await` keyword. */ -function isAwaitKeyword( - node: TSESTree.Token | undefined | null, -): node is TSESTree.IdentifierToken & { value: 'await' } { - return node?.type === AST_TOKEN_TYPES.Identifier && node.value === 'await'; -} +const isAwaitKeyword = isTokenOfTypeWithConditions(AST_TOKEN_TYPES.Identifier, { + value: 'await', +}); const isLoop = isNodeOfTypes([ AST_NODE_TYPES.DoWhileStatement,