Skip to content

Commit ae3eac7

Browse files
author
Thomas Lombart
authored
refactor(ast-utils): migrate custom node-utils to ASTUtils (#256)
Closes #253 * refactor(ast-utils): remove isIdentifier * refactor(ast-utils): migrate isAwaitExpression * refactor(ast-utils): use optional chaining for consistency
1 parent 6018dd1 commit ae3eac7

19 files changed

+155
-120
lines changed

lib/node-utils.ts

+17-28
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,13 @@ export function isCallExpression(
1515
export function isNewExpression(
1616
node: TSESTree.Node
1717
): node is TSESTree.NewExpression {
18-
return node && node.type === 'NewExpression';
19-
}
20-
21-
// TODO: remove this one and use ASTUtils one instead
22-
export function isIdentifier(node: TSESTree.Node): node is TSESTree.Identifier {
23-
return node && node.type === AST_NODE_TYPES.Identifier;
18+
return node?.type === 'NewExpression';
2419
}
2520

2621
export function isMemberExpression(
2722
node: TSESTree.Node
2823
): node is TSESTree.MemberExpression {
29-
return node && node.type === AST_NODE_TYPES.MemberExpression;
24+
return node?.type === AST_NODE_TYPES.MemberExpression;
3025
}
3126

3227
export function isLiteral(
@@ -38,7 +33,7 @@ export function isLiteral(
3833
export function isImportSpecifier(
3934
node: TSESTree.Node
4035
): node is TSESTree.ImportSpecifier {
41-
return node && node.type === AST_NODE_TYPES.ImportSpecifier;
36+
return node?.type === AST_NODE_TYPES.ImportSpecifier;
4237
}
4338

4439
export function isImportNamespaceSpecifier(
@@ -50,25 +45,25 @@ export function isImportNamespaceSpecifier(
5045
export function isImportDefaultSpecifier(
5146
node: TSESTree.Node
5247
): node is TSESTree.ImportDefaultSpecifier {
53-
return node && node.type === AST_NODE_TYPES.ImportDefaultSpecifier;
48+
return node?.type === AST_NODE_TYPES.ImportDefaultSpecifier;
5449
}
5550

5651
export function isBlockStatement(
5752
node: TSESTree.Node
5853
): node is TSESTree.BlockStatement {
59-
return node && node.type === AST_NODE_TYPES.BlockStatement;
54+
return node?.type === AST_NODE_TYPES.BlockStatement;
6055
}
6156

6257
export function isVariableDeclarator(
6358
node: TSESTree.Node
6459
): node is TSESTree.VariableDeclarator {
65-
return node && node.type === AST_NODE_TYPES.VariableDeclarator;
60+
return node?.type === AST_NODE_TYPES.VariableDeclarator;
6661
}
6762

6863
export function isObjectPattern(
6964
node: TSESTree.Node
7065
): node is TSESTree.ObjectPattern {
71-
return node && node.type === AST_NODE_TYPES.ObjectPattern;
66+
return node?.type === AST_NODE_TYPES.ObjectPattern;
7267
}
7368

7469
export function isProperty(
@@ -80,7 +75,7 @@ export function isProperty(
8075
export function isJSXAttribute(
8176
node: TSESTree.Node
8277
): node is TSESTree.JSXAttribute {
83-
return node && node.type === AST_NODE_TYPES.JSXAttribute;
78+
return node?.type === AST_NODE_TYPES.JSXAttribute;
8479
}
8580

8681
export function findClosestCallExpressionNode(
@@ -107,7 +102,7 @@ export function findClosestCallNode(
107102

108103
if (
109104
isCallExpression(node) &&
110-
isIdentifier(node.callee) &&
105+
ASTUtils.isIdentifier(node.callee) &&
111106
node.callee.name === name
112107
) {
113108
return node;
@@ -125,28 +120,21 @@ export function isObjectExpression(
125120
export function hasThenProperty(node: TSESTree.Node): boolean {
126121
return (
127122
isMemberExpression(node) &&
128-
isIdentifier(node.property) &&
123+
ASTUtils.isIdentifier(node.property) &&
129124
node.property.name === 'then'
130125
);
131126
}
132127

133-
// TODO: remove this one and use ASTUtils one instead
134-
export function isAwaitExpression(
135-
node: TSESTree.Node
136-
): node is TSESTree.AwaitExpression {
137-
return node && node.type === AST_NODE_TYPES.AwaitExpression;
138-
}
139-
140128
export function isArrowFunctionExpression(
141129
node: TSESTree.Node
142130
): node is TSESTree.ArrowFunctionExpression {
143-
return node && node.type === AST_NODE_TYPES.ArrowFunctionExpression;
131+
return node?.type === AST_NODE_TYPES.ArrowFunctionExpression;
144132
}
145133

146134
export function isReturnStatement(
147135
node: TSESTree.Node
148136
): node is TSESTree.ReturnStatement {
149-
return node && node.type === AST_NODE_TYPES.ReturnStatement;
137+
return node?.type === AST_NODE_TYPES.ReturnStatement;
150138
}
151139

152140
export function isArrayExpression(
@@ -163,7 +151,7 @@ export function isImportDeclaration(
163151

164152
export function isAwaited(node: TSESTree.Node): boolean {
165153
return (
166-
isAwaitExpression(node) ||
154+
ASTUtils.isAwaitExpression(node) ||
167155
isArrowFunctionExpression(node) ||
168156
isReturnStatement(node)
169157
);
@@ -200,9 +188,10 @@ export function isRenderFunction(
200188
// as well as `someLib.render` and `someUtils.customRenderFn`
201189
return renderFunctions.some((name) => {
202190
return (
203-
(isIdentifier(callNode.callee) && name === callNode.callee.name) ||
191+
(ASTUtils.isIdentifier(callNode.callee) &&
192+
name === callNode.callee.name) ||
204193
(isMemberExpression(callNode.callee) &&
205-
isIdentifier(callNode.callee.property) &&
194+
ASTUtils.isIdentifier(callNode.callee.property) &&
206195
name === callNode.callee.property.name)
207196
);
208197
});
@@ -213,7 +202,7 @@ export function isRenderVariableDeclarator(
213202
renderFunctions: string[]
214203
): boolean {
215204
if (node.init) {
216-
if (isAwaitExpression(node.init)) {
205+
if (ASTUtils.isAwaitExpression(node.init)) {
217206
return (
218207
node.init.argument &&
219208
isRenderFunction(

lib/rules/await-async-query.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ESLintUtils,
3+
TSESTree,
4+
ASTUtils,
5+
} from '@typescript-eslint/experimental-utils';
26
import { getDocsUrl, LIBRARY_MODULES } from '../utils';
37
import {
48
isCallExpression,
5-
isIdentifier,
69
isMemberExpression,
710
isAwaited,
811
isPromiseResolved,
@@ -23,13 +26,13 @@ function hasClosestExpectResolvesRejects(node: TSESTree.Node): boolean {
2326

2427
if (
2528
isCallExpression(node) &&
26-
isIdentifier(node.callee) &&
29+
ASTUtils.isIdentifier(node.callee) &&
2730
isMemberExpression(node.parent) &&
2831
node.callee.name === 'expect'
2932
) {
3033
const expectMatcher = node.parent.property;
3134
return (
32-
isIdentifier(expectMatcher) &&
35+
ASTUtils.isIdentifier(expectMatcher) &&
3336
(expectMatcher.name === 'resolves' || expectMatcher.name === 'rejects')
3437
);
3538
} else {

lib/rules/await-async-utils.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ESLintUtils,
3+
TSESTree,
4+
ASTUtils,
5+
} from '@typescript-eslint/experimental-utils';
26

37
import { getDocsUrl, ASYNC_UTILS, LIBRARY_MODULES } from '../utils';
48
import {
@@ -10,7 +14,6 @@ import {
1014
isImportNamespaceSpecifier,
1115
isCallExpression,
1216
isArrayExpression,
13-
isIdentifier,
1417
} from '../node-utils';
1518

1619
export const RULE_NAME = 'await-async-utils';
@@ -23,9 +26,9 @@ const ASYNC_UTILS_REGEXP = new RegExp(`^(${ASYNC_UTILS.join('|')})$`);
2326
function isPromiseAll(node: TSESTree.CallExpression) {
2427
return (
2528
isMemberExpression(node.callee) &&
26-
isIdentifier(node.callee.object) &&
29+
ASTUtils.isIdentifier(node.callee.object) &&
2730
node.callee.object.name === 'Promise' &&
28-
isIdentifier(node.callee.property) &&
31+
ASTUtils.isIdentifier(node.callee.property) &&
2932
node.callee.property.name === 'all'
3033
);
3134
}

lib/rules/await-fire-event.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ESLintUtils,
3+
TSESTree,
4+
ASTUtils,
5+
} from '@typescript-eslint/experimental-utils';
26
import { getDocsUrl } from '../utils';
3-
import { isIdentifier, isAwaited, isPromiseResolved } from '../node-utils';
7+
import { isAwaited, isPromiseResolved } from '../node-utils';
48

59
export const RULE_NAME = 'await-fire-event';
610
export type MessageIds = 'awaitFireEvent';
@@ -31,7 +35,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
3135
const fireEventMethodNode = memberExpression.property;
3236

3337
if (
34-
isIdentifier(fireEventMethodNode) &&
38+
ASTUtils.isIdentifier(fireEventMethodNode) &&
3539
!isAwaited(node.parent.parent.parent) &&
3640
!isPromiseResolved(fireEventMethodNode.parent)
3741
) {

lib/rules/no-await-sync-events.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ASTUtils,
3+
ESLintUtils,
4+
TSESTree,
5+
} from '@typescript-eslint/experimental-utils';
26
import { getDocsUrl, SYNC_EVENTS } from '../utils';
3-
import { isObjectExpression, isProperty, isIdentifier } from '../node-utils';
7+
import { isObjectExpression, isProperty } from '../node-utils';
48
export const RULE_NAME = 'no-await-sync-events';
59
export type MessageIds = 'noAwaitSyncEvents';
610
type Options = [];
@@ -41,7 +45,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
4145
callExpression.arguments[2].properties.some(
4246
(property) =>
4347
isProperty(property) &&
44-
isIdentifier(property.key) &&
48+
ASTUtils.isIdentifier(property.key) &&
4549
property.key.name === 'delay'
4650
);
4751

lib/rules/no-container.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ESLintUtils,
3+
TSESTree,
4+
ASTUtils,
5+
} from '@typescript-eslint/experimental-utils';
26
import { getDocsUrl } from '../utils';
37
import {
4-
isIdentifier,
58
isMemberExpression,
69
isObjectPattern,
710
isProperty,
@@ -54,12 +57,12 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
5457
innerNode: TSESTree.MemberExpression
5558
) {
5659
if (isMemberExpression(innerNode)) {
57-
if (isIdentifier(innerNode.object)) {
60+
if (ASTUtils.isIdentifier(innerNode.object)) {
5861
const isContainerName = innerNode.object.name === containerName;
5962
const isRenderWrapper = innerNode.object.name === renderWrapperName;
6063

6164
containerCallsMethod =
62-
isIdentifier(innerNode.property) &&
65+
ASTUtils.isIdentifier(innerNode.property) &&
6366
innerNode.property.name === 'container' &&
6467
isRenderWrapper;
6568

@@ -83,24 +86,24 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
8386
const containerIndex = node.id.properties.findIndex(
8487
(property) =>
8588
isProperty(property) &&
86-
isIdentifier(property.key) &&
89+
ASTUtils.isIdentifier(property.key) &&
8790
property.key.name === 'container'
8891
);
8992
const nodeValue =
9093
containerIndex !== -1 && node.id.properties[containerIndex].value;
91-
if (isIdentifier(nodeValue)) {
94+
if (ASTUtils.isIdentifier(nodeValue)) {
9295
containerName = nodeValue.name;
9396
} else {
9497
isObjectPattern(nodeValue) &&
9598
nodeValue.properties.forEach(
9699
(property) =>
97100
isProperty(property) &&
98-
isIdentifier(property.key) &&
101+
ASTUtils.isIdentifier(property.key) &&
99102
destructuredContainerPropNames.push(property.key.name)
100103
);
101104
}
102105
} else {
103-
renderWrapperName = isIdentifier(node.id) && node.id.name;
106+
renderWrapperName = ASTUtils.isIdentifier(node.id) && node.id.name;
104107
}
105108
}
106109
},
@@ -109,7 +112,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
109112
if (isMemberExpression(node.callee)) {
110113
showErrorIfChainedContainerMethod(node.callee);
111114
} else {
112-
isIdentifier(node.callee) &&
115+
ASTUtils.isIdentifier(node.callee) &&
113116
destructuredContainerPropNames.includes(node.callee.name) &&
114117
context.report({
115118
node,

lib/rules/no-debug.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ESLintUtils,
3+
TSESTree,
4+
ASTUtils,
5+
} from '@typescript-eslint/experimental-utils';
26
import {
37
getDocsUrl,
48
LIBRARY_MODULES,
@@ -7,7 +11,6 @@ import {
711
import {
812
isObjectPattern,
913
isProperty,
10-
isIdentifier,
1114
isCallExpression,
1215
isLiteral,
1316
isMemberExpression,
@@ -66,7 +69,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
6669
node.id.properties.some(
6770
(property) =>
6871
isProperty(property) &&
69-
isIdentifier(property.key) &&
72+
ASTUtils.isIdentifier(property.key) &&
7073
property.key.name === 'debug'
7174
)
7275
) {
@@ -102,7 +105,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
102105
declaratorNode.id.properties.some(
103106
(property) =>
104107
isProperty(property) &&
105-
isIdentifier(property.key) &&
108+
ASTUtils.isIdentifier(property.key) &&
106109
property.key.name === 'screen'
107110
);
108111
},
@@ -179,7 +182,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
179182
const parent = ref.identifier.parent;
180183
if (
181184
isMemberExpression(parent) &&
182-
isIdentifier(parent.property) &&
185+
ASTUtils.isIdentifier(parent.property) &&
183186
parent.property.name === 'debug' &&
184187
isCallExpression(parent.parent)
185188
) {

lib/rules/no-multiple-assertions-wait-for.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
1+
import {
2+
ESLintUtils,
3+
TSESTree,
4+
ASTUtils,
5+
} from '@typescript-eslint/experimental-utils';
26
import { getDocsUrl } from '../utils';
37
import {
48
isBlockStatement,
59
isMemberExpression,
610
isCallExpression,
7-
isIdentifier,
811
} from '../node-utils';
912

1013
export const RULE_NAME = 'no-multiple-assertions-wait-for';
@@ -42,7 +45,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
4245
const object: TSESTree.CallExpression =
4346
node.expression.callee.object;
4447
const expressionName: string =
45-
isIdentifier(object.callee) && object.callee.name;
48+
ASTUtils.isIdentifier(object.callee) && object.callee.name;
4649
return expressionName === 'expect';
4750
} else {
4851
return false;

lib/rules/no-node-access.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { TSESTree } from '@typescript-eslint/experimental-utils';
1+
import { TSESTree, ASTUtils } from '@typescript-eslint/experimental-utils';
22
import { ALL_RETURNING_NODES } from '../utils';
3-
import { isIdentifier } from '../node-utils';
43
import { createTestingLibraryRule } from '../create-testing-library-rule';
54

65
export const RULE_NAME = 'no-node-access';
@@ -27,7 +26,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
2726

2827
create(context) {
2928
function showErrorForNodeAccess(node: TSESTree.MemberExpression) {
30-
isIdentifier(node.property) &&
29+
ASTUtils.isIdentifier(node.property) &&
3130
ALL_RETURNING_NODES.includes(node.property.name) &&
3231
context.report({
3332
node: node,

0 commit comments

Comments
 (0)