Skip to content

Commit 989b060

Browse files
committed
refactor(utilities/var): improve 'isInitializedFromSource' function readability
1 parent 6a90c19 commit 989b060

File tree

6 files changed

+36
-49
lines changed

6 files changed

+36
-49
lines changed

.github/CONTRIBUTING.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ Before submitting your contribution though, please make sure to take a moment an
5959
- `packages/plugins/eslint-plugin-react-x`: ESLint plugin for `"react"`.
6060
- `packages/plugins/eslint-plugin-react-dom`: ESLint plugin for `"react-dom"`.
6161
- `packages/plugins/eslint-plugin-react-web-api` - ESLint plugin for interacting with Web APIs
62-
- `packages/plugins/eslint-plugin-react-hooks-extra`:ESLint plugin for React Hooks related rules.
62+
- `packages/plugins/eslint-plugin-react-hooks-extra`: ESLint plugin for React Hooks related rules.
6363
- `packages/plugins/eslint-plugin-react-naming-convention`: ESLint plugin for React naming conventions.
6464
- `packages/plugins/eslint-plugin-react-debug`: ESLint plugin for debugging ESLint React rules.
6565
- `packages/plugins/eslint-plugin`: The main ESLint plugin of ESLint React. Contains all the rules from the above plugins.
6666
- `packages/utilities/eff`: A subset of effect to produce a more lightweight version of the library.
6767
- `packages/utilities/ast`: TSESTree AST utility module.
6868
- `packages/utilities/var`: TSESTree AST utility module for static analysis of variables
6969
- `packages/utilities/jsx`: TSESTree AST utility module for static analysis of JSX.
70-
- `packages/core`: ESLint React's ESLint utility module for static analysis of React core APIs and Patterns.
71-
- `packages/types`: ESLint React's type definitions.
72-
- `packages/shared`: ESLint React's Shared constants and functions.
70+
- `packages/core`: Utility module for static analysis of React core APIs and Patterns.
71+
- `packages/types`: Type definitions.
72+
- `packages/shared`: Shared constants and functions.
7373
- `website`: The documentation website for ESLint React.
7474

7575
### Developing Documentation

packages/utilities/var/src/get-variable-def.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

packages/utilities/var/src/get-variable-node.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { DefinitionType } from "@typescript-eslint/scope-manager";
55
import type { TSESTree } from "@typescript-eslint/types";
66
import { AST_NODE_TYPES } from "@typescript-eslint/types";
77

8-
import { getVariableDef } from "./get-variable-def";
9-
108
/**
119
* Get the init node of the nth definition of a variable
1210
* @param at The index number of def in defs
@@ -26,7 +24,7 @@ export function getVariableNode(at: number) {
2624
> => {
2725
return F.pipe(
2826
O.some(variable),
29-
O.flatMap(getVariableDef(at)),
27+
O.flatMapNullable(v => v.defs.at(at)),
3028
O.flatMapNullable(def => {
3129
switch (true) {
3230
case def.type === DefinitionType.FunctionName

packages/utilities/var/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export * from "./get-child-scopes";
44
export * from "./get-scope";
55
export * from "./get-static-value";
66
export * from "./get-variable-declarator-id";
7-
export * from "./get-variable-def";
87
export * from "./get-variable-node";
98
export * from "./get-variables";
109
export * from "./is-initialized-from-source";
Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { isString, O } from "@eslint-react/eff";
1+
import * as AST from "@eslint-react/ast";
2+
import { F, O } from "@eslint-react/eff";
23
import type { Scope } from "@typescript-eslint/scope-manager";
4+
import type { TSESTree } from "@typescript-eslint/types";
35
import { AST_NODE_TYPES } from "@typescript-eslint/types";
4-
import { isMatching, match } from "ts-pattern";
6+
import { isMatching } from "ts-pattern";
57

68
import { findVariable } from "./find-variable";
79

@@ -19,8 +21,7 @@ export function isInitializedFromSource(
1921
): boolean {
2022
const maybeLatestDef = O.flatMapNullable(findVariable(name, initialScope), (v) => v.defs.at(-1));
2123
if (O.isNone(maybeLatestDef)) return false;
22-
const latestDef = maybeLatestDef.value;
23-
const { node, parent } = latestDef;
24+
const { node, parent } = maybeLatestDef.value;
2425
if (node.type === AST_NODE_TYPES.VariableDeclarator && node.init) {
2526
const { init } = node;
2627
// check for: `variable = Source.variable`
@@ -31,28 +32,31 @@ export function isInitializedFromSource(
3132
if (init.type === AST_NODE_TYPES.Identifier) {
3233
return isInitializedFromSource(init.name, source, initialScope);
3334
}
34-
const maybeRequireExpression = match(init)
35-
.with({
36-
type: AST_NODE_TYPES.CallExpression,
37-
callee: { type: AST_NODE_TYPES.Identifier, name: "require" },
38-
}, (exp) => O.some(exp))
39-
.with(
40-
{
41-
type: AST_NODE_TYPES.MemberExpression,
42-
object: {
43-
type: AST_NODE_TYPES.CallExpression,
44-
callee: { type: AST_NODE_TYPES.Identifier, name: "require" },
45-
},
46-
},
47-
({ object }) => O.some(object),
48-
)
49-
.otherwise(O.none);
50-
if (O.isNone(maybeRequireExpression)) return false;
51-
const requireExpression = maybeRequireExpression.value;
52-
const [firstArg] = requireExpression.arguments;
53-
if (firstArg?.type !== AST_NODE_TYPES.Literal || !isString(firstArg.value)) return false;
54-
return firstArg.value === source || firstArg.value.startsWith(`${source}/`);
35+
// check for: `variable = require('source')` or `variable = require('source').variable`
36+
return F.pipe(
37+
getRequireExpressionArgument(init),
38+
O.flatMapNullable((args) => args[0]),
39+
O.filter(AST.isStringLiteral),
40+
// check for: `require('source')` or `require('source/...')`
41+
O.exists((arg) => arg.value === source || arg.value.startsWith(`${source}/`)),
42+
);
5543
}
5644
// latest definition is an import declaration: import { variable } from 'source'
5745
return isMatching({ type: "ImportDeclaration", source: { value: source } }, parent);
5846
}
47+
48+
function getRequireExpressionArgument(node: TSESTree.Node): O.Option<TSESTree.CallExpressionArgument[]> {
49+
switch (true) {
50+
// require('source')
51+
case node.type === AST_NODE_TYPES.CallExpression
52+
&& node.callee.type === AST_NODE_TYPES.Identifier
53+
&& node.callee.name === "require": {
54+
return O.some(node.arguments);
55+
}
56+
// require('source').variable
57+
case node.type === AST_NODE_TYPES.MemberExpression: {
58+
return getRequireExpressionArgument(node.object);
59+
}
60+
}
61+
return O.none();
62+
}

packages/utilities/var/src/is-node-value-equal.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { AST_NODE_TYPES } from "@typescript-eslint/types";
66

77
import { findVariable } from "./find-variable";
88
import { getStaticValue } from "./get-static-value";
9-
import { getVariableDef } from "./get-variable-def";
109
import { getVariableNode } from "./get-variable-node";
1110

1211
const thisBlockTypes = [
@@ -49,8 +48,8 @@ export function isNodeValueEqual(
4948
const bVarNode = O.flatMap(bVar, getVariableNode(0));
5049
const aVarNodeParent = O.flatMapNullable(aVarNode, (n) => n.parent);
5150
const bVarNodeParent = O.flatMapNullable(bVarNode, (n) => n.parent);
52-
const aDef = O.flatMap(aVar, getVariableDef(0));
53-
const bDef = O.flatMap(bVar, getVariableDef(0));
51+
const aDef = O.flatMapNullable(aVar, v => v.defs.at(0));
52+
const bDef = O.flatMapNullable(bVar, v => v.defs.at(0));
5453
const aDefParentParent = O.flatMapNullable(aDef, (d) => d.parent?.parent);
5554
const bDefParentParent = O.flatMapNullable(bDef, (d) => d.parent?.parent);
5655
switch (true) {

0 commit comments

Comments
 (0)