@eslint-react/ast 2.0.0-next.152 → 2.0.0-next.154

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 +120 -131
  2. package/dist/index.js +220 -191
  3. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -2,14 +2,57 @@ import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
2
2
  import { unit } from "@eslint-react/eff";
3
3
  import { TSESTree as TSESTree$1 } from "@typescript-eslint/utils";
4
4
 
5
- //#region src/ast-array-method.d.ts
5
+ //#region src/array-index.d.ts
6
+ declare function getArrayMethodCallbackIndexParamPosition(methodName: string): number;
7
+ //#endregion
8
+ //#region src/array-method.d.ts
6
9
  declare function isArrayFromCall(node: TSESTree.Node, loose?: boolean): node is TSESTree.CallExpression;
7
10
  declare function isArrayMapCall(node: TSESTree.Node, loose?: boolean): node is TSESTree.CallExpression;
8
11
  //#endregion
9
- //#region src/ast-array-method-callback.d.ts
10
- declare function getArrayMethodCallbackIndexParamPosition(methodName: string): number;
12
+ //#region src/node-equal.d.ts
13
+ /**
14
+ * Determines whether node equals to another node
15
+ * @param a node to compare
16
+ * @param b node to compare
17
+ * @returns `true` if node equal
18
+ * @see https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/util/isNodeEqual.ts
19
+ */
20
+ declare const isNodeEqual: {
21
+ (a: TSESTree.Node): (b: TSESTree.Node) => boolean;
22
+ (a: TSESTree.Node, b: TSESTree.Node): boolean;
23
+ };
24
+ //#endregion
25
+ //#region src/node-format.d.ts
26
+ /**
27
+ * @internal
28
+ */
29
+ declare function toDelimiterFormat(node: TSESTree.Node, delimiter?: string): "RegExp literal" | Lowercase<string> | `JSX ${Lowercase<string>}`;
30
+ /**
31
+ * @internal
32
+ */
33
+ declare function toStringFormat(node: TSESTree.Node, getText: (node: TSESTree.Node) => string): string;
34
+ //#endregion
35
+ //#region src/node-is.d.ts
36
+ declare const is: <NodeType extends TSESTree.AST_NODE_TYPES>(nodeType: NodeType) => (node: TSESTree.Node | null | undefined) => node is Extract<TSESTree.Node, {
37
+ type: NodeType;
38
+ }>;
39
+ declare const isOneOf: <NodeTypes extends readonly TSESTree.AST_NODE_TYPES[]>(nodeTypes: NodeTypes) => (node: TSESTree.Node | null | undefined) => node is Extract<TSESTree.Node, {
40
+ type: NodeTypes[number];
41
+ }>;
42
+ declare const isFunction: (node: TSESTree.Node | null | undefined) => node is TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.FunctionExpression;
43
+ declare const isFunctionType: (node: TSESTree.Node | null | undefined) => node is TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.FunctionExpression | TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSDeclareFunctionNoDeclare | TSESTree.TSDeclareFunctionWithDeclare | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType | TSESTree.TSMethodSignatureComputedName | TSESTree.TSMethodSignatureNonComputedName;
44
+ declare const isClass: (node: TSESTree.Node | null | undefined) => node is TSESTree.ClassDeclarationWithName | TSESTree.ClassDeclarationWithOptionalName | TSESTree.ClassExpression;
45
+ declare const isMethodOrProperty: (node: TSESTree.Node | null | undefined) => node is TSESTree.MethodDefinitionComputedName | TSESTree.MethodDefinitionNonComputedName | TSESTree.PropertyDefinitionComputedName | TSESTree.PropertyDefinitionNonComputedName;
46
+ declare const isProperty: (node: TSESTree.Node | null | undefined) => node is TSESTree.PropertyDefinitionComputedName | TSESTree.PropertyDefinitionNonComputedName | TSESTree.TSIndexSignature | TSESTree.TSParameterProperty | TSESTree.TSPropertySignatureComputedName | TSESTree.TSPropertySignatureNonComputedName;
47
+ declare const isJSXElement: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXElement;
48
+ declare const isJSXFragment: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXFragment;
49
+ declare const isJSXTagNameExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXIdentifier | TSESTree.JSXMemberExpression | TSESTree.JSXNamespacedName;
50
+ declare const isJSX: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXAttribute | TSESTree.JSXClosingElement | TSESTree.JSXClosingFragment | TSESTree.JSXElement | TSESTree.JSXEmptyExpression | TSESTree.JSXExpressionContainer | TSESTree.JSXFragment | TSESTree.JSXIdentifier | TSESTree.JSXMemberExpression | TSESTree.JSXNamespacedName | TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment | TSESTree.JSXSpreadAttribute | TSESTree.JSXSpreadChild | TSESTree.JSXText;
51
+ declare const isLoop: (node: TSESTree.Node | null | undefined) => node is TSESTree.DoWhileStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.WhileStatement;
52
+ declare const isTypeExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion;
53
+ declare const isTypeAssertionExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.TSAsExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion;
11
54
  //#endregion
12
- //#region src/ast-node-types.d.ts
55
+ //#region src/node-types.d.ts
13
56
  type TSESTreeFunction = TSESTree$1.ArrowFunctionExpression | TSESTree$1.FunctionDeclaration | TSESTree$1.FunctionExpression;
14
57
  type TSESTreeFunctionType = TSESTree$1.TSCallSignatureDeclaration | TSESTree$1.TSConstructSignatureDeclaration | TSESTree$1.TSDeclareFunction | TSESTree$1.TSEmptyBodyFunctionExpression | TSESTree$1.TSFunctionType | TSESTree$1.TSMethodSignature | TSESTreeFunction;
15
58
  type TSESTreeClass = TSESTree$1.ClassDeclaration | TSESTree$1.ClassExpression;
@@ -23,95 +66,30 @@ type TSESTreeTypeDeclaration = TSESTree$1.TSInterfaceDeclaration | TSESTree$1.TS
23
66
  type TSESTreeTypeExpression = TSESTree$1.TSAsExpression | TSESTree$1.TSNonNullExpression | TSESTree$1.TSSatisfiesExpression | TSESTree$1.TSTypeAssertion | TSESTree$1.TSInstantiationExpression;
24
67
  type TSESTreeTypeAssertionExpression = TSESTree$1.TSAsExpression | TSESTree$1.TSNonNullExpression | TSESTree$1.TSSatisfiesExpression | TSESTree$1.TSTypeAssertion;
25
68
  //#endregion
26
- //#region src/ast-class-id.d.ts
69
+ //#region src/class-id.d.ts
27
70
  declare function getClassId(node: TSESTreeClass): TSESTree.Identifier | unit;
28
71
  //#endregion
29
- //#region src/ast-expression.d.ts
72
+ //#region src/expression-base.d.ts
30
73
  /**
31
- * Recursively get the inner expression until it's not a TypeExpression
32
- * @param node - The node to get the expression from
33
- * @returns The inner expression
34
- */
35
- declare function getJSExpression(node: TSESTree.Node): Exclude<TSESTree.Node, TSESTreeTypeExpression>;
36
- declare function isThisExpression(node: TSESTree.Expression): boolean;
37
- //#endregion
38
- //#region src/ast-function-id.d.ts
39
- /**
40
- * Gets the static name of a function AST node. For function declarations it is
41
- * easy. For anonymous function expressions it is much harder. If you search for
42
- * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
43
- * where JS gives anonymous function expressions names. We roughly detect the
44
- * same AST nodes with some exceptions to better fit our use case.
74
+ * Unwraps any type expressions to get the underlying JavaScript expression node.
75
+ * Recursively processes nodes until a non-type expression is found.
76
+ *
77
+ * @param node - The AST node to unwrap
78
+ * @returns The underlying JavaScript expression node
45
79
  */
46
- declare function getFunctionId(node: TSESTree.Expression | TSESTreeFunction): TSESTree.Identifier | unit;
80
+ declare function getUnderlyingExpression(node: TSESTree.Node): Exclude<TSESTree.Node, TSESTreeTypeExpression>;
47
81
  //#endregion
48
- //#region src/ast-function-init-path.d.ts
49
- type FunctionInitPath =
82
+ //#region src/expression-is.d.ts
50
83
  /**
51
- * function Comp() { return <div />; }
84
+ * Checks if the given expression is a 'this' expression.
85
+ * Unwraps any type expressions before checking.
86
+ *
87
+ * @param node - The expression node to check
88
+ * @returns true if the expression is a ThisExpression, false otherwise
52
89
  */
53
- readonly [TSESTree.FunctionDeclaration]
54
- /**
55
- * const Comp = () => <div />;
56
- * const Comp = function () { return <div />; };
57
- */ | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTreeFunction]
58
- /**
59
- * const Comp = React.memo(() => <div />);
60
- * const Comp = React.forwardRef(() => <div />);
61
- */ | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTreeFunction]
62
- /**
63
- * const Comp = React.memo(React.forwardRef(() => <div />));
64
- */ | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTree.CallExpression, TSESTreeFunction]
65
- /**
66
- * const Comps = {
67
- * TopNav() { return <div />; },
68
- * SidPanel: () => <div />,
69
- * }
70
- */ | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTreeFunction]
71
- /**
72
- * const Comps = {
73
- * TopNav: React.memo(() => <div />),
74
- * SidPanel: React.forwardRef(() => <div />),
75
- * }
76
- */ | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTreeFunction]
77
- /**
78
- * const Comps = {
79
- * TopNav: React.memo(React.forwardRef(() => <div />)),
80
- * SidPanel: React.forwardRef(React.memo(() => <div />)),
81
- * }
82
- */ | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTree.CallExpression, TSESTreeFunction]
83
- /**
84
- * class Comp {
85
- * TopNav() { return <div />; }
86
- * }
87
- */ | readonly [TSESTree.ClassDeclaration, TSESTree.ClassBody, TSESTree.MethodDefinition, TSESTreeFunction]
88
- /**
89
- * class Comp {
90
- * TopNav = () => <div />;
91
- * }
92
- */ | readonly [TSESTree.ClassDeclaration, TSESTree.ClassBody, TSESTree.PropertyDefinition, TSESTreeFunction];
93
- declare function getFunctionInitPath(node: TSESTreeFunction): unit | FunctionInitPath;
94
- declare function hasCallInFunctionInitPath(callName: string, initPath: FunctionInitPath): boolean;
95
- //#endregion
96
- //#region src/ast-function-is.d.ts
97
- declare function isEmptyFunction(node: TSESTreeFunction): boolean;
98
- declare function isImmediatelyInvokedFunction(node: TSESTreeFunction): boolean;
90
+ declare function isThisExpression(node: TSESTree.Expression): boolean;
99
91
  //#endregion
100
- //#region src/ast-hierarchy.d.ts
101
- /**
102
- * Find the parent node that satisfies the test function
103
- * @param node The AST node
104
- * @param test The test function
105
- * @returns The parent node that satisfies the test function or `_` if not found
106
- */
107
- declare function findParentNode<A extends TSESTree.Node>(node: TSESTree.Node | unit, test: (n: TSESTree.Node) => n is A): A | unit;
108
- /**
109
- * Find the parent node that satisfies the test function or `_` if not found
110
- * @param node The AST node
111
- * @param test The test function
112
- * @returns The parent node that satisfies the test function
113
- */
114
- declare function findParentNode(node: TSESTree.Node | unit, test: (node: TSESTree.Node) => boolean): TSESTree.Node | unit;
92
+ //#region src/expression-nested.d.ts
115
93
  /**
116
94
  * Get all nested identifiers in a expression like node
117
95
  * @param node The node to get the nested identifiers from
@@ -146,7 +124,45 @@ declare const getNestedNewExpressions: (node: TSESTree.Node) => TSESTree.NewExpr
146
124
  */
147
125
  declare const getNestedCallExpressions: (node: TSESTree.Node) => TSESTree.CallExpression[];
148
126
  //#endregion
149
- //#region src/ast-line.d.ts
127
+ //#region src/function-id.d.ts
128
+ /**
129
+ * Gets the static name of a function AST node. For function declarations it is
130
+ * easy. For anonymous function expressions it is much harder. If you search for
131
+ * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
132
+ * where JS gives anonymous function expressions names. We roughly detect the
133
+ * same AST nodes with some exceptions to better fit our use case.
134
+ */
135
+ declare function getFunctionId(node: TSESTree.Expression | TSESTreeFunction): TSESTree.Identifier | unit;
136
+ //#endregion
137
+ //#region src/function-init-path.d.ts
138
+ /**
139
+ * Represents various AST paths for React component function declarations.
140
+ * Each tuple type represents a specific component definition pattern.
141
+ */
142
+ type FunctionInitPath = readonly [TSESTree.FunctionDeclaration] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.ClassDeclaration, TSESTree.ClassBody, TSESTree.MethodDefinition, TSESTreeFunction] | readonly [TSESTree.ClassDeclaration, TSESTree.ClassBody, TSESTree.PropertyDefinition, TSESTreeFunction];
143
+ /**
144
+ * Identifies the initialization path of a function node in the AST.
145
+ * Determines what kind of component declaration pattern the function belongs to.
146
+ *
147
+ * @param node - The function node to analyze
148
+ * @returns The function initialization path or unit if not identifiable
149
+ */
150
+ declare function getFunctionInitPath(node: TSESTreeFunction): unit | FunctionInitPath;
151
+ /**
152
+ * Checks if a specific function call exists in the function initialization path.
153
+ * Useful for detecting HOCs like React.memo, React.forwardRef, etc.
154
+ *
155
+ * @param callName - The name of the call to check for (e.g., "memo", "forwardRef")
156
+ * @param initPath - The function initialization path to search in
157
+ * @returns True if the call exists in the path, false otherwise
158
+ */
159
+ declare function hasCallInFunctionInitPath(callName: string, initPath: FunctionInitPath): boolean;
160
+ //#endregion
161
+ //#region src/function-is.d.ts
162
+ declare function isFunctionEmpty(node: TSESTreeFunction): boolean;
163
+ declare function isFunctionImmediatelyInvoked(node: TSESTreeFunction): boolean;
164
+ //#endregion
165
+ //#region src/line.d.ts
150
166
  /**
151
167
  * Check if a node is multiline
152
168
  * @param node The AST node to check
@@ -160,7 +176,7 @@ declare function isMultiLine(node: TSESTree.Node): boolean;
160
176
  */
161
177
  declare function isLineBreak(node: TSESTree.Node): boolean;
162
178
  //#endregion
163
- //#region src/ast-literal-is.d.ts
179
+ //#region src/literal.d.ts
164
180
  declare function isLiteral(node: TSESTree.Node): node is TSESTree.Literal;
165
181
  declare function isLiteral(node: TSESTree.Node, type: "boolean"): node is TSESTree.BooleanLiteral;
166
182
  declare function isLiteral(node: TSESTree.Node, type: "null"): node is TSESTree.NullLiteral;
@@ -168,53 +184,26 @@ declare function isLiteral(node: TSESTree.Node, type: "number"): node is TSESTre
168
184
  declare function isLiteral(node: TSESTree.Node, type: "regexp"): node is TSESTree.RegExpLiteral;
169
185
  declare function isLiteral(node: TSESTree.Node, type: "string"): node is TSESTree.StringLiteral;
170
186
  //#endregion
171
- //#region src/ast-node-equal.d.ts
172
- /**
173
- * Determines whether node equals to another node
174
- * @param a node to compare
175
- * @param b node to compare
176
- * @returns `true` if node equal
177
- * @see https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/util/isNodeEqual.ts
178
- */
179
- declare const isNodeEqual: {
180
- (a: TSESTree.Node): (b: TSESTree.Node) => boolean;
181
- (a: TSESTree.Node, b: TSESTree.Node): boolean;
182
- };
187
+ //#region src/promise-then.d.ts
188
+ declare function isThenCall(node: TSESTree.CallExpression): boolean;
189
+ //#endregion
190
+ //#region src/property-name.d.ts
191
+ declare function getPropertyName(node: TSESTree.Node): string | unit;
183
192
  //#endregion
184
- //#region src/ast-node-format.d.ts
193
+ //#region src/traverse-up.d.ts
185
194
  /**
186
- * @internal
195
+ * Find the parent node that satisfies the test function
196
+ * @param node The AST node
197
+ * @param test The test function
198
+ * @returns The parent node that satisfies the test function or `_` if not found
187
199
  */
188
- declare function toDelimiterFormat(node: TSESTree.Node, delimiter?: string): "RegExp literal" | Lowercase<string> | `JSX ${Lowercase<string>}`;
200
+ declare function findParentNode<A extends TSESTree.Node>(node: TSESTree.Node | unit, test: (n: TSESTree.Node) => n is A): A | unit;
189
201
  /**
190
- * @internal
202
+ * Find the parent node that satisfies the test function or `_` if not found
203
+ * @param node The AST node
204
+ * @param test The test function
205
+ * @returns The parent node that satisfies the test function
191
206
  */
192
- declare function toStringFormat(node: TSESTree.Node, getText: (node: TSESTree.Node) => string): string;
193
- //#endregion
194
- //#region src/ast-node-is.d.ts
195
- declare const is: <NodeType extends TSESTree.AST_NODE_TYPES>(nodeType: NodeType) => (node: TSESTree.Node | null | undefined) => node is Extract<TSESTree.Node, {
196
- type: NodeType;
197
- }>;
198
- declare const isOneOf: <NodeTypes extends readonly TSESTree.AST_NODE_TYPES[]>(nodeTypes: NodeTypes) => (node: TSESTree.Node | null | undefined) => node is Extract<TSESTree.Node, {
199
- type: NodeTypes[number];
200
- }>;
201
- declare const isFunction: (node: TSESTree.Node | null | undefined) => node is TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression;
202
- declare const isFunctionType: (node: TSESTree.Node | null | undefined) => node is TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression | TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSDeclareFunctionNoDeclare | TSESTree.TSDeclareFunctionWithDeclare | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType | TSESTree.TSMethodSignatureComputedName | TSESTree.TSMethodSignatureNonComputedName;
203
- declare const isClass: (node: TSESTree.Node | null | undefined) => node is TSESTree.ClassDeclarationWithName | TSESTree.ClassDeclarationWithOptionalName | TSESTree.ClassExpression;
204
- declare const isMethodOrProperty: (node: TSESTree.Node | null | undefined) => node is TSESTree.MethodDefinitionComputedName | TSESTree.MethodDefinitionNonComputedName | TSESTree.PropertyDefinitionComputedName | TSESTree.PropertyDefinitionNonComputedName;
205
- declare const isProperty: (node: TSESTree.Node | null | undefined) => node is TSESTree.PropertyDefinitionComputedName | TSESTree.PropertyDefinitionNonComputedName | TSESTree.TSIndexSignature | TSESTree.TSParameterProperty | TSESTree.TSPropertySignatureComputedName | TSESTree.TSPropertySignatureNonComputedName;
206
- declare const isJSXElement: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXElement;
207
- declare const isJSXFragment: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXFragment;
208
- declare const isJSXTagNameExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXIdentifier | TSESTree.JSXMemberExpression | TSESTree.JSXNamespacedName;
209
- declare const isJSX: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXAttribute | TSESTree.JSXClosingElement | TSESTree.JSXClosingFragment | TSESTree.JSXElement | TSESTree.JSXEmptyExpression | TSESTree.JSXExpressionContainer | TSESTree.JSXFragment | TSESTree.JSXIdentifier | TSESTree.JSXMemberExpression | TSESTree.JSXNamespacedName | TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment | TSESTree.JSXSpreadAttribute | TSESTree.JSXSpreadChild | TSESTree.JSXText;
210
- declare const isLoop: (node: TSESTree.Node | null | undefined) => node is TSESTree.DoWhileStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.WhileStatement;
211
- declare const isTypeExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion;
212
- declare const isTypeAssertionExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.TSAsExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion;
213
- //#endregion
214
- //#region src/ast-property-name.d.ts
215
- declare function getPropertyName(node: TSESTree.Node): string | unit;
216
- //#endregion
217
- //#region src/ast-then.d.ts
218
- declare function isThenCall(node: TSESTree.CallExpression): boolean;
207
+ declare function findParentNode(node: TSESTree.Node | unit, test: (node: TSESTree.Node) => boolean): TSESTree.Node | unit;
219
208
  //#endregion
220
- export { FunctionInitPath, TSESTreeArrayTupleType, TSESTreeClass, TSESTreeDestructuringPattern, TSESTreeFunction, TSESTreeFunctionType, TSESTreeJSX, TSESTreeLoop, TSESTreeMethodOrProperty, TSESTreeProperty, TSESTreeTypeAssertionExpression, TSESTreeTypeDeclaration, TSESTreeTypeExpression, findParentNode, getArrayMethodCallbackIndexParamPosition, getClassId, getFunctionId, getFunctionInitPath, getJSExpression, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, hasCallInFunctionInitPath, is, isArrayFromCall, isArrayMapCall, isClass, isEmptyFunction, isFunction, isFunctionType, isImmediatelyInvokedFunction, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProperty, isThenCall, isThisExpression, isTypeAssertionExpression, isTypeExpression, toDelimiterFormat, toStringFormat };
209
+ export { FunctionInitPath, TSESTreeArrayTupleType, TSESTreeClass, TSESTreeDestructuringPattern, TSESTreeFunction, TSESTreeFunctionType, TSESTreeJSX, TSESTreeLoop, TSESTreeMethodOrProperty, TSESTreeProperty, TSESTreeTypeAssertionExpression, TSESTreeTypeDeclaration, TSESTreeTypeExpression, findParentNode, getArrayMethodCallbackIndexParamPosition, getClassId, getFunctionId, getFunctionInitPath, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, getUnderlyingExpression, hasCallInFunctionInitPath, is, isArrayFromCall, isArrayMapCall, isClass, isFunction, isFunctionEmpty, isFunctionImmediatelyInvoked, isFunctionType, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProperty, isThenCall, isThisExpression, isTypeAssertionExpression, isTypeExpression, toDelimiterFormat, toStringFormat };
package/dist/index.js CHANGED
@@ -1,27 +1,10 @@
1
1
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
2
2
  import { dual, unit } from "@eslint-react/eff";
3
+ import { delimiterCase, replace, toLowerCase } from "string-ts";
3
4
  import { ASTUtils } from "@typescript-eslint/utils";
4
5
  import { simpleTraverse } from "@typescript-eslint/typescript-estree";
5
- import { delimiterCase, replace, toLowerCase } from "string-ts";
6
6
 
7
- //#region src/ast-array-method.ts
8
- function isArrayFromCall(node, loose = true) {
9
- if (node.type !== AST_NODE_TYPES.CallExpression) return false;
10
- if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
11
- if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;
12
- const name = node.callee.property.name;
13
- return name === "from" || loose && name.startsWith("from");
14
- }
15
- function isArrayMapCall(node, loose = true) {
16
- if (node.type !== AST_NODE_TYPES.CallExpression) return false;
17
- if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
18
- if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;
19
- const name = node.callee.property.name;
20
- return name === "map" || loose && name.endsWith("Map");
21
- }
22
-
23
- //#endregion
24
- //#region src/ast-array-method-callback.ts
7
+ //#region src/array-index.ts
25
8
  const indexParamPosition = new Map([
26
9
  ["every", 1],
27
10
  ["filter", 1],
@@ -41,7 +24,24 @@ function getArrayMethodCallbackIndexParamPosition(methodName) {
41
24
  }
42
25
 
43
26
  //#endregion
44
- //#region src/ast-class-id.ts
27
+ //#region src/array-method.ts
28
+ function isArrayFromCall(node, loose = true) {
29
+ if (node.type !== AST_NODE_TYPES.CallExpression) return false;
30
+ if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
31
+ if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;
32
+ const name = node.callee.property.name;
33
+ return name === "from" || loose && name.startsWith("from");
34
+ }
35
+ function isArrayMapCall(node, loose = true) {
36
+ if (node.type !== AST_NODE_TYPES.CallExpression) return false;
37
+ if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
38
+ if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return false;
39
+ const name = node.callee.property.name;
40
+ return name === "map" || loose && name.endsWith("Map");
41
+ }
42
+
43
+ //#endregion
44
+ //#region src/class-id.ts
45
45
  function getClassId(node) {
46
46
  if (node.id != null) return node.id;
47
47
  if (node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES.Identifier) return node.parent.id;
@@ -49,7 +49,46 @@ function getClassId(node) {
49
49
  }
50
50
 
51
51
  //#endregion
52
- //#region src/ast-node-is.ts
52
+ //#region src/node-equal.ts
53
+ /**
54
+ * Determines whether node equals to another node
55
+ * @param a node to compare
56
+ * @param b node to compare
57
+ * @returns `true` if node equal
58
+ * @see https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/util/isNodeEqual.ts
59
+ */
60
+ const isNodeEqual = dual(2, (a, b) => {
61
+ switch (true) {
62
+ case a === b: return true;
63
+ case a.type !== b.type: return false;
64
+ case a.type === AST_NODE_TYPES.Literal && b.type === AST_NODE_TYPES.Literal: return a.value === b.value;
65
+ case a.type === AST_NODE_TYPES.TemplateElement && b.type === AST_NODE_TYPES.TemplateElement: return a.value.raw === b.value.raw;
66
+ case a.type === AST_NODE_TYPES.TemplateLiteral && b.type === AST_NODE_TYPES.TemplateLiteral: {
67
+ if (a.quasis.length !== b.quasis.length || a.expressions.length !== b.expressions.length) return false;
68
+ let i = a.quasis.length;
69
+ while (i--) if (a.quasis[i]?.value.raw !== b.quasis[i]?.value.raw) return false;
70
+ i = a.expressions.length;
71
+ while (i--) {
72
+ const exprA = a.expressions[i];
73
+ const exprB = b.expressions[i];
74
+ if (!isNodeEqual(exprA, exprB)) return false;
75
+ }
76
+ return true;
77
+ }
78
+ case a.type === AST_NODE_TYPES.Identifier && b.type === AST_NODE_TYPES.Identifier: return a.name === b.name;
79
+ case a.type === AST_NODE_TYPES.PrivateIdentifier && b.type === AST_NODE_TYPES.PrivateIdentifier: return a.name === b.name;
80
+ case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return isNodeEqual(a.property, b.property) && isNodeEqual(a.object, b.object);
81
+ case a.type === AST_NODE_TYPES.JSXAttribute && b.type === AST_NODE_TYPES.JSXAttribute:
82
+ if (a.name.name !== b.name.name) return false;
83
+ if (a.value == null || b.value == null) return a.value === b.value;
84
+ return isNodeEqual(a.value, b.value);
85
+ case a.type === AST_NODE_TYPES.ThisExpression && b.type === AST_NODE_TYPES.ThisExpression: return true;
86
+ default: return false;
87
+ }
88
+ });
89
+
90
+ //#endregion
91
+ //#region src/node-is.ts
53
92
  const is = ASTUtils.isNodeOfType;
54
93
  const isOneOf = ASTUtils.isNodeOfTypes;
55
94
  const isFunction = isOneOf([
@@ -122,110 +161,68 @@ const isTypeAssertionExpression = isOneOf([
122
161
  ]);
123
162
 
124
163
  //#endregion
125
- //#region src/ast-expression.ts
164
+ //#region src/node-format.ts
165
+ function getLiteralValueType(input) {
166
+ if (input === null) return "null";
167
+ return typeof input;
168
+ }
126
169
  /**
127
- * Recursively get the inner expression until it's not a TypeExpression
128
- * @param node - The node to get the expression from
129
- * @returns The inner expression
170
+ * @internal
130
171
  */
131
- function getJSExpression(node) {
132
- if (isTypeExpression(node)) return getJSExpression(node.expression);
133
- return node;
134
- }
135
- function isThisExpression(node) {
136
- return getJSExpression(node).type === AST_NODE_TYPES.ThisExpression;
172
+ function toDelimiterFormat(node, delimiter = " ") {
173
+ if (node.type === AST_NODE_TYPES.Literal) {
174
+ if ("regex" in node) return "RegExp literal";
175
+ return `${getLiteralValueType(node.value)} literal`;
176
+ }
177
+ if (isJSX(node)) return `JSX ${toLowerCase(delimiterCase(replace(node.type, "JSX", ""), delimiter))}`;
178
+ return toLowerCase(delimiterCase(node.type, delimiter));
137
179
  }
138
-
139
- //#endregion
140
- //#region src/ast-function-id.ts
141
180
  /**
142
- * Gets the static name of a function AST node. For function declarations it is
143
- * easy. For anonymous function expressions it is much harder. If you search for
144
- * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
145
- * where JS gives anonymous function expressions names. We roughly detect the
146
- * same AST nodes with some exceptions to better fit our use case.
181
+ * @internal
147
182
  */
148
- function getFunctionId(node) {
149
- switch (true) {
150
- case "id" in node && node.id != null: return node.id;
151
- case node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init === node && node.parent.id.type === AST_NODE_TYPES.Identifier: return node.parent.id;
152
- case node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=" && node.parent.left.type === AST_NODE_TYPES.Identifier: return node.parent.left;
153
- case node.parent.type === AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed && node.parent.key.type === AST_NODE_TYPES.Identifier: return node.parent.key;
154
- case isMethodOrProperty(node.parent) && node.parent.value === node && node.parent.key.type === AST_NODE_TYPES.Identifier: return node.parent.key;
155
- case node.parent.type === AST_NODE_TYPES.AssignmentPattern && node.parent.right === node && node.parent.left.type === AST_NODE_TYPES.Identifier: return node.parent.left;
156
- case isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
183
+ function toStringFormat(node, getText) {
184
+ switch (node.type) {
185
+ case AST_NODE_TYPES.Identifier:
186
+ case AST_NODE_TYPES.JSXIdentifier:
187
+ case AST_NODE_TYPES.PrivateIdentifier: return node.name;
188
+ case AST_NODE_TYPES.MemberExpression:
189
+ case AST_NODE_TYPES.JSXMemberExpression: return `${toStringFormat(node.object, getText)}.${toStringFormat(node.property, getText)}`;
190
+ case AST_NODE_TYPES.JSXNamespacedName: return `${node.namespace.name}:${node.name.name}`;
191
+ case AST_NODE_TYPES.JSXText: return node.value;
192
+ case AST_NODE_TYPES.Literal: return node.raw;
193
+ default: return getText(node);
157
194
  }
158
- return unit;
159
195
  }
160
196
 
161
197
  //#endregion
162
- //#region src/ast-function-init-path.ts
163
- function getFunctionInitPath(node) {
164
- if (node.type === AST_NODE_TYPES.FunctionDeclaration) return [node];
165
- const { parent } = node;
166
- switch (true) {
167
- case parent.type === AST_NODE_TYPES.VariableDeclarator: return [
168
- parent.parent,
169
- parent,
170
- node
171
- ];
172
- case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
173
- parent.parent.parent,
174
- parent.parent,
175
- parent,
176
- node
177
- ];
178
- case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.CallExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
179
- parent.parent.parent.parent,
180
- parent.parent.parent,
181
- parent.parent,
182
- parent,
183
- node
184
- ];
185
- case parent.type === AST_NODE_TYPES.Property && parent.parent.type === AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
186
- parent.parent.parent.parent,
187
- parent.parent.parent,
188
- parent.parent,
189
- parent,
190
- node
191
- ];
192
- case parent.type === AST_NODE_TYPES.MethodDefinition && parent.parent.parent.type === AST_NODE_TYPES.ClassDeclaration: return [
193
- parent.parent.parent,
194
- parent.parent,
195
- parent,
196
- node
197
- ];
198
- case parent.type === AST_NODE_TYPES.PropertyDefinition && parent.parent.parent.type === AST_NODE_TYPES.ClassDeclaration: return [
199
- parent.parent.parent,
200
- parent.parent,
201
- parent,
202
- node
203
- ];
204
- }
205
- return unit;
206
- }
207
- function hasCallInFunctionInitPath(callName, initPath) {
208
- return initPath.some((n) => {
209
- if (n.type !== AST_NODE_TYPES.CallExpression) return false;
210
- switch (n.callee.type) {
211
- case AST_NODE_TYPES.Identifier: return n.callee.name === callName;
212
- case AST_NODE_TYPES.MemberExpression: return "name" in n.callee.property && n.callee.property.name === callName;
213
- default: return false;
214
- }
215
- });
198
+ //#region src/expression-base.ts
199
+ /**
200
+ * Unwraps any type expressions to get the underlying JavaScript expression node.
201
+ * Recursively processes nodes until a non-type expression is found.
202
+ *
203
+ * @param node - The AST node to unwrap
204
+ * @returns The underlying JavaScript expression node
205
+ */
206
+ function getUnderlyingExpression(node) {
207
+ if (isTypeExpression(node)) return getUnderlyingExpression(node.expression);
208
+ return node;
216
209
  }
217
210
 
218
211
  //#endregion
219
- //#region src/ast-function-is.ts
220
- function isEmptyFunction(node) {
221
- return node.body.type === AST_NODE_TYPES.BlockStatement && node.body.body.length === 0;
222
- }
223
- function isImmediatelyInvokedFunction(node) {
224
- return node.type !== AST_NODE_TYPES.FunctionDeclaration && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
212
+ //#region src/expression-is.ts
213
+ /**
214
+ * Checks if the given expression is a 'this' expression.
215
+ * Unwraps any type expressions before checking.
216
+ *
217
+ * @param node - The expression node to check
218
+ * @returns true if the expression is a ThisExpression, false otherwise
219
+ */
220
+ function isThisExpression(node) {
221
+ return getUnderlyingExpression(node).type === AST_NODE_TYPES.ThisExpression;
225
222
  }
226
223
 
227
224
  //#endregion
228
- //#region src/ast-hierarchy.ts
225
+ //#region src/traverse-up.ts
229
226
  function findParentNode(node, test) {
230
227
  if (node == null) return unit;
231
228
  let parent = node.parent;
@@ -235,6 +232,9 @@ function findParentNode(node, test) {
235
232
  }
236
233
  return unit;
237
234
  }
235
+
236
+ //#endregion
237
+ //#region src/expression-nested.ts
238
238
  /**
239
239
  * Get all nested identifiers in a expression like node
240
240
  * @param node The node to get the nested identifiers from
@@ -418,7 +418,109 @@ const getNestedNewExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.NewExp
418
418
  const getNestedCallExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.CallExpression);
419
419
 
420
420
  //#endregion
421
- //#region src/ast-line.ts
421
+ //#region src/function-id.ts
422
+ /**
423
+ * Gets the static name of a function AST node. For function declarations it is
424
+ * easy. For anonymous function expressions it is much harder. If you search for
425
+ * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
426
+ * where JS gives anonymous function expressions names. We roughly detect the
427
+ * same AST nodes with some exceptions to better fit our use case.
428
+ */
429
+ function getFunctionId(node) {
430
+ switch (true) {
431
+ case "id" in node && node.id != null: return node.id;
432
+ case node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init === node && node.parent.id.type === AST_NODE_TYPES.Identifier: return node.parent.id;
433
+ case node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=" && node.parent.left.type === AST_NODE_TYPES.Identifier: return node.parent.left;
434
+ case node.parent.type === AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed && node.parent.key.type === AST_NODE_TYPES.Identifier: return node.parent.key;
435
+ case isMethodOrProperty(node.parent) && node.parent.value === node && node.parent.key.type === AST_NODE_TYPES.Identifier: return node.parent.key;
436
+ case node.parent.type === AST_NODE_TYPES.AssignmentPattern && node.parent.right === node && node.parent.left.type === AST_NODE_TYPES.Identifier: return node.parent.left;
437
+ case isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
438
+ }
439
+ return unit;
440
+ }
441
+
442
+ //#endregion
443
+ //#region src/function-init-path.ts
444
+ /**
445
+ * Identifies the initialization path of a function node in the AST.
446
+ * Determines what kind of component declaration pattern the function belongs to.
447
+ *
448
+ * @param node - The function node to analyze
449
+ * @returns The function initialization path or unit if not identifiable
450
+ */
451
+ function getFunctionInitPath(node) {
452
+ if (node.type === AST_NODE_TYPES.FunctionDeclaration) return [node];
453
+ const { parent } = node;
454
+ switch (true) {
455
+ case parent.type === AST_NODE_TYPES.VariableDeclarator: return [
456
+ parent.parent,
457
+ parent,
458
+ node
459
+ ];
460
+ case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
461
+ parent.parent.parent,
462
+ parent.parent,
463
+ parent,
464
+ node
465
+ ];
466
+ case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.CallExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
467
+ parent.parent.parent.parent,
468
+ parent.parent.parent,
469
+ parent.parent,
470
+ parent,
471
+ node
472
+ ];
473
+ case parent.type === AST_NODE_TYPES.Property && parent.parent.type === AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
474
+ parent.parent.parent.parent,
475
+ parent.parent.parent,
476
+ parent.parent,
477
+ parent,
478
+ node
479
+ ];
480
+ case parent.type === AST_NODE_TYPES.MethodDefinition && parent.parent.parent.type === AST_NODE_TYPES.ClassDeclaration: return [
481
+ parent.parent.parent,
482
+ parent.parent,
483
+ parent,
484
+ node
485
+ ];
486
+ case parent.type === AST_NODE_TYPES.PropertyDefinition && parent.parent.parent.type === AST_NODE_TYPES.ClassDeclaration: return [
487
+ parent.parent.parent,
488
+ parent.parent,
489
+ parent,
490
+ node
491
+ ];
492
+ }
493
+ return unit;
494
+ }
495
+ /**
496
+ * Checks if a specific function call exists in the function initialization path.
497
+ * Useful for detecting HOCs like React.memo, React.forwardRef, etc.
498
+ *
499
+ * @param callName - The name of the call to check for (e.g., "memo", "forwardRef")
500
+ * @param initPath - The function initialization path to search in
501
+ * @returns True if the call exists in the path, false otherwise
502
+ */
503
+ function hasCallInFunctionInitPath(callName, initPath) {
504
+ return initPath.some((node) => {
505
+ if (node.type !== AST_NODE_TYPES.CallExpression) return false;
506
+ const { callee } = node;
507
+ if (callee.type === AST_NODE_TYPES.Identifier) return callee.name === callName;
508
+ if (callee.type === AST_NODE_TYPES.MemberExpression && "name" in callee.property) return callee.property.name === callName;
509
+ return false;
510
+ });
511
+ }
512
+
513
+ //#endregion
514
+ //#region src/function-is.ts
515
+ function isFunctionEmpty(node) {
516
+ return node.body.type === AST_NODE_TYPES.BlockStatement && node.body.body.length === 0;
517
+ }
518
+ function isFunctionImmediatelyInvoked(node) {
519
+ return node.type !== AST_NODE_TYPES.FunctionDeclaration && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
520
+ }
521
+
522
+ //#endregion
523
+ //#region src/line.ts
422
524
  /**
423
525
  * Check if a node is multiline
424
526
  * @param node The AST node to check
@@ -437,7 +539,7 @@ function isLineBreak(node) {
437
539
  }
438
540
 
439
541
  //#endregion
440
- //#region src/ast-literal-is.ts
542
+ //#region src/literal.ts
441
543
  function isLiteral(node, type) {
442
544
  if (node.type !== AST_NODE_TYPES.Literal) return false;
443
545
  if (type == null) return true;
@@ -451,82 +553,15 @@ function isLiteral(node, type) {
451
553
  }
452
554
 
453
555
  //#endregion
454
- //#region src/ast-node-equal.ts
455
- /**
456
- * Determines whether node equals to another node
457
- * @param a node to compare
458
- * @param b node to compare
459
- * @returns `true` if node equal
460
- * @see https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/util/isNodeEqual.ts
461
- */
462
- const isNodeEqual = dual(2, (a, b) => {
463
- switch (true) {
464
- case a === b: return true;
465
- case a.type !== b.type: return false;
466
- case a.type === AST_NODE_TYPES.Literal && b.type === AST_NODE_TYPES.Literal: return a.value === b.value;
467
- case a.type === AST_NODE_TYPES.TemplateElement && b.type === AST_NODE_TYPES.TemplateElement: return a.value.raw === b.value.raw;
468
- case a.type === AST_NODE_TYPES.TemplateLiteral && b.type === AST_NODE_TYPES.TemplateLiteral: {
469
- if (a.quasis.length !== b.quasis.length || a.expressions.length !== b.expressions.length) return false;
470
- let i = a.quasis.length;
471
- while (i--) if (a.quasis[i]?.value.raw !== b.quasis[i]?.value.raw) return false;
472
- i = a.expressions.length;
473
- while (i--) {
474
- const exprA = a.expressions[i];
475
- const exprB = b.expressions[i];
476
- if (!isNodeEqual(exprA, exprB)) return false;
477
- }
478
- return true;
479
- }
480
- case a.type === AST_NODE_TYPES.Identifier && b.type === AST_NODE_TYPES.Identifier: return a.name === b.name;
481
- case a.type === AST_NODE_TYPES.PrivateIdentifier && b.type === AST_NODE_TYPES.PrivateIdentifier: return a.name === b.name;
482
- case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return isNodeEqual(a.property, b.property) && isNodeEqual(a.object, b.object);
483
- case a.type === AST_NODE_TYPES.JSXAttribute && b.type === AST_NODE_TYPES.JSXAttribute:
484
- if (a.name.name !== b.name.name) return false;
485
- if (a.value == null || b.value == null) return a.value === b.value;
486
- return isNodeEqual(a.value, b.value);
487
- case a.type === AST_NODE_TYPES.ThisExpression && b.type === AST_NODE_TYPES.ThisExpression: return true;
488
- default: return false;
489
- }
490
- });
491
-
492
- //#endregion
493
- //#region src/ast-node-format.ts
494
- function getLiteralValueType(input) {
495
- if (input === null) return "null";
496
- return typeof input;
497
- }
498
- /**
499
- * @internal
500
- */
501
- function toDelimiterFormat(node, delimiter = " ") {
502
- if (node.type === AST_NODE_TYPES.Literal) {
503
- if ("regex" in node) return "RegExp literal";
504
- return `${getLiteralValueType(node.value)} literal`;
505
- }
506
- if (isJSX(node)) return `JSX ${toLowerCase(delimiterCase(replace(node.type, "JSX", ""), delimiter))}`;
507
- return toLowerCase(delimiterCase(node.type, delimiter));
508
- }
509
- /**
510
- * @internal
511
- */
512
- function toStringFormat(node, getText) {
513
- switch (node.type) {
514
- case AST_NODE_TYPES.Identifier:
515
- case AST_NODE_TYPES.JSXIdentifier:
516
- case AST_NODE_TYPES.PrivateIdentifier: return node.name;
517
- case AST_NODE_TYPES.MemberExpression:
518
- case AST_NODE_TYPES.JSXMemberExpression: return `${toStringFormat(node.object, getText)}.${toStringFormat(node.property, getText)}`;
519
- case AST_NODE_TYPES.JSXNamespacedName: return `${node.namespace.name}:${node.name.name}`;
520
- case AST_NODE_TYPES.JSXText: return node.value;
521
- case AST_NODE_TYPES.Literal: return node.raw;
522
- default: return getText(node);
523
- }
556
+ //#region src/promise-then.ts
557
+ function isThenCall(node) {
558
+ return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
524
559
  }
525
560
 
526
561
  //#endregion
527
- //#region src/ast-property-name.ts
562
+ //#region src/property-name.ts
528
563
  function getPropertyName(node) {
529
- if (isTypeExpression(node)) return getPropertyName(getJSExpression(node));
564
+ if (isTypeExpression(node)) return getPropertyName(getUnderlyingExpression(node));
530
565
  if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) return node.name;
531
566
  if (node.type === AST_NODE_TYPES.Literal) return String(node.value);
532
567
  if (node.type === AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) return node.quasis[0]?.value.raw;
@@ -534,10 +569,4 @@ function getPropertyName(node) {
534
569
  }
535
570
 
536
571
  //#endregion
537
- //#region src/ast-then.ts
538
- function isThenCall(node) {
539
- return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
540
- }
541
-
542
- //#endregion
543
- export { findParentNode, getArrayMethodCallbackIndexParamPosition, getClassId, getFunctionId, getFunctionInitPath, getJSExpression, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, hasCallInFunctionInitPath, is, isArrayFromCall, isArrayMapCall, isClass, isEmptyFunction, isFunction, isFunctionType, isImmediatelyInvokedFunction, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProperty, isThenCall, isThisExpression, isTypeAssertionExpression, isTypeExpression, toDelimiterFormat, toStringFormat };
572
+ export { findParentNode, getArrayMethodCallbackIndexParamPosition, getClassId, getFunctionId, getFunctionInitPath, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, getUnderlyingExpression, hasCallInFunctionInitPath, is, isArrayFromCall, isArrayMapCall, isClass, isFunction, isFunctionEmpty, isFunctionImmediatelyInvoked, isFunctionType, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProperty, isThenCall, isThisExpression, isTypeAssertionExpression, isTypeExpression, toDelimiterFormat, toStringFormat };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/ast",
3
- "version": "2.0.0-next.152",
3
+ "version": "2.0.0-next.154",
4
4
  "description": "ESLint React's TSESTree AST utility module.",
5
5
  "homepage": "https://github.com/Rel1cx/eslint-react",
6
6
  "bugs": {
@@ -32,7 +32,7 @@
32
32
  "@typescript-eslint/utils": "^8.41.0",
33
33
  "string-ts": "^2.2.1",
34
34
  "ts-pattern": "^5.8.0",
35
- "@eslint-react/eff": "2.0.0-next.152"
35
+ "@eslint-react/eff": "2.0.0-next.154"
36
36
  },
37
37
  "devDependencies": {
38
38
  "tsdown": "^0.14.2",