@eslint-react/var 3.0.0-next.6 → 3.0.0-next.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +31 -79
  2. package/dist/index.js +116 -225
  3. package/package.json +6 -6
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { TSESTree } from "@typescript-eslint/types";
3
3
  import { Scope, Variable } from "@typescript-eslint/scope-manager";
4
4
  import { RuleContext } from "@eslint-react/shared";
5
5
 
6
- //#region src/var-assignment-target.d.ts
6
+ //#region src/find-enclosing-assignment-target.d.ts
7
7
  /**
8
8
  * Finds the enclosing assignment target (variable, property, etc.) for a given node
9
9
  *
@@ -16,54 +16,23 @@ declare function findEnclosingAssignmentTarget(node: TSESTree.Node): TSESTree.Ar
16
16
  * Type representing the possible assignment targets returned by `findEnclosingAssignmentTarget`
17
17
  */
18
18
  type AssignmentTarget = ReturnType<typeof findEnclosingAssignmentTarget>;
19
- /**
20
- * Check if two assignment targets are equal
21
- * Compares nodes directly or by their values
22
- * @param context The rule context
23
- * @param a The first node to compare
24
- * @param b The second node to compare
25
- * @returns True if the assignment targets are equal
26
- * @internal
27
- */
28
- declare function isAssignmentTargetEqual(context: RuleContext, a: TSESTree.Node, b: TSESTree.Node): boolean;
29
- //#endregion
30
- //#region src/var-definition.d.ts
31
- /**
32
- * Get the definition node of a variable at a specific definition index
33
- * @param variable The variable to get the definition node from
34
- * @param at The index of the definition to retrieve (negative index supported)
35
- * @returns The definition node or unit if not found
36
- */
37
- declare function getVariableDefinitionNode(variable: Variable | unit, at: number): unit | TSESTree.ClassDeclaration | TSESTree.ClassDeclarationWithName | TSESTree.ClassDeclarationWithOptionalName | TSESTree.Expression | TSESTree.FunctionDeclaration | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName;
38
- /**
39
- * Get the definition node of a variable at a specific definition index (loose version)
40
- * Also returns the function node if the definition is a parameter
41
- * @param variable The variable to get the definition node from
42
- * @param at The index of the definition to retrieve
43
- * @returns The definition node or unit if not found
44
- */
45
- declare function getVariableDefinitionNodeLoose(variable: Variable | unit, at: number): unit | TSESTree.ClassDeclaration | TSESTree.ClassDeclarationWithName | TSESTree.ClassDeclarationWithOptionalName | TSESTree.Expression | TSESTree.FunctionDeclaration | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName;
46
19
  //#endregion
47
- //#region src/var-import-source.d.ts
20
+ //#region src/find-variable.d.ts
48
21
  /**
49
- * Find the import source of a variable
50
- * @param name The variable name
51
- * @param initialScope The initial scope to search
52
- * @returns The import source or undefined if not found
53
- */
54
- declare function findImportSource(name: string, initialScope: Scope): string | undefined;
55
- //#endregion
56
- //#region src/var-node-equality.d.ts
57
- /**
58
- * Determine whether node value equals to another node value
59
- * @param a node to compare
60
- * @param b node to compare
61
- * @param initialScopes initial scopes of the two nodes
62
- * @returns `true` if node value equal
22
+ * Find a variable by name or identifier node in the scope chain
23
+ * @param initialScope The scope to start searching from
24
+ * @returns The found variable or unit if not found
25
+ * @overload
26
+ * @param nameOrNode The variable name or identifier node to find
27
+ * @param initialScope The scope to start searching from
28
+ * @returns The found variable or unit if not found
63
29
  */
64
- declare function isNodeEqual(a: TSESTree.Node, b: TSESTree.Node, initialScopes: [aScope: Scope, bScope: Scope]): boolean;
30
+ declare const findVariable: {
31
+ (initialScope: Scope): (nameOrNode: string | TSESTree.Identifier | unit) => Variable | unit;
32
+ (nameOrNode: string | TSESTree.Identifier | unit, initialScope: Scope): Variable | unit;
33
+ };
65
34
  //#endregion
66
- //#region src/var-object-type.d.ts
35
+ //#region src/get-object-type.d.ts
67
36
  /**
68
37
  * Represents the type classification of an object node
69
38
  */
@@ -101,43 +70,26 @@ type ObjectType = {
101
70
  */
102
71
  declare function getObjectType(node: TSESTree.Node | unit, initialScope: Scope): ObjectType | unit;
103
72
  //#endregion
104
- //#region src/var-property.d.ts
73
+ //#region src/is-assignment-target-equal.d.ts
105
74
  /**
106
- * Find a property by name in an array of properties
107
- * Handles spread elements by recursively resolving the referenced object
108
- * @param name The property name to find
109
- * @param properties The array of properties to search
110
- * @param initialScope The scope to use for variable resolution
111
- * @param seen Set of already seen variable names to prevent circular references
112
- * @returns The found property or unit if not found
75
+ * Check if two assignment targets are equal
76
+ * Compares nodes directly or by their values
77
+ * @param context The rule context
78
+ * @param a The first node to compare
79
+ * @param b The second node to compare
80
+ * @returns True if the assignment targets are equal
81
+ * @internal
113
82
  */
114
- declare function findProperty(name: string, properties: (TSESTree.Property | TSESTree.RestElement | TSESTree.SpreadElement)[], initialScope: Scope, seen?: Set<string>): (typeof properties)[number] | unit;
83
+ declare function isAssignmentTargetEqual(context: RuleContext, a: TSESTree.Node, b: TSESTree.Node): boolean;
115
84
  //#endregion
116
- //#region src/var-scope.d.ts
117
- /**
118
- * Get all variables from the given scope up to the global scope
119
- * @param initialScope The scope to start from
120
- * @returns All variables from the given scope up to the global scope
121
- */
122
- declare function getVariables(initialScope: Scope): Variable[];
85
+ //#region src/is-value-equal.d.ts
123
86
  /**
124
- * Find a variable by name or identifier node in the scope chain
125
- * @param initialScope The scope to start searching from
126
- * @returns The found variable or unit if not found
127
- * @overload
128
- * @param nameOrNode The variable name or identifier node to find
129
- * @param initialScope The scope to start searching from
130
- * @returns The found variable or unit if not found
131
- */
132
- declare const findVariable: {
133
- (initialScope: Scope): (nameOrNode: string | TSESTree.Identifier | unit) => Variable | unit;
134
- (nameOrNode: string | TSESTree.Identifier | unit, initialScope: Scope): Variable | unit;
135
- };
136
- /**
137
- * Get all child scopes recursively from a given scope
138
- * @param scope The scope to get child scopes from
139
- * @returns Array of all child scopes including the input scope
87
+ * Determine whether node value equals to another node value
88
+ * @param a node to compare
89
+ * @param b node to compare
90
+ * @param initialScopes initial scopes of the two nodes
91
+ * @returns `true` if node value equal
140
92
  */
141
- declare function getChildScopes(scope: Scope): readonly Scope[];
93
+ declare function isValueEqual(a: TSESTree.Node, b: TSESTree.Node, initialScopes: [aScope: Scope, bScope: Scope]): boolean;
142
94
  //#endregion
143
- export { AssignmentTarget, ObjectType, findEnclosingAssignmentTarget, findImportSource, findProperty, findVariable, getChildScopes, getObjectType, getVariableDefinitionNode, getVariableDefinitionNodeLoose, getVariables, isAssignmentTargetEqual, isNodeEqual };
95
+ export { AssignmentTarget, ObjectType, findEnclosingAssignmentTarget, findVariable, getObjectType, isAssignmentTargetEqual, isValueEqual };
package/dist/index.js CHANGED
@@ -1,154 +1,11 @@
1
- import * as ast from "@eslint-react/ast";
2
- import { dual, identity, unit } from "@eslint-react/eff";
1
+ import { dual, unit } from "@eslint-react/eff";
3
2
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
4
3
  import * as astUtils from "@typescript-eslint/utils/ast-utils";
5
4
  import { getStaticValue } from "@typescript-eslint/utils/ast-utils";
6
- import { DefinitionType, ScopeType } from "@typescript-eslint/scope-manager";
7
- import { P, match } from "ts-pattern";
8
-
9
- //#region src/var-definition.ts
10
- /**
11
- * Get the definition node of a variable at a specific definition index
12
- * @param variable The variable to get the definition node from
13
- * @param at The index of the definition to retrieve (negative index supported)
14
- * @returns The definition node or unit if not found
15
- */
16
- function getVariableDefinitionNode(variable, at) {
17
- if (variable == null) return unit;
18
- const def = variable.defs.at(at);
19
- if (def == null) return unit;
20
- switch (true) {
21
- case def.type === DefinitionType.FunctionName && def.node.type === AST_NODE_TYPES.FunctionDeclaration: return def.node;
22
- case def.type === DefinitionType.ClassName && def.node.type === AST_NODE_TYPES.ClassDeclaration: return def.node;
23
- case "init" in def.node && def.node.init != null && !("declarations" in def.node.init): return def.node.init;
24
- default: return unit;
25
- }
26
- }
27
- /**
28
- * Get the definition node of a variable at a specific definition index (loose version)
29
- * Also returns the function node if the definition is a parameter
30
- * @param variable The variable to get the definition node from
31
- * @param at The index of the definition to retrieve
32
- * @returns The definition node or unit if not found
33
- */
34
- function getVariableDefinitionNodeLoose(variable, at) {
35
- if (variable == null) return unit;
36
- const node = getVariableDefinitionNode(variable, at);
37
- if (node != null) return node;
38
- const def = variable.defs.at(at);
39
- if (def?.type === DefinitionType.Parameter && ast.isFunction(def.node)) return def.node;
40
- return unit;
41
- }
42
-
43
- //#endregion
44
- //#region src/var-scope.ts
45
- /**
46
- * Get all variables from the given scope up to the global scope
47
- * @param initialScope The scope to start from
48
- * @returns All variables from the given scope up to the global scope
49
- */
50
- function getVariables(initialScope) {
51
- let scope = initialScope;
52
- const variables = [...scope.variables];
53
- while (scope.type !== ScopeType.global) {
54
- scope = scope.upper;
55
- variables.push(...scope.variables);
56
- }
57
- return variables.reverse();
58
- }
59
- /**
60
- * Find a variable by name or identifier node in the scope chain
61
- * @param initialScope The scope to start searching from
62
- * @returns The found variable or unit if not found
63
- * @overload
64
- * @param nameOrNode The variable name or identifier node to find
65
- * @param initialScope The scope to start searching from
66
- * @returns The found variable or unit if not found
67
- */
68
- const findVariable = dual(2, (nameOrNode, initialScope) => {
69
- if (nameOrNode == null) return unit;
70
- return astUtils.findVariable(initialScope, nameOrNode) ?? unit;
71
- });
72
- /**
73
- * Get all child scopes recursively from a given scope
74
- * @param scope The scope to get child scopes from
75
- * @returns Array of all child scopes including the input scope
76
- */
77
- function getChildScopes(scope) {
78
- const scopes = [scope];
79
- for (const childScope of scope.childScopes) scopes.push(...getChildScopes(childScope));
80
- return scopes;
81
- }
82
-
83
- //#endregion
84
- //#region src/var-node-equality.ts
85
- const thisBlockTypes = [
86
- AST_NODE_TYPES.FunctionDeclaration,
87
- AST_NODE_TYPES.FunctionExpression,
88
- AST_NODE_TYPES.ClassBody,
89
- AST_NODE_TYPES.Program
90
- ];
91
- /**
92
- * Determine whether node value equals to another node value
93
- * @param a node to compare
94
- * @param b node to compare
95
- * @param initialScopes initial scopes of the two nodes
96
- * @returns `true` if node value equal
97
- */
98
- function isNodeEqual(a, b, initialScopes) {
99
- a = ast.isTypeExpression(a) ? ast.getUnderlyingExpression(a) : a;
100
- b = ast.isTypeExpression(b) ? ast.getUnderlyingExpression(b) : b;
101
- const [aScope, bScope] = initialScopes;
102
- switch (true) {
103
- case a === b: return true;
104
- case a.type === AST_NODE_TYPES.Literal && b.type === AST_NODE_TYPES.Literal: return a.value === b.value;
105
- case a.type === AST_NODE_TYPES.TemplateElement && b.type === AST_NODE_TYPES.TemplateElement: return a.value.cooked === b.value.cooked;
106
- case a.type === AST_NODE_TYPES.Identifier && b.type === AST_NODE_TYPES.Identifier: {
107
- const aVar = findVariable(a, aScope);
108
- const bVar = findVariable(b, bScope);
109
- const aVarNode = getVariableDefinitionNodeLoose(aVar, 0);
110
- const bVarNode = getVariableDefinitionNodeLoose(bVar, 0);
111
- const aVarNodeParent = aVarNode?.parent;
112
- const bVarNodeParent = bVarNode?.parent;
113
- const aDef = aVar?.defs.at(0);
114
- const bDef = bVar?.defs.at(0);
115
- const aDefParentParent = aDef?.parent?.parent;
116
- const bDefParentParent = bDef?.parent?.parent;
117
- switch (true) {
118
- case aVarNodeParent?.type === AST_NODE_TYPES.CallExpression && bVarNodeParent?.type === AST_NODE_TYPES.CallExpression && ast.isFunction(aVarNode) && ast.isFunction(bVarNode): {
119
- if (!ast.isNodeEqual(aVarNodeParent.callee, bVarNodeParent.callee)) return false;
120
- const aParams = aVarNode.params;
121
- const bParams = bVarNode.params;
122
- const aPos = aParams.findIndex((x) => ast.isNodeEqual(x, a));
123
- const bPos = bParams.findIndex((x) => ast.isNodeEqual(x, b));
124
- return aPos !== -1 && bPos !== -1 && aPos === bPos;
125
- }
126
- case aDefParentParent?.type === AST_NODE_TYPES.ForOfStatement && bDefParentParent?.type === AST_NODE_TYPES.ForOfStatement: {
127
- const aLeft = aDefParentParent.left;
128
- const bLeft = bDefParentParent.left;
129
- if (aLeft.type !== bLeft.type) return false;
130
- const aRight = aDefParentParent.right;
131
- const bRight = bDefParentParent.right;
132
- return ast.isNodeEqual(aRight, bRight);
133
- }
134
- default: return aVar != null && bVar != null && aVar === bVar;
135
- }
136
- }
137
- case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return ast.isNodeEqual(a.property, b.property) && isNodeEqual(a.object, b.object, initialScopes);
138
- case a.type === AST_NODE_TYPES.ThisExpression && b.type === AST_NODE_TYPES.ThisExpression:
139
- if (aScope.block === bScope.block) return true;
140
- return ast.findParentNode(a, ast.isOneOf(thisBlockTypes)) === ast.findParentNode(b, ast.isOneOf(thisBlockTypes));
141
- default: {
142
- const aStatic = getStaticValue(a, aScope);
143
- const bStatic = getStaticValue(b, bScope);
144
- return aStatic != null && bStatic != null && aStatic.value === bStatic.value;
145
- }
146
- }
147
- }
5
+ import { DefinitionType } from "@typescript-eslint/scope-manager";
6
+ import * as ast from "@eslint-react/ast";
148
7
 
149
- //#endregion
150
- //#region src/var-assignment-target.ts
151
- /** eslint-disable jsdoc/require-param */
8
+ //#region src/find-enclosing-assignment-target.ts
152
9
  /**
153
10
  * Finds the enclosing assignment target (variable, property, etc.) for a given node
154
11
  *
@@ -165,63 +22,25 @@ function findEnclosingAssignmentTarget(node) {
165
22
  default: return findEnclosingAssignmentTarget(node.parent);
166
23
  }
167
24
  }
168
- /**
169
- * Check if two assignment targets are equal
170
- * Compares nodes directly or by their values
171
- * @param context The rule context
172
- * @param a The first node to compare
173
- * @param b The second node to compare
174
- * @returns True if the assignment targets are equal
175
- * @internal
176
- */
177
- function isAssignmentTargetEqual(context, a, b) {
178
- return ast.isNodeEqual(a, b) || isNodeEqual(a, b, [context.sourceCode.getScope(a), context.sourceCode.getScope(b)]);
179
- }
180
25
 
181
26
  //#endregion
182
- //#region src/var-import-source.ts
27
+ //#region src/find-variable.ts
183
28
  /**
184
- * Get the arguments of a require expression
185
- * @param node The node to match
186
- * @returns The require expression arguments or undefined if the node is not a require expression
187
- */
188
- function getRequireExpressionArguments(node) {
189
- return match(node).with({
190
- type: AST_NODE_TYPES.CallExpression,
191
- arguments: P.select(),
192
- callee: {
193
- type: AST_NODE_TYPES.Identifier,
194
- name: "require"
195
- }
196
- }, identity).with({
197
- type: AST_NODE_TYPES.MemberExpression,
198
- object: P.select()
199
- }, getRequireExpressionArguments).otherwise(() => null);
200
- }
201
- /**
202
- * Find the import source of a variable
203
- * @param name The variable name
204
- * @param initialScope The initial scope to search
205
- * @returns The import source or undefined if not found
29
+ * Find a variable by name or identifier node in the scope chain
30
+ * @param initialScope The scope to start searching from
31
+ * @returns The found variable or unit if not found
32
+ * @overload
33
+ * @param nameOrNode The variable name or identifier node to find
34
+ * @param initialScope The scope to start searching from
35
+ * @returns The found variable or unit if not found
206
36
  */
207
- function findImportSource(name, initialScope) {
208
- const latestDef = findVariable(name, initialScope)?.defs.at(-1);
209
- if (latestDef == null) return unit;
210
- const { node, parent } = latestDef;
211
- if (node.type === AST_NODE_TYPES.VariableDeclarator && node.init != null) {
212
- const { init } = node;
213
- if (init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier) return findImportSource(init.object.name, initialScope);
214
- if (init.type === AST_NODE_TYPES.Identifier) return findImportSource(init.name, initialScope);
215
- const arg0 = getRequireExpressionArguments(init)?.[0];
216
- if (arg0 == null || !ast.isLiteral(arg0, "string")) return unit;
217
- return arg0.value;
218
- }
219
- if (parent?.type === AST_NODE_TYPES.ImportDeclaration) return parent.source.value;
220
- return unit;
221
- }
37
+ const findVariable = dual(2, (nameOrNode, initialScope) => {
38
+ if (nameOrNode == null) return unit;
39
+ return astUtils.findVariable(initialScope, nameOrNode) ?? unit;
40
+ });
222
41
 
223
42
  //#endregion
224
- //#region src/var-object-type.ts
43
+ //#region src/get-object-type.ts
225
44
  /**
226
45
  * Detect the ObjectType of a given node
227
46
  * @param node The node to check
@@ -265,9 +84,20 @@ function getObjectType(node, initialScope) {
265
84
  node
266
85
  };
267
86
  return unit;
268
- case AST_NODE_TYPES.Identifier:
269
- if (!("name" in node) || typeof node.name !== "string") return unit;
270
- return getObjectType(getVariableDefinitionNode(initialScope.set.get(node.name), -1), initialScope);
87
+ case AST_NODE_TYPES.Identifier: {
88
+ function resolve(v) {
89
+ if (v == null) return unit;
90
+ const def = v.defs.at(-1);
91
+ if (def == null) return unit;
92
+ if (def.type === DefinitionType.Variable) return def.node.init;
93
+ if (def.type === DefinitionType.Parameter) return unit;
94
+ if (def.type === DefinitionType.ImportBinding) return unit;
95
+ return def.node;
96
+ }
97
+ const initNode = resolve(initialScope.set.get(node.name));
98
+ if (initNode == null) return unit;
99
+ return getObjectType(initNode, initialScope);
100
+ }
271
101
  case AST_NODE_TYPES.MemberExpression:
272
102
  if (!("object" in node)) return unit;
273
103
  return getObjectType(node.object, initialScope);
@@ -292,35 +122,96 @@ function getObjectType(node, initialScope) {
292
122
  }
293
123
 
294
124
  //#endregion
295
- //#region src/var-property.ts
125
+ //#region src/is-value-equal.ts
126
+ const thisBlockTypes = [
127
+ AST_NODE_TYPES.FunctionDeclaration,
128
+ AST_NODE_TYPES.FunctionExpression,
129
+ AST_NODE_TYPES.ClassBody,
130
+ AST_NODE_TYPES.Program
131
+ ];
296
132
  /**
297
- * Find a property by name in an array of properties
298
- * Handles spread elements by recursively resolving the referenced object
299
- * @param name The property name to find
300
- * @param properties The array of properties to search
301
- * @param initialScope The scope to use for variable resolution
302
- * @param seen Set of already seen variable names to prevent circular references
303
- * @returns The found property or unit if not found
133
+ * Determine whether node value equals to another node value
134
+ * @param a node to compare
135
+ * @param b node to compare
136
+ * @param initialScopes initial scopes of the two nodes
137
+ * @returns `true` if node value equal
304
138
  */
305
- function findProperty(name, properties, initialScope, seen = /* @__PURE__ */ new Set()) {
306
- return properties.findLast((prop) => {
307
- if (prop.type === AST_NODE_TYPES.Property) return "name" in prop.key && prop.key.name === name;
308
- if (prop.type === AST_NODE_TYPES.SpreadElement) switch (prop.argument.type) {
309
- case AST_NODE_TYPES.Identifier: {
310
- if (seen.has(prop.argument.name)) return false;
311
- const variableNode = getVariableDefinitionNode(findVariable(prop.argument.name, initialScope), 0);
312
- if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) {
313
- seen.add(prop.argument.name);
314
- return findProperty(name, variableNode.properties, initialScope, seen) != null;
139
+ function isValueEqual(a, b, initialScopes) {
140
+ a = ast.isTypeExpression(a) ? ast.getUnderlyingExpression(a) : a;
141
+ b = ast.isTypeExpression(b) ? ast.getUnderlyingExpression(b) : b;
142
+ const [aScope, bScope] = initialScopes;
143
+ switch (true) {
144
+ case a === b: return true;
145
+ case a.type === AST_NODE_TYPES.Literal && b.type === AST_NODE_TYPES.Literal: return a.value === b.value;
146
+ case a.type === AST_NODE_TYPES.TemplateElement && b.type === AST_NODE_TYPES.TemplateElement: return a.value.cooked === b.value.cooked;
147
+ case a.type === AST_NODE_TYPES.Identifier && b.type === AST_NODE_TYPES.Identifier: {
148
+ const aVar = findVariable(a, aScope);
149
+ const bVar = findVariable(b, bScope);
150
+ const resolve = (variable) => {
151
+ if (variable == null) return unit;
152
+ const def = variable.defs.at(0);
153
+ if (def != null) switch (true) {
154
+ case def.type === DefinitionType.FunctionName && def.node.type === AST_NODE_TYPES.FunctionDeclaration: return def.node;
155
+ case def.type === DefinitionType.ClassName && def.node.type === AST_NODE_TYPES.ClassDeclaration: return def.node;
156
+ case "init" in def.node && def.node.init != null && !("declarations" in def.node.init): return def.node.init;
315
157
  }
316
- return false;
158
+ if (def?.type === DefinitionType.Parameter && ast.isFunction(def.node)) return def.node;
159
+ return unit;
160
+ };
161
+ const aVarInit = resolve(aVar);
162
+ const bVarInit = resolve(bVar);
163
+ const aVarInitParent = aVarInit?.parent;
164
+ const bVarInitParent = bVarInit?.parent;
165
+ const aDef = aVar?.defs.at(0);
166
+ const bDef = bVar?.defs.at(0);
167
+ const aDefParentParent = aDef?.parent?.parent;
168
+ const bDefParentParent = bDef?.parent?.parent;
169
+ switch (true) {
170
+ case aVarInitParent?.type === AST_NODE_TYPES.CallExpression && bVarInitParent?.type === AST_NODE_TYPES.CallExpression && ast.isFunction(aVarInit) && ast.isFunction(bVarInit): {
171
+ if (!ast.isNodeEqual(aVarInitParent.callee, bVarInitParent.callee)) return false;
172
+ const aParams = aVarInit.params;
173
+ const bParams = bVarInit.params;
174
+ const aPos = aParams.findIndex((x) => ast.isNodeEqual(x, a));
175
+ const bPos = bParams.findIndex((x) => ast.isNodeEqual(x, b));
176
+ return aPos !== -1 && bPos !== -1 && aPos === bPos;
177
+ }
178
+ case aDefParentParent?.type === AST_NODE_TYPES.ForOfStatement && bDefParentParent?.type === AST_NODE_TYPES.ForOfStatement: {
179
+ const aLeft = aDefParentParent.left;
180
+ const bLeft = bDefParentParent.left;
181
+ if (aLeft.type !== bLeft.type) return false;
182
+ const aRight = aDefParentParent.right;
183
+ const bRight = bDefParentParent.right;
184
+ return ast.isNodeEqual(aRight, bRight);
185
+ }
186
+ default: return aVar != null && bVar != null && aVar === bVar;
317
187
  }
318
- case AST_NODE_TYPES.ObjectExpression: return findProperty(name, prop.argument.properties, initialScope, seen) != null;
319
- default: return false;
320
188
  }
321
- return false;
322
- });
189
+ case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return ast.isNodeEqual(a.property, b.property) && isValueEqual(a.object, b.object, initialScopes);
190
+ case a.type === AST_NODE_TYPES.ThisExpression && b.type === AST_NODE_TYPES.ThisExpression:
191
+ if (aScope.block === bScope.block) return true;
192
+ return ast.findParentNode(a, ast.isOneOf(thisBlockTypes)) === ast.findParentNode(b, ast.isOneOf(thisBlockTypes));
193
+ default: {
194
+ const aStatic = getStaticValue(a, aScope);
195
+ const bStatic = getStaticValue(b, bScope);
196
+ return aStatic != null && bStatic != null && aStatic.value === bStatic.value;
197
+ }
198
+ }
199
+ }
200
+
201
+ //#endregion
202
+ //#region src/is-assignment-target-equal.ts
203
+ /**
204
+ * Check if two assignment targets are equal
205
+ * Compares nodes directly or by their values
206
+ * @param context The rule context
207
+ * @param a The first node to compare
208
+ * @param b The second node to compare
209
+ * @returns True if the assignment targets are equal
210
+ * @internal
211
+ */
212
+ function isAssignmentTargetEqual(context, a, b) {
213
+ return ast.isNodeEqual(a, b) || isValueEqual(a, b, [context.sourceCode.getScope(a), context.sourceCode.getScope(b)]);
323
214
  }
324
215
 
325
216
  //#endregion
326
- export { findEnclosingAssignmentTarget, findImportSource, findProperty, findVariable, getChildScopes, getObjectType, getVariableDefinitionNode, getVariableDefinitionNodeLoose, getVariables, isAssignmentTargetEqual, isNodeEqual };
217
+ export { findEnclosingAssignmentTarget, findVariable, getObjectType, isAssignmentTargetEqual, isValueEqual };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/var",
3
- "version": "3.0.0-next.6",
3
+ "version": "3.0.0-next.61",
4
4
  "description": "ESLint React's TSESTree AST utility module for static analysis of variables.",
5
5
  "homepage": "https://github.com/Rel1cx/eslint-react",
6
6
  "bugs": {
@@ -34,12 +34,12 @@
34
34
  "@typescript-eslint/types": "canary",
35
35
  "@typescript-eslint/utils": "canary",
36
36
  "ts-pattern": "^5.9.0",
37
- "@eslint-react/ast": "3.0.0-next.6",
38
- "@eslint-react/eff": "3.0.0-next.6",
39
- "@eslint-react/shared": "3.0.0-next.6"
37
+ "@eslint-react/shared": "3.0.0-next.61",
38
+ "@eslint-react/eff": "3.0.0-next.61",
39
+ "@eslint-react/ast": "3.0.0-next.61"
40
40
  },
41
41
  "devDependencies": {
42
- "tsdown": "^0.20.3",
42
+ "tsdown": "^0.21.0-beta.2",
43
43
  "@local/configs": "0.0.0"
44
44
  },
45
45
  "peerDependencies": {
@@ -52,6 +52,6 @@
52
52
  "scripts": {
53
53
  "build": "tsdown --dts-resolve",
54
54
  "lint:publish": "publint",
55
- "lint:ts": "tsc --noEmit"
55
+ "lint:ts": "tsl"
56
56
  }
57
57
  }