@eslint-react/ast 2.0.0-next.6 → 2.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.
- package/dist/index.d.ts +141 -219
- package/dist/index.js +531 -554
- package/package.json +8 -9
package/dist/index.js
CHANGED
|
@@ -1,595 +1,572 @@
|
|
|
1
|
-
import { AST_NODE_TYPES } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
2
|
+
import { dual, unit } from "@eslint-react/eff";
|
|
3
|
+
import { delimiterCase, replace, toLowerCase } from "string-ts";
|
|
4
|
+
import { ASTUtils } from "@typescript-eslint/utils";
|
|
5
|
+
import { simpleTraverse } from "@typescript-eslint/typescript-estree";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
//#region src/array-index.ts
|
|
8
|
+
const indexParamPosition = new Map([
|
|
9
|
+
["every", 1],
|
|
10
|
+
["filter", 1],
|
|
11
|
+
["find", 1],
|
|
12
|
+
["findIndex", 1],
|
|
13
|
+
["findLast", 1],
|
|
14
|
+
["findLastIndex", 1],
|
|
15
|
+
["flatMap", 1],
|
|
16
|
+
["forEach", 1],
|
|
17
|
+
["map", 1],
|
|
18
|
+
["reduce", 2],
|
|
19
|
+
["reduceRight", 2],
|
|
20
|
+
["some", 1]
|
|
21
|
+
]);
|
|
22
|
+
function getArrayMethodCallbackIndexParamPosition(methodName) {
|
|
23
|
+
return indexParamPosition.get(methodName) ?? -1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/array-method.ts
|
|
8
28
|
function isArrayFromCall(node, loose = true) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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");
|
|
14
34
|
}
|
|
15
35
|
function isArrayMapCall(node, loose = true) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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");
|
|
21
41
|
}
|
|
22
42
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
["every", 1],
|
|
26
|
-
["filter", 1],
|
|
27
|
-
["find", 1],
|
|
28
|
-
["findIndex", 1],
|
|
29
|
-
["findLast", 1],
|
|
30
|
-
["findLastIndex", 1],
|
|
31
|
-
["flatMap", 1],
|
|
32
|
-
["forEach", 1],
|
|
33
|
-
["map", 1],
|
|
34
|
-
["reduce", 2],
|
|
35
|
-
["reduceRight", 2],
|
|
36
|
-
["some", 1]
|
|
37
|
-
]);
|
|
38
|
-
function getArrayMethodCallbackIndexParamPosition(methodName) {
|
|
39
|
-
return indexParamPosition.get(methodName) ?? -1;
|
|
40
|
-
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/class-id.ts
|
|
41
45
|
function getClassId(node) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
return _;
|
|
46
|
+
if (node.id != null) return node.id;
|
|
47
|
+
if (node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES.Identifier) return node.parent.id;
|
|
48
|
+
return unit;
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
AST_NODE_TYPES.TSParameterProperty,
|
|
97
|
-
AST_NODE_TYPES.TSPropertySignature
|
|
98
|
-
]);
|
|
99
|
-
var isJSXElement = is(AST_NODE_TYPES.JSXElement);
|
|
100
|
-
var isJSXFragment = is(AST_NODE_TYPES.JSXFragment);
|
|
101
|
-
var isJSXTagNameExpression = isOneOf([
|
|
102
|
-
AST_NODE_TYPES.JSXIdentifier,
|
|
103
|
-
AST_NODE_TYPES.JSXMemberExpression,
|
|
104
|
-
AST_NODE_TYPES.JSXNamespacedName
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
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
|
|
92
|
+
const is = ASTUtils.isNodeOfType;
|
|
93
|
+
const isOneOf = ASTUtils.isNodeOfTypes;
|
|
94
|
+
const isFunction = isOneOf([
|
|
95
|
+
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
96
|
+
AST_NODE_TYPES.FunctionDeclaration,
|
|
97
|
+
AST_NODE_TYPES.FunctionExpression
|
|
105
98
|
]);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
AST_NODE_TYPES.JSXNamespacedName,
|
|
117
|
-
AST_NODE_TYPES.JSXOpeningElement,
|
|
118
|
-
AST_NODE_TYPES.JSXOpeningFragment,
|
|
119
|
-
AST_NODE_TYPES.JSXSpreadAttribute,
|
|
120
|
-
AST_NODE_TYPES.JSXSpreadChild,
|
|
121
|
-
AST_NODE_TYPES.JSXText
|
|
99
|
+
const isFunctionType = isOneOf([
|
|
100
|
+
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
101
|
+
AST_NODE_TYPES.FunctionDeclaration,
|
|
102
|
+
AST_NODE_TYPES.FunctionExpression,
|
|
103
|
+
AST_NODE_TYPES.TSCallSignatureDeclaration,
|
|
104
|
+
AST_NODE_TYPES.TSConstructSignatureDeclaration,
|
|
105
|
+
AST_NODE_TYPES.TSDeclareFunction,
|
|
106
|
+
AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
|
|
107
|
+
AST_NODE_TYPES.TSFunctionType,
|
|
108
|
+
AST_NODE_TYPES.TSMethodSignature
|
|
122
109
|
]);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
110
|
+
const isClass = isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]);
|
|
111
|
+
const isMethodOrProperty = isOneOf([AST_NODE_TYPES.PropertyDefinition, AST_NODE_TYPES.MethodDefinition]);
|
|
112
|
+
const isProperty = isOneOf([
|
|
113
|
+
AST_NODE_TYPES.PropertyDefinition,
|
|
114
|
+
AST_NODE_TYPES.TSIndexSignature,
|
|
115
|
+
AST_NODE_TYPES.TSParameterProperty,
|
|
116
|
+
AST_NODE_TYPES.TSPropertySignature
|
|
128
117
|
]);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
118
|
+
const isJSXElement = is(AST_NODE_TYPES.JSXElement);
|
|
119
|
+
const isJSXFragment = is(AST_NODE_TYPES.JSXFragment);
|
|
120
|
+
const isJSXTagNameExpression = isOneOf([
|
|
121
|
+
AST_NODE_TYPES.JSXIdentifier,
|
|
122
|
+
AST_NODE_TYPES.JSXMemberExpression,
|
|
123
|
+
AST_NODE_TYPES.JSXNamespacedName
|
|
132
124
|
]);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
AST_NODE_TYPES.SequenceExpression,
|
|
150
|
-
AST_NODE_TYPES.Super,
|
|
151
|
-
AST_NODE_TYPES.TaggedTemplateExpression,
|
|
152
|
-
AST_NODE_TYPES.ThisExpression
|
|
125
|
+
const isJSX = isOneOf([
|
|
126
|
+
AST_NODE_TYPES.JSXAttribute,
|
|
127
|
+
AST_NODE_TYPES.JSXClosingElement,
|
|
128
|
+
AST_NODE_TYPES.JSXClosingFragment,
|
|
129
|
+
AST_NODE_TYPES.JSXElement,
|
|
130
|
+
AST_NODE_TYPES.JSXEmptyExpression,
|
|
131
|
+
AST_NODE_TYPES.JSXExpressionContainer,
|
|
132
|
+
AST_NODE_TYPES.JSXFragment,
|
|
133
|
+
AST_NODE_TYPES.JSXIdentifier,
|
|
134
|
+
AST_NODE_TYPES.JSXMemberExpression,
|
|
135
|
+
AST_NODE_TYPES.JSXNamespacedName,
|
|
136
|
+
AST_NODE_TYPES.JSXOpeningElement,
|
|
137
|
+
AST_NODE_TYPES.JSXOpeningFragment,
|
|
138
|
+
AST_NODE_TYPES.JSXSpreadAttribute,
|
|
139
|
+
AST_NODE_TYPES.JSXSpreadChild,
|
|
140
|
+
AST_NODE_TYPES.JSXText
|
|
153
141
|
]);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
AST_NODE_TYPES.FunctionExpression,
|
|
161
|
-
AST_NODE_TYPES.Identifier,
|
|
162
|
-
AST_NODE_TYPES.JSXElement,
|
|
163
|
-
AST_NODE_TYPES.JSXFragment,
|
|
164
|
-
AST_NODE_TYPES.Literal,
|
|
165
|
-
AST_NODE_TYPES.TemplateLiteral,
|
|
166
|
-
AST_NODE_TYPES.MemberExpression,
|
|
167
|
-
AST_NODE_TYPES.MetaProperty,
|
|
168
|
-
AST_NODE_TYPES.ObjectExpression,
|
|
169
|
-
AST_NODE_TYPES.ObjectPattern,
|
|
170
|
-
AST_NODE_TYPES.SequenceExpression,
|
|
171
|
-
AST_NODE_TYPES.Super,
|
|
172
|
-
AST_NODE_TYPES.TaggedTemplateExpression,
|
|
173
|
-
AST_NODE_TYPES.ThisExpression,
|
|
174
|
-
AST_NODE_TYPES.TSAsExpression,
|
|
175
|
-
AST_NODE_TYPES.TSNonNullExpression,
|
|
176
|
-
AST_NODE_TYPES.TSTypeAssertion
|
|
142
|
+
const isLoop = isOneOf([
|
|
143
|
+
AST_NODE_TYPES.DoWhileStatement,
|
|
144
|
+
AST_NODE_TYPES.ForInStatement,
|
|
145
|
+
AST_NODE_TYPES.ForOfStatement,
|
|
146
|
+
AST_NODE_TYPES.ForStatement,
|
|
147
|
+
AST_NODE_TYPES.WhileStatement
|
|
177
148
|
]);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
149
|
+
const isTypeExpression = isOneOf([
|
|
150
|
+
AST_NODE_TYPES.TSAsExpression,
|
|
151
|
+
AST_NODE_TYPES.TSTypeAssertion,
|
|
152
|
+
AST_NODE_TYPES.TSNonNullExpression,
|
|
153
|
+
AST_NODE_TYPES.TSSatisfiesExpression,
|
|
154
|
+
AST_NODE_TYPES.TSInstantiationExpression
|
|
184
155
|
]);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
156
|
+
const isTypeAssertionExpression = isOneOf([
|
|
157
|
+
AST_NODE_TYPES.TSAsExpression,
|
|
158
|
+
AST_NODE_TYPES.TSTypeAssertion,
|
|
159
|
+
AST_NODE_TYPES.TSNonNullExpression,
|
|
160
|
+
AST_NODE_TYPES.TSSatisfiesExpression
|
|
190
161
|
]);
|
|
191
162
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return node;
|
|
198
|
-
}
|
|
199
|
-
function isThisExpression(node) {
|
|
200
|
-
return getJSExpression(node).type === AST_NODE_TYPES.ThisExpression;
|
|
201
|
-
}
|
|
202
|
-
function getFunctionId(node) {
|
|
203
|
-
switch (true) {
|
|
204
|
-
// function MaybeComponent() {}
|
|
205
|
-
case ("id" in node && node.id != null):
|
|
206
|
-
return node.id;
|
|
207
|
-
// const whatever = function MaybeComponent() {};
|
|
208
|
-
case (node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init === node && node.parent.id.type === AST_NODE_TYPES.Identifier):
|
|
209
|
-
return node.parent.id;
|
|
210
|
-
// MaybeComponent = () => {};
|
|
211
|
-
case (node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=" && node.parent.left.type === AST_NODE_TYPES.Identifier):
|
|
212
|
-
return node.parent.left;
|
|
213
|
-
// {MaybeComponent: () => {}}
|
|
214
|
-
// {MaybeComponent() {}}
|
|
215
|
-
case (node.parent.type === AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed && node.parent.key.type === AST_NODE_TYPES.Identifier):
|
|
216
|
-
return node.parent.key;
|
|
217
|
-
// class {MaybeComponent = () => {}}
|
|
218
|
-
// class {MaybeComponent() {}}
|
|
219
|
-
case (isMethodOrProperty(node.parent) && node.parent.value === node && node.parent.key.type === AST_NODE_TYPES.Identifier):
|
|
220
|
-
return node.parent.key;
|
|
221
|
-
// Follow spec convention for `IsAnonymousFunctionDefinition()` usage.
|
|
222
|
-
//
|
|
223
|
-
// const {MaybeComponent = () => {}} = {};
|
|
224
|
-
// ({MaybeComponent = () => {}} = {});
|
|
225
|
-
case (node.parent.type === AST_NODE_TYPES.AssignmentPattern && node.parent.right === node && node.parent.left.type === AST_NODE_TYPES.Identifier):
|
|
226
|
-
return node.parent.left;
|
|
227
|
-
// const MaybeComponent = (() => {})!;
|
|
228
|
-
// const MaybeComponent = (() => {}) as FunctionComponent;
|
|
229
|
-
// const MaybeComponent = (() => {}) satisfies FunctionComponent;
|
|
230
|
-
case isTypeAssertionExpression(node.parent):
|
|
231
|
-
return getFunctionId(node.parent);
|
|
232
|
-
}
|
|
233
|
-
return _;
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/node-format.ts
|
|
165
|
+
function getLiteralValueType(input) {
|
|
166
|
+
if (input === null) return "null";
|
|
167
|
+
return typeof input;
|
|
234
168
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
case (parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.CallExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator):
|
|
246
|
-
return [parent.parent.parent.parent, parent.parent.parent, parent.parent, parent, node];
|
|
247
|
-
case (parent.type === AST_NODE_TYPES.Property && parent.parent.type === AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator):
|
|
248
|
-
return [parent.parent.parent.parent, parent.parent.parent, parent.parent, parent, node];
|
|
249
|
-
case (parent.type === AST_NODE_TYPES.MethodDefinition && parent.parent.parent.type === AST_NODE_TYPES.ClassDeclaration):
|
|
250
|
-
return [parent.parent.parent, parent.parent, parent, node];
|
|
251
|
-
case (parent.type === AST_NODE_TYPES.PropertyDefinition && parent.parent.parent.type === AST_NODE_TYPES.ClassDeclaration):
|
|
252
|
-
return [parent.parent.parent, parent.parent, parent, node];
|
|
253
|
-
}
|
|
254
|
-
return _;
|
|
169
|
+
/**
|
|
170
|
+
* @internal
|
|
171
|
+
*/
|
|
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));
|
|
255
179
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
180
|
+
/**
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
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);
|
|
194
|
+
}
|
|
270
195
|
}
|
|
271
|
-
|
|
272
|
-
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
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;
|
|
273
209
|
}
|
|
274
|
-
|
|
275
|
-
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
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;
|
|
276
222
|
}
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region src/traverse-up.ts
|
|
277
226
|
function findParentNode(node, test) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
return _;
|
|
227
|
+
if (node == null) return unit;
|
|
228
|
+
let parent = node.parent;
|
|
229
|
+
while (parent != null && parent.type !== AST_NODE_TYPES.Program) {
|
|
230
|
+
if (test(parent)) return parent;
|
|
231
|
+
parent = parent.parent;
|
|
232
|
+
}
|
|
233
|
+
return unit;
|
|
287
234
|
}
|
|
235
|
+
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/expression-nested.ts
|
|
238
|
+
/**
|
|
239
|
+
* Get all nested identifiers in a expression like node
|
|
240
|
+
* @param node The node to get the nested identifiers from
|
|
241
|
+
* @returns All nested identifiers
|
|
242
|
+
*/
|
|
288
243
|
function getNestedIdentifiers(node) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
349
|
-
return identifiers;
|
|
244
|
+
const identifiers = [];
|
|
245
|
+
if (node.type === AST_NODE_TYPES.Identifier) identifiers.push(node);
|
|
246
|
+
if ("arguments" in node) {
|
|
247
|
+
const chunk = node.arguments.map(getNestedIdentifiers).flat(1);
|
|
248
|
+
identifiers.push(...chunk);
|
|
249
|
+
}
|
|
250
|
+
if ("elements" in node) {
|
|
251
|
+
const chunk = node.elements.filter((x) => x != null).map(getNestedIdentifiers).flat(1);
|
|
252
|
+
identifiers.push(...chunk);
|
|
253
|
+
}
|
|
254
|
+
if ("properties" in node) {
|
|
255
|
+
const chunk = node.properties.map(getNestedIdentifiers).flat(1);
|
|
256
|
+
identifiers.push(...chunk);
|
|
257
|
+
}
|
|
258
|
+
if ("expressions" in node) {
|
|
259
|
+
const chunk = node.expressions.map(getNestedIdentifiers).flat(1);
|
|
260
|
+
identifiers.push(...chunk);
|
|
261
|
+
}
|
|
262
|
+
if ("left" in node) {
|
|
263
|
+
const chunk = getNestedIdentifiers(node.left);
|
|
264
|
+
identifiers.push(...chunk);
|
|
265
|
+
}
|
|
266
|
+
if ("right" in node) {
|
|
267
|
+
const chunk = getNestedIdentifiers(node.right);
|
|
268
|
+
identifiers.push(...chunk);
|
|
269
|
+
}
|
|
270
|
+
if (node.type === AST_NODE_TYPES.Property) {
|
|
271
|
+
const chunk = getNestedIdentifiers(node.value);
|
|
272
|
+
identifiers.push(...chunk);
|
|
273
|
+
}
|
|
274
|
+
if (node.type === AST_NODE_TYPES.SpreadElement) {
|
|
275
|
+
const chunk = getNestedIdentifiers(node.argument);
|
|
276
|
+
identifiers.push(...chunk);
|
|
277
|
+
}
|
|
278
|
+
if (node.type === AST_NODE_TYPES.MemberExpression) {
|
|
279
|
+
const chunk = getNestedIdentifiers(node.object);
|
|
280
|
+
identifiers.push(...chunk);
|
|
281
|
+
}
|
|
282
|
+
if (node.type === AST_NODE_TYPES.UnaryExpression) {
|
|
283
|
+
const chunk = getNestedIdentifiers(node.argument);
|
|
284
|
+
identifiers.push(...chunk);
|
|
285
|
+
}
|
|
286
|
+
if (node.type === AST_NODE_TYPES.ChainExpression) {
|
|
287
|
+
const chunk = getNestedIdentifiers(node.expression);
|
|
288
|
+
identifiers.push(...chunk);
|
|
289
|
+
}
|
|
290
|
+
if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
291
|
+
const chunk = getNestedIdentifiers(node.expression);
|
|
292
|
+
identifiers.push(...chunk);
|
|
293
|
+
}
|
|
294
|
+
if (node.type === AST_NODE_TYPES.TSAsExpression) {
|
|
295
|
+
const chunk = getNestedIdentifiers(node.expression);
|
|
296
|
+
identifiers.push(...chunk);
|
|
297
|
+
}
|
|
298
|
+
if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
299
|
+
const chunk = getNestedIdentifiers(node.expression);
|
|
300
|
+
identifiers.push(...chunk);
|
|
301
|
+
}
|
|
302
|
+
return identifiers;
|
|
350
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Gets the nested return statements in the node that are within the same function
|
|
306
|
+
* @param node The AST node
|
|
307
|
+
* @returns The nested return statements in the node
|
|
308
|
+
*/
|
|
351
309
|
function getNestedReturnStatements(node) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
statements.push(node2);
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
return statements;
|
|
310
|
+
const statements = [];
|
|
311
|
+
const boundaryNode = isFunction(node) ? node : findParentNode(node, isFunction);
|
|
312
|
+
simpleTraverse(node, { enter(node$1) {
|
|
313
|
+
if (node$1.type !== AST_NODE_TYPES.ReturnStatement) return;
|
|
314
|
+
const parentFunction = findParentNode(node$1, isFunction);
|
|
315
|
+
if (parentFunction !== boundaryNode) return;
|
|
316
|
+
statements.push(node$1);
|
|
317
|
+
} });
|
|
318
|
+
return statements;
|
|
367
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Get all nested expressions of type T in an expression like node
|
|
322
|
+
* @param type The type of the expression to retrieve within the node
|
|
323
|
+
* @returns A partially applied function bound to a predicate of type T. The returned function can be called passing a
|
|
324
|
+
* node, and it will return an array of all nested expressions of type T.
|
|
325
|
+
*/
|
|
368
326
|
function getNestedExpressionsOfType(type) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return expressions;
|
|
449
|
-
};
|
|
327
|
+
const isNodeOfType = is(type);
|
|
328
|
+
return function(node) {
|
|
329
|
+
const boundGetNestedExpressionsOfType = getNestedExpressionsOfType(type);
|
|
330
|
+
const expressions = [];
|
|
331
|
+
if (isNodeOfType(node)) expressions.push(node);
|
|
332
|
+
if ("arguments" in node) {
|
|
333
|
+
const chunk = node.arguments.map(getNestedExpressionsOfType(type)).flat(1);
|
|
334
|
+
expressions.push(...chunk);
|
|
335
|
+
}
|
|
336
|
+
if ("expression" in node && node.expression !== true && node.expression !== false) {
|
|
337
|
+
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
338
|
+
expressions.push(...chunk);
|
|
339
|
+
}
|
|
340
|
+
if ("left" in node) {
|
|
341
|
+
const chunk = boundGetNestedExpressionsOfType(node.left);
|
|
342
|
+
expressions.push(...chunk);
|
|
343
|
+
}
|
|
344
|
+
if ("right" in node) {
|
|
345
|
+
const chunk = boundGetNestedExpressionsOfType(node.right);
|
|
346
|
+
expressions.push(...chunk);
|
|
347
|
+
}
|
|
348
|
+
if ("test" in node && node.test != null) {
|
|
349
|
+
const chunk = boundGetNestedExpressionsOfType(node.test);
|
|
350
|
+
expressions.push(...chunk);
|
|
351
|
+
}
|
|
352
|
+
if ("consequent" in node) {
|
|
353
|
+
const chunk = Array.isArray(node.consequent) ? node.consequent.map(boundGetNestedExpressionsOfType).flat(1) : boundGetNestedExpressionsOfType(node.consequent);
|
|
354
|
+
expressions.push(...chunk);
|
|
355
|
+
}
|
|
356
|
+
if ("alternate" in node && node.alternate != null) {
|
|
357
|
+
const chunk = Array.isArray(node.alternate) ? node.alternate.map(boundGetNestedExpressionsOfType).flat(1) : boundGetNestedExpressionsOfType(node.alternate);
|
|
358
|
+
expressions.push(...chunk);
|
|
359
|
+
}
|
|
360
|
+
if ("elements" in node) {
|
|
361
|
+
const chunk = node.elements.filter((x) => x != null).map(getNestedExpressionsOfType(type)).flat(1);
|
|
362
|
+
expressions.push(...chunk);
|
|
363
|
+
}
|
|
364
|
+
if ("properties" in node) {
|
|
365
|
+
const chunk = node.properties.map(boundGetNestedExpressionsOfType).flat(1);
|
|
366
|
+
expressions.push(...chunk);
|
|
367
|
+
}
|
|
368
|
+
if ("expressions" in node) {
|
|
369
|
+
const chunk = node.expressions.map(boundGetNestedExpressionsOfType).flat(1);
|
|
370
|
+
expressions.push(...chunk);
|
|
371
|
+
}
|
|
372
|
+
if (node.type === AST_NODE_TYPES.Property) {
|
|
373
|
+
const chunk = boundGetNestedExpressionsOfType(node.value);
|
|
374
|
+
expressions.push(...chunk);
|
|
375
|
+
}
|
|
376
|
+
if (node.type === AST_NODE_TYPES.SpreadElement) {
|
|
377
|
+
const chunk = boundGetNestedExpressionsOfType(node.argument);
|
|
378
|
+
expressions.push(...chunk);
|
|
379
|
+
}
|
|
380
|
+
if (node.type === AST_NODE_TYPES.MemberExpression) {
|
|
381
|
+
const chunk = boundGetNestedExpressionsOfType(node.object);
|
|
382
|
+
expressions.push(...chunk);
|
|
383
|
+
}
|
|
384
|
+
if (node.type === AST_NODE_TYPES.UnaryExpression) {
|
|
385
|
+
const chunk = boundGetNestedExpressionsOfType(node.argument);
|
|
386
|
+
expressions.push(...chunk);
|
|
387
|
+
}
|
|
388
|
+
if (node.type === AST_NODE_TYPES.ChainExpression) {
|
|
389
|
+
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
390
|
+
expressions.push(...chunk);
|
|
391
|
+
}
|
|
392
|
+
if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
393
|
+
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
394
|
+
expressions.push(...chunk);
|
|
395
|
+
}
|
|
396
|
+
if (node.type === AST_NODE_TYPES.TSAsExpression) {
|
|
397
|
+
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
398
|
+
expressions.push(...chunk);
|
|
399
|
+
}
|
|
400
|
+
if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
401
|
+
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
402
|
+
expressions.push(...chunk);
|
|
403
|
+
}
|
|
404
|
+
return expressions;
|
|
405
|
+
};
|
|
450
406
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
407
|
+
/**
|
|
408
|
+
* Get all nested new expressions in an expression like node
|
|
409
|
+
* @param node The node to get the nested new expressions from
|
|
410
|
+
* @returns All nested new expressions
|
|
411
|
+
*/
|
|
412
|
+
const getNestedNewExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.NewExpression);
|
|
413
|
+
/**
|
|
414
|
+
* Get all nested call expressions in a expression like node
|
|
415
|
+
* @param node The node to get the nested call expressions from
|
|
416
|
+
* @returns All nested call expressions
|
|
417
|
+
*/
|
|
418
|
+
const getNestedCallExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.CallExpression);
|
|
419
|
+
|
|
420
|
+
//#endregion
|
|
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;
|
|
455
440
|
}
|
|
456
|
-
|
|
457
|
-
|
|
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;
|
|
458
494
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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
|
+
});
|
|
474
511
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return false;
|
|
481
|
-
case (a.type === AST_NODE_TYPES.Literal && b.type === AST_NODE_TYPES.Literal):
|
|
482
|
-
return a.value === b.value;
|
|
483
|
-
case (a.type === AST_NODE_TYPES.TemplateElement && b.type === AST_NODE_TYPES.TemplateElement):
|
|
484
|
-
return a.value.raw === b.value.raw;
|
|
485
|
-
case (a.type === AST_NODE_TYPES.TemplateLiteral && b.type === AST_NODE_TYPES.TemplateLiteral): {
|
|
486
|
-
if (a.quasis.length !== b.quasis.length || a.expressions.length !== b.expressions.length) {
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
let i = a.quasis.length;
|
|
490
|
-
while (i--) {
|
|
491
|
-
if (a.quasis[i]?.value.raw !== b.quasis[i]?.value.raw) {
|
|
492
|
-
return false;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
i = a.expressions.length;
|
|
496
|
-
while (i--) {
|
|
497
|
-
const exprA = a.expressions[i];
|
|
498
|
-
const exprB = b.expressions[i];
|
|
499
|
-
if (!isNodeEqual(exprA, exprB)) {
|
|
500
|
-
return false;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
return true;
|
|
504
|
-
}
|
|
505
|
-
case (a.type === AST_NODE_TYPES.Identifier && b.type === AST_NODE_TYPES.Identifier):
|
|
506
|
-
return a.name === b.name;
|
|
507
|
-
case (a.type === AST_NODE_TYPES.PrivateIdentifier && b.type === AST_NODE_TYPES.PrivateIdentifier):
|
|
508
|
-
return a.name === b.name;
|
|
509
|
-
case (a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression):
|
|
510
|
-
return isNodeEqual(a.property, b.property) && isNodeEqual(a.object, b.object);
|
|
511
|
-
case (a.type === AST_NODE_TYPES.JSXAttribute && b.type === AST_NODE_TYPES.JSXAttribute): {
|
|
512
|
-
if (a.name.name !== b.name.name) {
|
|
513
|
-
return false;
|
|
514
|
-
}
|
|
515
|
-
if (a.value == null || b.value == null) {
|
|
516
|
-
return a.value === b.value;
|
|
517
|
-
}
|
|
518
|
-
return isNodeEqual(a.value, b.value);
|
|
519
|
-
}
|
|
520
|
-
case (a.type === AST_NODE_TYPES.ThisExpression && b.type === AST_NODE_TYPES.ThisExpression):
|
|
521
|
-
return true;
|
|
522
|
-
default:
|
|
523
|
-
return false;
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
function isProcessEnvNodeEnv(node) {
|
|
527
|
-
return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.Identifier && node.object.object.name === "process" && node.object.property.type === AST_NODE_TYPES.Identifier && node.object.property.name === "env" && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "NODE_ENV";
|
|
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;
|
|
528
517
|
}
|
|
529
|
-
function
|
|
530
|
-
|
|
531
|
-
if (node.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
532
|
-
if (node.operator !== operator) return false;
|
|
533
|
-
if (isProcessEnvNodeEnv(node.left) && isLiteral(node.right, "string")) {
|
|
534
|
-
return node.right.value === value;
|
|
535
|
-
}
|
|
536
|
-
if (isLiteral(node.left, "string") && isProcessEnvNodeEnv(node.right)) {
|
|
537
|
-
return node.left.value === value;
|
|
538
|
-
}
|
|
539
|
-
return false;
|
|
518
|
+
function isFunctionImmediatelyInvoked(node) {
|
|
519
|
+
return node.type !== AST_NODE_TYPES.FunctionDeclaration && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
|
|
540
520
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
return _;
|
|
521
|
+
|
|
522
|
+
//#endregion
|
|
523
|
+
//#region src/literal.ts
|
|
524
|
+
function isLiteral(node, type) {
|
|
525
|
+
if (node.type !== AST_NODE_TYPES.Literal) return false;
|
|
526
|
+
if (type == null) return true;
|
|
527
|
+
switch (type) {
|
|
528
|
+
case "boolean": return typeof node.value === "boolean";
|
|
529
|
+
case "null": return node.value === null;
|
|
530
|
+
case "number": return typeof node.value === "number";
|
|
531
|
+
case "regexp": return "regex" in node;
|
|
532
|
+
case "string": return typeof node.value === "string";
|
|
533
|
+
}
|
|
555
534
|
}
|
|
556
|
-
|
|
557
|
-
|
|
535
|
+
|
|
536
|
+
//#endregion
|
|
537
|
+
//#region src/misc.ts
|
|
538
|
+
/**
|
|
539
|
+
* Check if a node is multiline
|
|
540
|
+
* @param node The AST node to check
|
|
541
|
+
* @returns `true` if the node is multiline
|
|
542
|
+
*/
|
|
543
|
+
function isMultiLine(node) {
|
|
544
|
+
return node.loc.start.line !== node.loc.end.line;
|
|
558
545
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
546
|
+
/**
|
|
547
|
+
* Check if a node is a line break
|
|
548
|
+
* @param node The AST node to check
|
|
549
|
+
* @returns boolean
|
|
550
|
+
*/
|
|
551
|
+
function isLineBreak(node) {
|
|
552
|
+
return isOneOf([AST_NODE_TYPES.Literal, AST_NODE_TYPES.JSXText])(node) && typeof node.value === "string" && node.value.trim() === "" && isMultiLine(node);
|
|
562
553
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
return `${getLiteralValueType(node.value)} literal`;
|
|
569
|
-
}
|
|
570
|
-
if (isJSX(node)) {
|
|
571
|
-
return `JSX ${toLowerCase(delimiterCase(replace(node.type, "JSX", ""), delimiter))}`;
|
|
572
|
-
}
|
|
573
|
-
return toLowerCase(delimiterCase(node.type, delimiter));
|
|
554
|
+
|
|
555
|
+
//#endregion
|
|
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";
|
|
574
559
|
}
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
case AST_NODE_TYPES.JSXNamespacedName:
|
|
585
|
-
return `${node.namespace.name}:${node.name.name}`;
|
|
586
|
-
case AST_NODE_TYPES.JSXText:
|
|
587
|
-
return node.value;
|
|
588
|
-
case AST_NODE_TYPES.Literal:
|
|
589
|
-
return node.raw;
|
|
590
|
-
default:
|
|
591
|
-
return getText(node);
|
|
592
|
-
}
|
|
560
|
+
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/property-name.ts
|
|
563
|
+
function getPropertyName(node) {
|
|
564
|
+
if (isTypeExpression(node)) return getPropertyName(getUnderlyingExpression(node));
|
|
565
|
+
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) return node.name;
|
|
566
|
+
if (node.type === AST_NODE_TYPES.Literal) return String(node.value);
|
|
567
|
+
if (node.type === AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) return node.quasis[0]?.value.raw;
|
|
568
|
+
return unit;
|
|
593
569
|
}
|
|
594
570
|
|
|
595
|
-
|
|
571
|
+
//#endregion
|
|
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 };
|