Skip to content

Commit 0430b94

Browse files
committed
refactor: rename value construction to construction detection and update related types
1 parent 8d0cd1c commit 0430b94

File tree

8 files changed

+113
-109
lines changed

8 files changed

+113
-109
lines changed

packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
4040
const { version } = getSettingsFromContext(context);
4141
const isReact18OrBelow = compare(version, "19.0.0", "<");
4242
const { ctx, listeners } = ER.useComponentCollector(context);
43-
const constructions = new Map<AST.TSESTreeFunction, VAR.ValueConstruction[]>();
43+
const constructions = new Map<AST.TSESTreeFunction, VAR.Construction[]>();
4444

4545
return {
4646
...listeners,
@@ -62,7 +62,7 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
6262
if (value?.type !== T.JSXExpressionContainer) return;
6363
const valueExpression = value.expression;
6464
const initialScope = context.sourceCode.getScope(valueExpression);
65-
const construction = VAR.getValueConstruction(valueExpression, initialScope);
65+
const construction = VAR.getConstructionDetectionResult(valueExpression, initialScope);
6666
if (construction == null) return;
6767
if (ER.isReactHookCall(construction.node)) {
6868
return;

packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-default-props.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
7272
const { value } = prop;
7373
const { right } = value;
7474
const initialScope = context.sourceCode.getScope(value);
75-
const construction = VAR.getValueConstruction(
75+
const construction = VAR.getConstructionDetectionResult(
7676
value,
7777
initialScope,
78-
VAR.ValueConstructionHint.StrictCallExpression,
78+
VAR.ConstructionDetectionHint.StrictCallExpression,
7979
);
8080
if (construction == null) {
8181
continue;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type ConstructionDetectionHint = bigint;
2+
3+
export const ConstructionDetectionHint = {
4+
None: 0n,
5+
StrictCallExpression: 1n << 0n,
6+
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import type { Scope } from "@typescript-eslint/scope-manager";
2+
import type { TSESTree } from "@typescript-eslint/types";
3+
import type { Construction } from "./construction";
4+
import { _ } from "@eslint-react/eff";
5+
6+
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
7+
import { getVariableInitNode } from "../get-variable-init-node";
8+
import { ConstructionDetectionHint } from "./construction-detection-hint";
9+
10+
/**
11+
* Detects the construction type of a given node.
12+
* @param node The node to check.
13+
* @param initialScope The initial scope to check for variable declarations.
14+
* @param hint Optional hint to control the detection behavior.
15+
* @returns The construction type of the node, or `_` if not found.
16+
*/
17+
export function getConstructionDetectionResult(
18+
node: TSESTree.Node | _,
19+
initialScope: Scope,
20+
hint = ConstructionDetectionHint.None,
21+
): Construction | _ {
22+
if (node == null) return _;
23+
switch (node.type) {
24+
case T.JSXElement:
25+
case T.JSXFragment:
26+
return { kind: "JSXElement", node } as const;
27+
case T.ArrayExpression:
28+
return { kind: "ArrayExpression", node } as const;
29+
case T.ObjectExpression:
30+
return { kind: "ObjectExpression", node } as const;
31+
case T.ClassExpression:
32+
return { kind: "ClassExpression", node } as const;
33+
case T.NewExpression:
34+
return { kind: "NewExpression", node } as const;
35+
case T.FunctionExpression:
36+
case T.ArrowFunctionExpression:
37+
return { kind: "FunctionExpression", node } as const;
38+
case T.CallExpression: {
39+
if (hint & ConstructionDetectionHint.StrictCallExpression) {
40+
return { kind: "CallExpression", node } as const;
41+
}
42+
return _;
43+
}
44+
case T.MemberExpression: {
45+
if (!("object" in node)) return _;
46+
return getConstructionDetectionResult(node.object, initialScope, hint);
47+
}
48+
case T.AssignmentExpression:
49+
case T.AssignmentPattern: {
50+
if (!("right" in node)) return _;
51+
return getConstructionDetectionResult(node.right, initialScope, hint);
52+
}
53+
case T.LogicalExpression: {
54+
const lvc = getConstructionDetectionResult(node.left, initialScope, hint);
55+
if (lvc == null) return _;
56+
return getConstructionDetectionResult(node.right, initialScope, hint);
57+
}
58+
case T.ConditionalExpression: {
59+
const cvc = getConstructionDetectionResult(node.consequent, initialScope, hint);
60+
if (cvc == null) return _;
61+
return getConstructionDetectionResult(node.alternate, initialScope, hint);
62+
}
63+
case T.Identifier: {
64+
if (!("name" in node) || typeof node.name !== "string") {
65+
return _;
66+
}
67+
const variable = initialScope.set.get(node.name);
68+
const variableNode = getVariableInitNode(variable, -1);
69+
return getConstructionDetectionResult(variableNode, initialScope, hint);
70+
}
71+
case T.Literal: {
72+
if ("regex" in node) {
73+
return { kind: "RegExpLiteral", node } as const;
74+
}
75+
return _;
76+
}
77+
default: {
78+
if (!("expression" in node) || typeof node.expression !== "object") {
79+
return _;
80+
}
81+
return getConstructionDetectionResult(node.expression, initialScope, hint);
82+
}
83+
}
84+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { TSESTree } from "@typescript-eslint/types";
2+
3+
/**
4+
* Represents the construction type of a expression like node.
5+
*/
6+
export type Construction =
7+
| { kind: "ArrayExpression"; node: TSESTree.ArrayExpression }
8+
| { kind: "CallExpression"; node: TSESTree.CallExpression }
9+
| { kind: "ClassExpression"; node: TSESTree.ClassExpression }
10+
| { kind: "FunctionDeclaration"; node: TSESTree.FunctionDeclaration }
11+
| { kind: "FunctionExpression"; node: TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression }
12+
| { kind: "JSXElement"; node: TSESTree.JSXElement | TSESTree.JSXFragment }
13+
| { kind: "NewExpression"; node: TSESTree.NewExpression }
14+
| { kind: "ObjectExpression"; node: TSESTree.ObjectExpression }
15+
| { kind: "RegExpLiteral"; node: TSESTree.RegExpLiteral };
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type * from "./construction";
2+
export * from "./construction-detection";
3+
export * from "./construction-detection-hint";
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from "./construction";
12
export * from "./find-property-in-properties";
23
export * from "./find-variable";
34
export * from "./get-child-scopes";
@@ -6,4 +7,3 @@ export * from "./get-variable-init-node";
67
export * from "./get-variables";
78
export * from "./is-node-value-equal";
89
export * from "./lazy-value";
9-
export * from "./value-construction";

packages/utilities/var/src/value-construction.ts

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

0 commit comments

Comments
 (0)