@eslint-react/ast 5.2.1-next.1 → 5.2.2-beta.0
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/chunk-BYypO7fO.js +18 -0
- package/dist/index.d.ts +63 -493
- package/dist/index.js +157 -780
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,83 +1,105 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./chunk-BYypO7fO.js";
|
|
2
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
2
3
|
import { ASTUtils } from "@typescript-eslint/utils";
|
|
3
|
-
import { simpleTraverse } from "@typescript-eslint/typescript-estree";
|
|
4
4
|
import { delimiterCase, replace, toLowerCase } from "string-ts";
|
|
5
5
|
|
|
6
|
-
//#region src/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function
|
|
29
|
-
return
|
|
6
|
+
//#region src/check.ts
|
|
7
|
+
var check_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
directive: () => directive,
|
|
9
|
+
identifier: () => identifier,
|
|
10
|
+
is: () => is,
|
|
11
|
+
isClass: () => isClass,
|
|
12
|
+
isFunction: () => isFunction,
|
|
13
|
+
isJSX: () => isJSX,
|
|
14
|
+
isJSXElement: () => isJSXElement,
|
|
15
|
+
isJSXFragment: () => isJSXFragment,
|
|
16
|
+
isJSXLike: () => isJSXLike,
|
|
17
|
+
isJSXTagNameExpression: () => isJSXTagNameExpression,
|
|
18
|
+
isMethodOrProperty: () => isMethodOrProperty,
|
|
19
|
+
isOneOf: () => isOneOf,
|
|
20
|
+
isProperty: () => isProperty,
|
|
21
|
+
isTypeAssertionExpression: () => isTypeAssertionExpression,
|
|
22
|
+
isTypeExpression: () => isTypeExpression,
|
|
23
|
+
literal: () => literal,
|
|
24
|
+
thisExpression: () => thisExpression
|
|
25
|
+
});
|
|
26
|
+
const is = ASTUtils.isNodeOfType;
|
|
27
|
+
const isOneOf = ASTUtils.isNodeOfTypes;
|
|
28
|
+
function identifier(node, named) {
|
|
29
|
+
return node?.type === AST_NODE_TYPES.Identifier && (named == null || node.name === named);
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/literal-is.ts
|
|
34
|
-
function isLiteral(node, type) {
|
|
31
|
+
function literal(node, ofKind) {
|
|
35
32
|
if (node.type !== AST_NODE_TYPES.Literal) return false;
|
|
36
|
-
if (
|
|
37
|
-
switch (
|
|
33
|
+
if (ofKind == null) return true;
|
|
34
|
+
switch (ofKind) {
|
|
38
35
|
case "boolean": return typeof node.value === "boolean";
|
|
39
36
|
case "null": return node.value === null;
|
|
40
37
|
case "number": return typeof node.value === "number";
|
|
41
38
|
case "regexp": return "regex" in node;
|
|
42
39
|
case "string": return typeof node.value === "string";
|
|
40
|
+
default: return false;
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
//#region src/directive-is.ts
|
|
48
|
-
/**
|
|
49
|
-
* Check if a node is a directive expression statement
|
|
50
|
-
* @param node The node to check
|
|
51
|
-
* @returns True if the node is a directive, false otherwise
|
|
52
|
-
*/
|
|
53
|
-
function isDirective(node) {
|
|
54
|
-
return node.type === AST_NODE_TYPES.ExpressionStatement && node.directive != null;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Check if a node is a directive-like expression statement
|
|
58
|
-
* @param node The node to check
|
|
59
|
-
* @returns True if the node is a directive, false otherwise
|
|
60
|
-
*/
|
|
61
|
-
function isDirectiveLike(node) {
|
|
62
|
-
return node.type === AST_NODE_TYPES.ExpressionStatement && isLiteral(node.expression, "string") && isDirectiveName(node.expression.value);
|
|
43
|
+
function thisExpression(expression) {
|
|
44
|
+
return expression.type === AST_NODE_TYPES.ThisExpression;
|
|
63
45
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
46
|
+
const isFunction = isOneOf([
|
|
47
|
+
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
48
|
+
AST_NODE_TYPES.FunctionDeclaration,
|
|
49
|
+
AST_NODE_TYPES.FunctionExpression
|
|
50
|
+
]);
|
|
51
|
+
const isClass = isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]);
|
|
52
|
+
const isMethodOrProperty = isOneOf([AST_NODE_TYPES.PropertyDefinition, AST_NODE_TYPES.MethodDefinition]);
|
|
53
|
+
const isProperty = isOneOf([
|
|
54
|
+
AST_NODE_TYPES.PropertyDefinition,
|
|
55
|
+
AST_NODE_TYPES.TSIndexSignature,
|
|
56
|
+
AST_NODE_TYPES.TSParameterProperty,
|
|
57
|
+
AST_NODE_TYPES.TSPropertySignature
|
|
58
|
+
]);
|
|
59
|
+
const isJSXElement = is(AST_NODE_TYPES.JSXElement);
|
|
60
|
+
const isJSXFragment = is(AST_NODE_TYPES.JSXFragment);
|
|
61
|
+
const isJSXLike = isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment]);
|
|
62
|
+
const isJSXTagNameExpression = isOneOf([
|
|
63
|
+
AST_NODE_TYPES.JSXIdentifier,
|
|
64
|
+
AST_NODE_TYPES.JSXMemberExpression,
|
|
65
|
+
AST_NODE_TYPES.JSXNamespacedName
|
|
66
|
+
]);
|
|
67
|
+
const isJSX = isOneOf([
|
|
68
|
+
AST_NODE_TYPES.JSXAttribute,
|
|
69
|
+
AST_NODE_TYPES.JSXClosingElement,
|
|
70
|
+
AST_NODE_TYPES.JSXClosingFragment,
|
|
71
|
+
AST_NODE_TYPES.JSXElement,
|
|
72
|
+
AST_NODE_TYPES.JSXEmptyExpression,
|
|
73
|
+
AST_NODE_TYPES.JSXExpressionContainer,
|
|
74
|
+
AST_NODE_TYPES.JSXFragment,
|
|
75
|
+
AST_NODE_TYPES.JSXIdentifier,
|
|
76
|
+
AST_NODE_TYPES.JSXMemberExpression,
|
|
77
|
+
AST_NODE_TYPES.JSXNamespacedName,
|
|
78
|
+
AST_NODE_TYPES.JSXOpeningElement,
|
|
79
|
+
AST_NODE_TYPES.JSXOpeningFragment,
|
|
80
|
+
AST_NODE_TYPES.JSXSpreadAttribute,
|
|
81
|
+
AST_NODE_TYPES.JSXSpreadChild,
|
|
82
|
+
AST_NODE_TYPES.JSXText
|
|
83
|
+
]);
|
|
84
|
+
const isTypeExpression = isOneOf([
|
|
85
|
+
AST_NODE_TYPES.TSAsExpression,
|
|
86
|
+
AST_NODE_TYPES.TSTypeAssertion,
|
|
87
|
+
AST_NODE_TYPES.TSNonNullExpression,
|
|
88
|
+
AST_NODE_TYPES.TSSatisfiesExpression,
|
|
89
|
+
AST_NODE_TYPES.TSInstantiationExpression
|
|
90
|
+
]);
|
|
91
|
+
const isTypeAssertionExpression = isOneOf([
|
|
92
|
+
AST_NODE_TYPES.TSAsExpression,
|
|
93
|
+
AST_NODE_TYPES.TSTypeAssertion,
|
|
94
|
+
AST_NODE_TYPES.TSNonNullExpression,
|
|
95
|
+
AST_NODE_TYPES.TSSatisfiesExpression
|
|
96
|
+
]);
|
|
97
|
+
function directive(node) {
|
|
98
|
+
return node.type === AST_NODE_TYPES.ExpressionStatement && node.directive != null;
|
|
74
99
|
}
|
|
75
100
|
|
|
76
101
|
//#endregion
|
|
77
102
|
//#region ../../.pkgs/eff/dist/index.js
|
|
78
|
-
function or(a, b) {
|
|
79
|
-
return (data) => a(data) || b(data);
|
|
80
|
-
}
|
|
81
103
|
/**
|
|
82
104
|
* Creates a function that can be used in a data-last (aka `pipe`able) or
|
|
83
105
|
* data-first style.
|
|
@@ -195,606 +217,57 @@ const dual = function(arity, body) {
|
|
|
195
217
|
const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
|
|
196
218
|
|
|
197
219
|
//#endregion
|
|
198
|
-
//#region src/
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
* @returns True if the node is a function
|
|
215
|
-
*/
|
|
216
|
-
const isFunction = isOneOf([
|
|
217
|
-
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
218
|
-
AST_NODE_TYPES.FunctionDeclaration,
|
|
219
|
-
AST_NODE_TYPES.FunctionExpression
|
|
220
|
-
]);
|
|
221
|
-
/**
|
|
222
|
-
* Check if a node is a function type (including TypeScript function types)
|
|
223
|
-
* @param node The node to check
|
|
224
|
-
* @returns True if the node is a function type
|
|
225
|
-
*/
|
|
226
|
-
const isFunctionType = isOneOf([
|
|
227
|
-
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
228
|
-
AST_NODE_TYPES.FunctionDeclaration,
|
|
229
|
-
AST_NODE_TYPES.FunctionExpression,
|
|
230
|
-
AST_NODE_TYPES.TSCallSignatureDeclaration,
|
|
231
|
-
AST_NODE_TYPES.TSConstructSignatureDeclaration,
|
|
232
|
-
AST_NODE_TYPES.TSDeclareFunction,
|
|
233
|
-
AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
|
|
234
|
-
AST_NODE_TYPES.TSFunctionType,
|
|
235
|
-
AST_NODE_TYPES.TSMethodSignature
|
|
236
|
-
]);
|
|
237
|
-
/**
|
|
238
|
-
* Check if a node is a class declaration or expression
|
|
239
|
-
* @param node The node to check
|
|
240
|
-
* @returns True if the node is a class
|
|
241
|
-
*/
|
|
242
|
-
const isClass = isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]);
|
|
243
|
-
/**
|
|
244
|
-
* Check if a node is a method or property definition
|
|
245
|
-
* @param node The node to check
|
|
246
|
-
* @returns True if the node is a method or property definition
|
|
247
|
-
*/
|
|
248
|
-
const isMethodOrProperty = isOneOf([AST_NODE_TYPES.PropertyDefinition, AST_NODE_TYPES.MethodDefinition]);
|
|
249
|
-
/**
|
|
250
|
-
* Check if a node is a property-like node (including TypeScript property signatures)
|
|
251
|
-
* @param node The node to check
|
|
252
|
-
* @returns True if the node is a property
|
|
253
|
-
*/
|
|
254
|
-
const isProperty = isOneOf([
|
|
255
|
-
AST_NODE_TYPES.PropertyDefinition,
|
|
256
|
-
AST_NODE_TYPES.TSIndexSignature,
|
|
257
|
-
AST_NODE_TYPES.TSParameterProperty,
|
|
258
|
-
AST_NODE_TYPES.TSPropertySignature
|
|
259
|
-
]);
|
|
260
|
-
/**
|
|
261
|
-
* Check if a node is a JSX element
|
|
262
|
-
* @param node The node to check
|
|
263
|
-
* @returns True if the node is a JSX element
|
|
264
|
-
*/
|
|
265
|
-
const isJSXElement = is(AST_NODE_TYPES.JSXElement);
|
|
266
|
-
/**
|
|
267
|
-
* Check if a node is a JSX fragment
|
|
268
|
-
* @param node The node to check
|
|
269
|
-
* @returns True if the node is a JSX fragment
|
|
270
|
-
*/
|
|
271
|
-
const isJSXFragment = is(AST_NODE_TYPES.JSXFragment);
|
|
272
|
-
/**
|
|
273
|
-
* Check if a node is a JSX element or JSX fragment
|
|
274
|
-
*/
|
|
275
|
-
const isJSXElementLike = or(isJSXElement, isJSXFragment);
|
|
276
|
-
/**
|
|
277
|
-
* Check if a node is a JSX tag name expression (identifier, member expression, or namespaced name)
|
|
278
|
-
* @param node The node to check
|
|
279
|
-
* @returns True if the node is a JSX tag name expression
|
|
280
|
-
*/
|
|
281
|
-
const isJSXTagNameExpression = isOneOf([
|
|
282
|
-
AST_NODE_TYPES.JSXIdentifier,
|
|
283
|
-
AST_NODE_TYPES.JSXMemberExpression,
|
|
284
|
-
AST_NODE_TYPES.JSXNamespacedName
|
|
285
|
-
]);
|
|
286
|
-
/**
|
|
287
|
-
* Check if a node is a JSX-related node
|
|
288
|
-
* Note: This runtime guard includes JSXExpressionContainer which is commonly needed
|
|
289
|
-
* for AST traversals but not included in the TSESTreeJSX type union.
|
|
290
|
-
* @param node The node to check
|
|
291
|
-
* @returns True if the node is a JSX node
|
|
292
|
-
* @see TSESTreeJSX
|
|
293
|
-
*/
|
|
294
|
-
const isJSX = isOneOf([
|
|
295
|
-
AST_NODE_TYPES.JSXAttribute,
|
|
296
|
-
AST_NODE_TYPES.JSXClosingElement,
|
|
297
|
-
AST_NODE_TYPES.JSXClosingFragment,
|
|
298
|
-
AST_NODE_TYPES.JSXElement,
|
|
299
|
-
AST_NODE_TYPES.JSXEmptyExpression,
|
|
300
|
-
AST_NODE_TYPES.JSXExpressionContainer,
|
|
301
|
-
AST_NODE_TYPES.JSXFragment,
|
|
302
|
-
AST_NODE_TYPES.JSXIdentifier,
|
|
303
|
-
AST_NODE_TYPES.JSXMemberExpression,
|
|
304
|
-
AST_NODE_TYPES.JSXNamespacedName,
|
|
305
|
-
AST_NODE_TYPES.JSXOpeningElement,
|
|
306
|
-
AST_NODE_TYPES.JSXOpeningFragment,
|
|
307
|
-
AST_NODE_TYPES.JSXSpreadAttribute,
|
|
308
|
-
AST_NODE_TYPES.JSXSpreadChild,
|
|
309
|
-
AST_NODE_TYPES.JSXText
|
|
310
|
-
]);
|
|
311
|
-
/**
|
|
312
|
-
* Check if a node is a loop statement
|
|
313
|
-
* @param node The node to check
|
|
314
|
-
* @returns True if the node is a loop
|
|
315
|
-
*/
|
|
316
|
-
const isLoop = isOneOf([
|
|
317
|
-
AST_NODE_TYPES.DoWhileStatement,
|
|
318
|
-
AST_NODE_TYPES.ForInStatement,
|
|
319
|
-
AST_NODE_TYPES.ForOfStatement,
|
|
320
|
-
AST_NODE_TYPES.ForStatement,
|
|
321
|
-
AST_NODE_TYPES.WhileStatement
|
|
322
|
-
]);
|
|
323
|
-
/**
|
|
324
|
-
* Check if a node is a control flow statement (loop, if, or switch)
|
|
325
|
-
* @param node The node to check
|
|
326
|
-
* @returns True if the node is a control flow statement
|
|
327
|
-
*/
|
|
328
|
-
const isControlFlow = or(isLoop, isOneOf([AST_NODE_TYPES.IfStatement, AST_NODE_TYPES.SwitchStatement]));
|
|
329
|
-
/**
|
|
330
|
-
* Check if a node is a conditional expression or control flow statement
|
|
331
|
-
* @param node The node to check
|
|
332
|
-
* @returns True if the node is conditional
|
|
333
|
-
*/
|
|
334
|
-
const isConditional = or(isControlFlow, isOneOf([AST_NODE_TYPES.LogicalExpression, AST_NODE_TYPES.ConditionalExpression]));
|
|
335
|
-
/**
|
|
336
|
-
* Check if a node is a TypeScript type expression
|
|
337
|
-
* @param node The node to check
|
|
338
|
-
* @returns True if the node is a type expression
|
|
339
|
-
*/
|
|
340
|
-
const isTypeExpression = isOneOf([
|
|
341
|
-
AST_NODE_TYPES.TSAsExpression,
|
|
342
|
-
AST_NODE_TYPES.TSTypeAssertion,
|
|
343
|
-
AST_NODE_TYPES.TSNonNullExpression,
|
|
344
|
-
AST_NODE_TYPES.TSSatisfiesExpression,
|
|
345
|
-
AST_NODE_TYPES.TSInstantiationExpression
|
|
346
|
-
]);
|
|
347
|
-
/**
|
|
348
|
-
* Check if a node is a TypeScript type assertion expression
|
|
349
|
-
* @param node The node to check
|
|
350
|
-
* @returns True if the node is a type assertion expression
|
|
351
|
-
*/
|
|
352
|
-
const isTypeAssertionExpression = isOneOf([
|
|
353
|
-
AST_NODE_TYPES.TSAsExpression,
|
|
354
|
-
AST_NODE_TYPES.TSTypeAssertion,
|
|
355
|
-
AST_NODE_TYPES.TSNonNullExpression,
|
|
356
|
-
AST_NODE_TYPES.TSSatisfiesExpression
|
|
357
|
-
]);
|
|
358
|
-
|
|
359
|
-
//#endregion
|
|
360
|
-
//#region src/node-unwrap.ts
|
|
361
|
-
/**
|
|
362
|
-
* Unwraps any type expressions to get the underlying JavaScript expression node.
|
|
363
|
-
* Recursively processes nodes until a non-type expression is found.
|
|
364
|
-
* @param node The AST node to unwrap
|
|
365
|
-
* @returns The underlying JavaScript expression node
|
|
366
|
-
*/
|
|
367
|
-
function getUnderlyingExpression(node) {
|
|
368
|
-
if (isTypeExpression(node)) return getUnderlyingExpression(node.expression);
|
|
369
|
-
return node;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
//#endregion
|
|
373
|
-
//#region src/expression-is.ts
|
|
374
|
-
/**
|
|
375
|
-
* Check if the given expression is a 'this' expression
|
|
376
|
-
* Unwraps any type expressions before checking
|
|
377
|
-
*
|
|
378
|
-
* @param node The expression node to check
|
|
379
|
-
* @returns True if the expression is a 'this' expression, false otherwise
|
|
380
|
-
*/
|
|
381
|
-
function isThisExpressionLoose(node) {
|
|
382
|
-
return getUnderlyingExpression(node).type === AST_NODE_TYPES.ThisExpression;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
//#endregion
|
|
386
|
-
//#region src/node-traverse.ts
|
|
387
|
-
function findParent(node, test) {
|
|
388
|
-
if (node == null) return null;
|
|
389
|
-
let parent = node.parent;
|
|
390
|
-
while (parent != null && parent.type !== AST_NODE_TYPES.Program) {
|
|
391
|
-
if (test(parent)) return parent;
|
|
392
|
-
parent = parent.parent;
|
|
393
|
-
}
|
|
220
|
+
//#region src/extract.ts
|
|
221
|
+
var extract_exports = /* @__PURE__ */ __exportAll({
|
|
222
|
+
fullyQualifiedName: () => fullyQualifiedName,
|
|
223
|
+
humanReadableKind: () => humanReadableKind,
|
|
224
|
+
propertyName: () => propertyName,
|
|
225
|
+
rootIdentifier: () => rootIdentifier,
|
|
226
|
+
unwrapped: () => unwrapped
|
|
227
|
+
});
|
|
228
|
+
function unwrapped(from) {
|
|
229
|
+
if (isTypeExpression(from)) return unwrapped(from.expression);
|
|
230
|
+
return from;
|
|
231
|
+
}
|
|
232
|
+
function rootIdentifier(from) {
|
|
233
|
+
const node = unwrapped(from);
|
|
234
|
+
if (node.type === AST_NODE_TYPES.Identifier) return node;
|
|
235
|
+
if (node.type === AST_NODE_TYPES.MemberExpression) return rootIdentifier(node.object);
|
|
394
236
|
return null;
|
|
395
237
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
* @param node The node to get the nested identifiers from
|
|
402
|
-
* @returns All nested identifiers
|
|
403
|
-
*/
|
|
404
|
-
function getNestedIdentifiers(node) {
|
|
405
|
-
const identifiers = [];
|
|
406
|
-
if (node.type === AST_NODE_TYPES.Identifier) identifiers.push(node);
|
|
407
|
-
if ("arguments" in node) {
|
|
408
|
-
const chunk = node.arguments.flatMap(getNestedIdentifiers);
|
|
409
|
-
identifiers.push(...chunk);
|
|
410
|
-
}
|
|
411
|
-
if ("elements" in node) {
|
|
412
|
-
const chunk = node.elements.filter((x) => x != null).flatMap(getNestedIdentifiers);
|
|
413
|
-
identifiers.push(...chunk);
|
|
414
|
-
}
|
|
415
|
-
if ("properties" in node) {
|
|
416
|
-
const chunk = node.properties.flatMap(getNestedIdentifiers);
|
|
417
|
-
identifiers.push(...chunk);
|
|
418
|
-
}
|
|
419
|
-
if ("expressions" in node) {
|
|
420
|
-
const chunk = node.expressions.flatMap(getNestedIdentifiers);
|
|
421
|
-
identifiers.push(...chunk);
|
|
422
|
-
}
|
|
423
|
-
if ("left" in node) {
|
|
424
|
-
const chunk = getNestedIdentifiers(node.left);
|
|
425
|
-
identifiers.push(...chunk);
|
|
426
|
-
}
|
|
427
|
-
if ("right" in node) {
|
|
428
|
-
const chunk = getNestedIdentifiers(node.right);
|
|
429
|
-
identifiers.push(...chunk);
|
|
430
|
-
}
|
|
431
|
-
if (node.type === AST_NODE_TYPES.Property) {
|
|
432
|
-
const chunk = getNestedIdentifiers(node.value);
|
|
433
|
-
identifiers.push(...chunk);
|
|
434
|
-
}
|
|
435
|
-
if (node.type === AST_NODE_TYPES.SpreadElement) {
|
|
436
|
-
const chunk = getNestedIdentifiers(node.argument);
|
|
437
|
-
identifiers.push(...chunk);
|
|
438
|
-
}
|
|
439
|
-
if (node.type === AST_NODE_TYPES.MemberExpression) {
|
|
440
|
-
identifiers.push(...getNestedIdentifiers(node.object));
|
|
441
|
-
if (node.computed) identifiers.push(...getNestedIdentifiers(node.property));
|
|
442
|
-
}
|
|
443
|
-
if (node.type === AST_NODE_TYPES.UnaryExpression) {
|
|
444
|
-
const chunk = getNestedIdentifiers(node.argument);
|
|
445
|
-
identifiers.push(...chunk);
|
|
446
|
-
}
|
|
447
|
-
if (node.type === AST_NODE_TYPES.ChainExpression) {
|
|
448
|
-
const chunk = getNestedIdentifiers(node.expression);
|
|
449
|
-
identifiers.push(...chunk);
|
|
450
|
-
}
|
|
451
|
-
if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
452
|
-
const chunk = getNestedIdentifiers(node.expression);
|
|
453
|
-
identifiers.push(...chunk);
|
|
454
|
-
}
|
|
455
|
-
if (node.type === AST_NODE_TYPES.TSAsExpression) {
|
|
456
|
-
const chunk = getNestedIdentifiers(node.expression);
|
|
457
|
-
identifiers.push(...chunk);
|
|
458
|
-
}
|
|
459
|
-
if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
|
|
460
|
-
const chunk = getNestedIdentifiers(node.expression);
|
|
461
|
-
identifiers.push(...chunk);
|
|
462
|
-
}
|
|
463
|
-
if (node.type === AST_NODE_TYPES.ConditionalExpression) {
|
|
464
|
-
identifiers.push(...getNestedIdentifiers(node.test));
|
|
465
|
-
identifiers.push(...getNestedIdentifiers(node.consequent));
|
|
466
|
-
identifiers.push(...getNestedIdentifiers(node.alternate));
|
|
467
|
-
}
|
|
468
|
-
if (node.type === AST_NODE_TYPES.AwaitExpression) identifiers.push(...getNestedIdentifiers(node.argument));
|
|
469
|
-
if (node.type === AST_NODE_TYPES.YieldExpression && node.argument != null) identifiers.push(...getNestedIdentifiers(node.argument));
|
|
470
|
-
if (node.type === AST_NODE_TYPES.UpdateExpression) identifiers.push(...getNestedIdentifiers(node.argument));
|
|
471
|
-
if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) identifiers.push(...getNestedIdentifiers(node.callee));
|
|
472
|
-
if (node.type === AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
473
|
-
identifiers.push(...getNestedIdentifiers(node.tag));
|
|
474
|
-
identifiers.push(...getNestedIdentifiers(node.quasi));
|
|
475
|
-
}
|
|
476
|
-
if (node.type === AST_NODE_TYPES.ImportExpression) identifiers.push(...getNestedIdentifiers(node.source));
|
|
477
|
-
if (node.type === AST_NODE_TYPES.TSTypeAssertion) identifiers.push(...getNestedIdentifiers(node.expression));
|
|
478
|
-
if (node.type === AST_NODE_TYPES.TSInstantiationExpression) identifiers.push(...getNestedIdentifiers(node.expression));
|
|
479
|
-
return identifiers;
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* Gets the nested return statements in the node that are within the same function
|
|
483
|
-
* @param node The AST node
|
|
484
|
-
* @returns The nested return statements in the node
|
|
485
|
-
*/
|
|
486
|
-
function getNestedReturnStatements(node) {
|
|
487
|
-
const statements = [];
|
|
488
|
-
const boundaryNode = isFunction(node) ? node : findParent(node, isFunction);
|
|
489
|
-
simpleTraverse(node, { enter(node) {
|
|
490
|
-
if (node.type !== AST_NODE_TYPES.ReturnStatement) return;
|
|
491
|
-
if (findParent(node, isFunction) !== boundaryNode) return;
|
|
492
|
-
statements.push(node);
|
|
493
|
-
} });
|
|
494
|
-
return statements;
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Get all nested expressions of type T in an expression like node
|
|
498
|
-
* @param type The type of the expression to retrieve within the node
|
|
499
|
-
* @returns A partially applied function bound to a predicate of type AST. The returned function can be called passing a
|
|
500
|
-
* node, and it will return an array of all nested expressions of type AST.
|
|
501
|
-
*/
|
|
502
|
-
function getNestedExpressionsOfType(type) {
|
|
503
|
-
const isNodeOfType = is(type);
|
|
504
|
-
const recurse = (node) => {
|
|
505
|
-
const expressions = [];
|
|
506
|
-
if (isNodeOfType(node)) expressions.push(node);
|
|
507
|
-
if ("arguments" in node) {
|
|
508
|
-
const chunk = node.arguments.flatMap(recurse);
|
|
509
|
-
expressions.push(...chunk);
|
|
510
|
-
}
|
|
511
|
-
if ("expression" in node && node.expression !== true && node.expression !== false) {
|
|
512
|
-
const chunk = recurse(node.expression);
|
|
513
|
-
expressions.push(...chunk);
|
|
514
|
-
}
|
|
515
|
-
if ("left" in node) {
|
|
516
|
-
const chunk = recurse(node.left);
|
|
517
|
-
expressions.push(...chunk);
|
|
518
|
-
}
|
|
519
|
-
if ("right" in node) {
|
|
520
|
-
const chunk = recurse(node.right);
|
|
521
|
-
expressions.push(...chunk);
|
|
522
|
-
}
|
|
523
|
-
if ("test" in node && node.test != null) {
|
|
524
|
-
const chunk = recurse(node.test);
|
|
525
|
-
expressions.push(...chunk);
|
|
526
|
-
}
|
|
527
|
-
if ("consequent" in node) {
|
|
528
|
-
const chunk = Array.isArray(node.consequent) ? node.consequent.flatMap(recurse) : recurse(node.consequent);
|
|
529
|
-
expressions.push(...chunk);
|
|
530
|
-
}
|
|
531
|
-
if ("alternate" in node && node.alternate != null) {
|
|
532
|
-
const chunk = Array.isArray(node.alternate) ? node.alternate.flatMap(recurse) : recurse(node.alternate);
|
|
533
|
-
expressions.push(...chunk);
|
|
534
|
-
}
|
|
535
|
-
if ("elements" in node) {
|
|
536
|
-
const chunk = node.elements.filter((x) => x != null).flatMap(recurse);
|
|
537
|
-
expressions.push(...chunk);
|
|
538
|
-
}
|
|
539
|
-
if ("properties" in node) {
|
|
540
|
-
const chunk = node.properties.flatMap(recurse);
|
|
541
|
-
expressions.push(...chunk);
|
|
542
|
-
}
|
|
543
|
-
if ("expressions" in node) {
|
|
544
|
-
const chunk = node.expressions.flatMap(recurse);
|
|
545
|
-
expressions.push(...chunk);
|
|
546
|
-
}
|
|
547
|
-
if (node.type === AST_NODE_TYPES.Property) {
|
|
548
|
-
const chunk = recurse(node.value);
|
|
549
|
-
expressions.push(...chunk);
|
|
550
|
-
}
|
|
551
|
-
if (node.type === AST_NODE_TYPES.SpreadElement) {
|
|
552
|
-
const chunk = recurse(node.argument);
|
|
553
|
-
expressions.push(...chunk);
|
|
554
|
-
}
|
|
555
|
-
if (node.type === AST_NODE_TYPES.MemberExpression) {
|
|
556
|
-
expressions.push(...recurse(node.object));
|
|
557
|
-
if (node.computed) expressions.push(...recurse(node.property));
|
|
558
|
-
}
|
|
559
|
-
if (node.type === AST_NODE_TYPES.UnaryExpression) {
|
|
560
|
-
const chunk = recurse(node.argument);
|
|
561
|
-
expressions.push(...chunk);
|
|
562
|
-
}
|
|
563
|
-
if (node.type === AST_NODE_TYPES.AwaitExpression) expressions.push(...recurse(node.argument));
|
|
564
|
-
if (node.type === AST_NODE_TYPES.YieldExpression && node.argument != null) expressions.push(...recurse(node.argument));
|
|
565
|
-
if (node.type === AST_NODE_TYPES.UpdateExpression) expressions.push(...recurse(node.argument));
|
|
566
|
-
if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) expressions.push(...recurse(node.callee));
|
|
567
|
-
if (node.type === AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
568
|
-
expressions.push(...recurse(node.tag));
|
|
569
|
-
expressions.push(...recurse(node.quasi));
|
|
570
|
-
}
|
|
571
|
-
if (node.type === AST_NODE_TYPES.ImportExpression) expressions.push(...recurse(node.source));
|
|
572
|
-
return expressions;
|
|
573
|
-
};
|
|
574
|
-
return recurse;
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* Get all nested new expressions in an expression like node
|
|
578
|
-
* @param node The node to get the nested new expressions from
|
|
579
|
-
* @returns All nested new expressions
|
|
580
|
-
*/
|
|
581
|
-
const getNestedNewExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.NewExpression);
|
|
582
|
-
/**
|
|
583
|
-
* Get all nested call expressions in a expression like node
|
|
584
|
-
* @param node The node to get the nested call expressions from
|
|
585
|
-
* @returns All nested call expressions
|
|
586
|
-
*/
|
|
587
|
-
const getNestedCallExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.CallExpression);
|
|
588
|
-
|
|
589
|
-
//#endregion
|
|
590
|
-
//#region src/file-directive.ts
|
|
591
|
-
/**
|
|
592
|
-
* Get all directive expression statements from the top of a program AST node
|
|
593
|
-
* @param node The program AST node
|
|
594
|
-
* @returns The array of directive string literals (ex: "use strict")
|
|
595
|
-
*/
|
|
596
|
-
function getFileDirectives(node) {
|
|
597
|
-
const directives = [];
|
|
598
|
-
for (const stmt of node.body) {
|
|
599
|
-
if (!isDirective(stmt)) continue;
|
|
600
|
-
directives.push(stmt);
|
|
601
|
-
}
|
|
602
|
-
return directives;
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Check if a directive with the given name exists in the file directives
|
|
606
|
-
* @param node The program AST node
|
|
607
|
-
* @param name The directive name to check (ex: "use strict", "use memo", "use no memo")
|
|
608
|
-
* @returns True if the directive exists, false otherwise
|
|
609
|
-
*/
|
|
610
|
-
function isDirectiveInFile(node, name) {
|
|
611
|
-
return getFileDirectives(node).some((d) => d.directive === name);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
//#endregion
|
|
615
|
-
//#region src/function-directive.ts
|
|
616
|
-
/**
|
|
617
|
-
* Get all directive expression statements from the top of a function AST node
|
|
618
|
-
* @param node The function AST node
|
|
619
|
-
* @returns The array of directive string literals (ex: "use memo", "use no memo")
|
|
620
|
-
*/
|
|
621
|
-
function getFunctionDirectives(node) {
|
|
622
|
-
const directives = [];
|
|
623
|
-
if (node.body.type !== AST_NODE_TYPES.BlockStatement) return directives;
|
|
624
|
-
for (const stmt of node.body.body) {
|
|
625
|
-
if (!isDirective(stmt)) continue;
|
|
626
|
-
directives.push(stmt);
|
|
627
|
-
}
|
|
628
|
-
return directives;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Check if a directive with the given name exists in the function directives
|
|
632
|
-
* @param node The function AST node
|
|
633
|
-
* @param name The directive name to check (ex: "use memo", "use no memo")
|
|
634
|
-
* @returns True if the directive exists, false otherwise
|
|
635
|
-
*/
|
|
636
|
-
function isDirectiveInFunction(node, name) {
|
|
637
|
-
return getFunctionDirectives(node).some((d) => d.directive === name);
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
//#endregion
|
|
641
|
-
//#region src/function-id.ts
|
|
642
|
-
/**
|
|
643
|
-
* Gets the static name of a function AST node. For function declarations it is
|
|
644
|
-
* easy. For anonymous function expressions it is much harder. If you search for
|
|
645
|
-
* `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
|
|
646
|
-
* where JS gives anonymous function expressions names. We roughly detect the
|
|
647
|
-
* same AST nodes with some exceptions to better fit our use case.
|
|
648
|
-
*/
|
|
649
|
-
function getFunctionId(node) {
|
|
650
|
-
switch (true) {
|
|
651
|
-
case "id" in node && node.id != null: return node.id;
|
|
652
|
-
case node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init === node: return node.parent.id;
|
|
653
|
-
case node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=": return node.parent.left;
|
|
654
|
-
case node.parent.type === AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed: return node.parent.key;
|
|
655
|
-
case isMethodOrProperty(node.parent) && node.parent.value === node: return node.parent.key;
|
|
656
|
-
case node.parent.type === AST_NODE_TYPES.AssignmentPattern && node.parent.right === node: return node.parent.left;
|
|
657
|
-
case node.parent.type === AST_NODE_TYPES.ConditionalExpression: return getFunctionId(node.parent);
|
|
658
|
-
case isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
|
|
659
|
-
}
|
|
238
|
+
function propertyName(from) {
|
|
239
|
+
if (isTypeExpression(from)) return propertyName(unwrapped(from));
|
|
240
|
+
if (from.type === AST_NODE_TYPES.Identifier || from.type === AST_NODE_TYPES.PrivateIdentifier) return from.name;
|
|
241
|
+
if (from.type === AST_NODE_TYPES.Literal) return String(from.value);
|
|
242
|
+
if (from.type === AST_NODE_TYPES.TemplateLiteral && from.expressions.length === 0) return from.quasis[0]?.value.cooked ?? from.quasis[0]?.value.raw ?? null;
|
|
660
243
|
return null;
|
|
661
244
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
if (node.type === AST_NODE_TYPES.FunctionDeclaration) return [node];
|
|
674
|
-
let parent = node.parent;
|
|
675
|
-
while (isTypeExpression(parent)) parent = parent.parent;
|
|
676
|
-
switch (true) {
|
|
677
|
-
case parent.type === AST_NODE_TYPES.VariableDeclarator: return [
|
|
678
|
-
parent.parent,
|
|
679
|
-
parent,
|
|
680
|
-
node
|
|
681
|
-
];
|
|
682
|
-
case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
|
|
683
|
-
parent.parent.parent,
|
|
684
|
-
parent.parent,
|
|
685
|
-
parent,
|
|
686
|
-
node
|
|
687
|
-
];
|
|
688
|
-
case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.CallExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
|
|
689
|
-
parent.parent.parent.parent,
|
|
690
|
-
parent.parent.parent,
|
|
691
|
-
parent.parent,
|
|
692
|
-
parent,
|
|
693
|
-
node
|
|
694
|
-
];
|
|
695
|
-
case parent.type === AST_NODE_TYPES.Property && parent.parent.type === AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
|
|
696
|
-
parent.parent.parent.parent,
|
|
697
|
-
parent.parent.parent,
|
|
698
|
-
parent.parent,
|
|
699
|
-
parent,
|
|
700
|
-
node
|
|
701
|
-
];
|
|
702
|
-
case parent.type === AST_NODE_TYPES.MethodDefinition: return [
|
|
703
|
-
parent.parent.parent,
|
|
704
|
-
parent.parent,
|
|
705
|
-
parent,
|
|
706
|
-
node
|
|
707
|
-
];
|
|
708
|
-
case parent.type === AST_NODE_TYPES.PropertyDefinition: return [
|
|
709
|
-
parent.parent.parent,
|
|
710
|
-
parent.parent,
|
|
711
|
-
parent,
|
|
712
|
-
node
|
|
713
|
-
];
|
|
245
|
+
function fullyQualifiedName(from, using) {
|
|
246
|
+
switch (from.type) {
|
|
247
|
+
case AST_NODE_TYPES.Identifier:
|
|
248
|
+
case AST_NODE_TYPES.JSXIdentifier:
|
|
249
|
+
case AST_NODE_TYPES.PrivateIdentifier: return from.name;
|
|
250
|
+
case AST_NODE_TYPES.MemberExpression:
|
|
251
|
+
case AST_NODE_TYPES.JSXMemberExpression: return `${fullyQualifiedName(from.object, using)}.${fullyQualifiedName(from.property, using)}`;
|
|
252
|
+
case AST_NODE_TYPES.JSXNamespacedName: return `${from.namespace.name}:${from.name.name}`;
|
|
253
|
+
case AST_NODE_TYPES.JSXText: return from.value;
|
|
254
|
+
case AST_NODE_TYPES.Literal: return from.raw;
|
|
255
|
+
default: return using(from);
|
|
714
256
|
}
|
|
715
|
-
return null;
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
* Check if a specific function call exists in the function initialization path.
|
|
719
|
-
* Useful for detecting HOCs like React.memo, React.forwardRef, etc.
|
|
720
|
-
*
|
|
721
|
-
* @param callName The name of the call to check for (ex: "memo", "forwardRef")
|
|
722
|
-
* @param initPath The function initialization path to search in
|
|
723
|
-
* @returns True if the call exists in the path, false otherwise
|
|
724
|
-
*/
|
|
725
|
-
function hasCallInFunctionInitPath(callName, initPath) {
|
|
726
|
-
return initPath.some((node) => {
|
|
727
|
-
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
728
|
-
const { callee } = node;
|
|
729
|
-
if (callee.type === AST_NODE_TYPES.Identifier) return callee.name === callName;
|
|
730
|
-
if (callee.type === AST_NODE_TYPES.MemberExpression && "name" in callee.property) return callee.property.name === callName;
|
|
731
|
-
return false;
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
//#endregion
|
|
736
|
-
//#region src/function-is.ts
|
|
737
|
-
/**
|
|
738
|
-
* Check if a function is empty
|
|
739
|
-
* @param node The function node to check
|
|
740
|
-
* @returns True if the function is empty, false otherwise
|
|
741
|
-
*/
|
|
742
|
-
function isFunctionEmpty(node) {
|
|
743
|
-
return node.body.type === AST_NODE_TYPES.BlockStatement && node.body.body.length === 0;
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* Check if a function is immediately invoked
|
|
747
|
-
* @param node The function node to check
|
|
748
|
-
* @returns True if the function is immediately invoked, false otherwise
|
|
749
|
-
*/
|
|
750
|
-
function isFunctionImmediatelyInvoked(node) {
|
|
751
|
-
return node.type !== AST_NODE_TYPES.FunctionDeclaration && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
|
|
752
257
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
* @param node The node to check
|
|
759
|
-
* @param name The name to check
|
|
760
|
-
* @returns True if the node is an identifier, false otherwise
|
|
761
|
-
*/
|
|
762
|
-
function isIdentifier(node, name) {
|
|
763
|
-
return node != null && node.type === AST_NODE_TYPES.Identifier && (name == null || node.name === name);
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
//#endregion
|
|
767
|
-
//#region src/identifier-name.ts
|
|
768
|
-
/**
|
|
769
|
-
* Check if a string is a valid JavaScript identifier name
|
|
770
|
-
* Note: This only checks for ASCII identifiers. Unicode identifiers (e.g., `const 变量 = 1`)
|
|
771
|
-
* are not supported by this simple regex check.
|
|
772
|
-
* @param name The string to check
|
|
773
|
-
* @returns True if the string is a valid ASCII identifier name
|
|
774
|
-
*/
|
|
775
|
-
function isIdentifierName(name) {
|
|
776
|
-
return /^[A-Z$_][\w$]*$/i.test(name);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
//#endregion
|
|
780
|
-
//#region src/identifier-traverse.ts
|
|
781
|
-
/**
|
|
782
|
-
* Get the root identifier of a (possibly nested) member expression.
|
|
783
|
-
* For `a.b.c`, returns the `a` Identifier node.
|
|
784
|
-
* @param node The expression to analyze
|
|
785
|
-
* @returns The root Identifier node, or null if it cannot be determined (ex: non-identifier root)
|
|
786
|
-
*/
|
|
787
|
-
function getRootIdentifier(node) {
|
|
788
|
-
const expr = getUnderlyingExpression(node);
|
|
789
|
-
switch (expr.type) {
|
|
790
|
-
case AST_NODE_TYPES.Identifier: return expr;
|
|
791
|
-
case AST_NODE_TYPES.MemberExpression: return getRootIdentifier(expr.object);
|
|
792
|
-
default: return null;
|
|
258
|
+
function humanReadableKind(of, delimiter = " ") {
|
|
259
|
+
if (of.type === AST_NODE_TYPES.Literal) {
|
|
260
|
+
if ("regex" in of) return "RegExp literal";
|
|
261
|
+
if (of.value === null) return "null literal";
|
|
262
|
+
return `${typeof of.value} literal`;
|
|
793
263
|
}
|
|
264
|
+
if (isJSX(of)) return `JSX ${toLowerCase(delimiterCase(replace(of.type, "JSX", ""), delimiter))}`;
|
|
265
|
+
return toLowerCase(delimiterCase(of.type, delimiter));
|
|
794
266
|
}
|
|
795
267
|
|
|
796
268
|
//#endregion
|
|
797
|
-
//#region src/
|
|
269
|
+
//#region src/compare.ts
|
|
270
|
+
var compare_exports = /* @__PURE__ */ __exportAll({ areEqual: () => areEqual });
|
|
798
271
|
/**
|
|
799
272
|
* Check if two nodes are equal
|
|
800
273
|
* @param a node to compare
|
|
@@ -802,9 +275,9 @@ function getRootIdentifier(node) {
|
|
|
802
275
|
* @returns `true` if node equal
|
|
803
276
|
* @see https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/util/isNodeEqual.ts
|
|
804
277
|
*/
|
|
805
|
-
const
|
|
806
|
-
a = isTypeExpression(a) ?
|
|
807
|
-
b = isTypeExpression(b) ?
|
|
278
|
+
const areEqual = dual(2, (a, b) => {
|
|
279
|
+
a = isTypeExpression(a) ? unwrapped(a) : a;
|
|
280
|
+
b = isTypeExpression(b) ? unwrapped(b) : b;
|
|
808
281
|
switch (true) {
|
|
809
282
|
case a === b: return true;
|
|
810
283
|
case a.type !== b.type: return false;
|
|
@@ -818,80 +291,29 @@ const isNodeEqual = dual(2, (a, b) => {
|
|
|
818
291
|
while (i--) {
|
|
819
292
|
const exprA = a.expressions[i];
|
|
820
293
|
const exprB = b.expressions[i];
|
|
821
|
-
if (!
|
|
294
|
+
if (!areEqual(exprA, exprB)) return false;
|
|
822
295
|
}
|
|
823
296
|
return true;
|
|
824
297
|
}
|
|
825
298
|
case a.type === AST_NODE_TYPES.Identifier && b.type === AST_NODE_TYPES.Identifier: return a.name === b.name;
|
|
826
299
|
case a.type === AST_NODE_TYPES.PrivateIdentifier && b.type === AST_NODE_TYPES.PrivateIdentifier: return a.name === b.name;
|
|
827
|
-
case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return
|
|
300
|
+
case a.type === AST_NODE_TYPES.MemberExpression && b.type === AST_NODE_TYPES.MemberExpression: return areEqual(a.property, b.property) && areEqual(a.object, b.object);
|
|
828
301
|
case a.type === AST_NODE_TYPES.JSXIdentifier && b.type === AST_NODE_TYPES.JSXIdentifier: return a.name === b.name;
|
|
829
|
-
case a.type === AST_NODE_TYPES.JSXNamespacedName && b.type === AST_NODE_TYPES.JSXNamespacedName: return
|
|
830
|
-
case a.type === AST_NODE_TYPES.JSXMemberExpression && b.type === AST_NODE_TYPES.JSXMemberExpression: return
|
|
302
|
+
case a.type === AST_NODE_TYPES.JSXNamespacedName && b.type === AST_NODE_TYPES.JSXNamespacedName: return areEqual(a.namespace, b.namespace) && areEqual(a.name, b.name);
|
|
303
|
+
case a.type === AST_NODE_TYPES.JSXMemberExpression && b.type === AST_NODE_TYPES.JSXMemberExpression: return areEqual(a.object, b.object) && areEqual(a.property, b.property);
|
|
831
304
|
case a.type === AST_NODE_TYPES.JSXAttribute && b.type === AST_NODE_TYPES.JSXAttribute:
|
|
832
|
-
if (!
|
|
305
|
+
if (!areEqual(a.name, b.name)) return false;
|
|
833
306
|
if (a.value == null || b.value == null) return a.value === b.value;
|
|
834
|
-
return
|
|
307
|
+
return areEqual(a.value, b.value);
|
|
835
308
|
case a.type === AST_NODE_TYPES.ThisExpression && b.type === AST_NODE_TYPES.ThisExpression: return true;
|
|
836
309
|
default: return false;
|
|
837
310
|
}
|
|
838
311
|
});
|
|
839
312
|
|
|
840
313
|
//#endregion
|
|
841
|
-
//#region src/
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
if ("regex" in node) return "RegExp literal";
|
|
845
|
-
if (node.value === null) return "null literal";
|
|
846
|
-
return `${typeof node.value} literal`;
|
|
847
|
-
}
|
|
848
|
-
if (isJSX(node)) return `JSX ${toLowerCase(delimiterCase(replace(node.type, "JSX", ""), delimiter))}`;
|
|
849
|
-
return toLowerCase(delimiterCase(node.type, delimiter));
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
//#endregion
|
|
853
|
-
//#region src/node-line.ts
|
|
854
|
-
function isMultiLine(node) {
|
|
855
|
-
return node.loc.start.line !== node.loc.end.line;
|
|
856
|
-
}
|
|
857
|
-
function isLineBreak(node) {
|
|
858
|
-
return isOneOf([AST_NODE_TYPES.Literal, AST_NODE_TYPES.JSXText])(node) && typeof node.value === "string" && node.value.trim() === "" && isMultiLine(node);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
//#endregion
|
|
862
|
-
//#region src/node-name.ts
|
|
863
|
-
function getFullyQualifiedName(node, getText) {
|
|
864
|
-
switch (node.type) {
|
|
865
|
-
case AST_NODE_TYPES.Identifier:
|
|
866
|
-
case AST_NODE_TYPES.JSXIdentifier:
|
|
867
|
-
case AST_NODE_TYPES.PrivateIdentifier: return node.name;
|
|
868
|
-
case AST_NODE_TYPES.MemberExpression:
|
|
869
|
-
case AST_NODE_TYPES.JSXMemberExpression: return `${getFullyQualifiedName(node.object, getText)}.${getFullyQualifiedName(node.property, getText)}`;
|
|
870
|
-
case AST_NODE_TYPES.JSXNamespacedName: return `${node.namespace.name}:${node.name.name}`;
|
|
871
|
-
case AST_NODE_TYPES.JSXText: return node.value;
|
|
872
|
-
case AST_NODE_TYPES.Literal: return node.raw;
|
|
873
|
-
default: return getText(node);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
//#endregion
|
|
878
|
-
//#region src/node-selectors.ts
|
|
879
|
-
/**
|
|
880
|
-
* Selector for arrow function expressions with implicit return
|
|
881
|
-
*/
|
|
882
|
-
const SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION = "ArrowFunctionExpression[body.type!='BlockStatement']";
|
|
883
|
-
/**
|
|
884
|
-
* Selector for variable declarators with object destructuring
|
|
885
|
-
*/
|
|
886
|
-
const SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR = [
|
|
887
|
-
"VariableDeclarator",
|
|
888
|
-
"[id.type='ObjectPattern']",
|
|
889
|
-
"[init.type='Identifier']"
|
|
890
|
-
].join("");
|
|
891
|
-
/**
|
|
892
|
-
* Selector for assignment expressions that set displayName
|
|
893
|
-
*/
|
|
894
|
-
const SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION = [
|
|
314
|
+
//#region src/select.ts
|
|
315
|
+
var select_exports = /* @__PURE__ */ __exportAll({ displayNameAssignment: () => displayNameAssignment });
|
|
316
|
+
const displayNameAssignment = [
|
|
895
317
|
"AssignmentExpression",
|
|
896
318
|
"[operator='=']",
|
|
897
319
|
"[left.type='MemberExpression']",
|
|
@@ -899,71 +321,26 @@ const SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION = [
|
|
|
899
321
|
].join("");
|
|
900
322
|
|
|
901
323
|
//#endregion
|
|
902
|
-
//#region src/
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
* @param value The string literal value to compare against
|
|
916
|
-
* @returns True if the node is a binary expression that compares `process.env.NODE_ENV` with the specified value, false otherwise
|
|
917
|
-
*/
|
|
918
|
-
function isProcessEnvNodeEnvCompare(node, operator, value) {
|
|
919
|
-
if (node == null) return false;
|
|
920
|
-
if (node.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
921
|
-
if (node.operator !== operator) return false;
|
|
922
|
-
if (isProcessEnvNodeEnv(node.left) && isLiteral(node.right, "string")) return node.right.value === value;
|
|
923
|
-
if (isLiteral(node.left, "string") && isProcessEnvNodeEnv(node.right)) return node.left.value === value;
|
|
924
|
-
return false;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
//#endregion
|
|
928
|
-
//#region src/pattern-test-mock.ts
|
|
929
|
-
function isTestMock(node) {
|
|
930
|
-
return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "mock";
|
|
931
|
-
}
|
|
932
|
-
function isTestMockCallback(node) {
|
|
933
|
-
return node != null && isFunction(node) && node.parent.type === AST_NODE_TYPES.CallExpression && isTestMock(node.parent.callee) && node.parent.arguments[1] === node;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
//#endregion
|
|
937
|
-
//#region src/property-name.ts
|
|
938
|
-
/**
|
|
939
|
-
* Get the name of a property from a node
|
|
940
|
-
* Handles identifiers, private identifiers, literals, and template literals
|
|
941
|
-
* @param node The node to get the property name from
|
|
942
|
-
* @returns The property name or null if not determinable
|
|
943
|
-
*/
|
|
944
|
-
function getPropertyName(node) {
|
|
945
|
-
if (isTypeExpression(node)) return getPropertyName(getUnderlyingExpression(node));
|
|
946
|
-
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) return node.name;
|
|
947
|
-
if (node.type === AST_NODE_TYPES.Literal) return String(node.value);
|
|
948
|
-
if (node.type === AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? null;
|
|
324
|
+
//#region src/traverse.ts
|
|
325
|
+
var traverse_exports = /* @__PURE__ */ __exportAll({
|
|
326
|
+
findParent: () => findParent,
|
|
327
|
+
findProperty: () => findProperty
|
|
328
|
+
});
|
|
329
|
+
function findParent(of, where) {
|
|
330
|
+
if (of == null) return null;
|
|
331
|
+
let parent = of.parent;
|
|
332
|
+
while (parent?.type !== AST_NODE_TYPES.Program) {
|
|
333
|
+
if (parent == null) return null;
|
|
334
|
+
if (where(parent)) return parent;
|
|
335
|
+
parent = parent.parent;
|
|
336
|
+
}
|
|
949
337
|
return null;
|
|
950
338
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
* Note: This only handles inline object literals in spread elements. Properties from variables
|
|
957
|
-
* (e.g., `{...props}` where props is a variable) are not resolved.
|
|
958
|
-
* @param properties The properties of the object expression to traverse
|
|
959
|
-
* @param name The name of the property to find
|
|
960
|
-
* @returns The matching property node, or null if not found
|
|
961
|
-
*/
|
|
962
|
-
function findProperty(properties, name) {
|
|
963
|
-
for (const prop of properties) {
|
|
964
|
-
if (prop.type === AST_NODE_TYPES.Property && getPropertyName(prop.key) === name) return prop;
|
|
965
|
-
if (prop.type === AST_NODE_TYPES.SpreadElement && prop.argument.type === AST_NODE_TYPES.ObjectExpression) {
|
|
966
|
-
const found = findProperty(prop.argument.properties, name);
|
|
339
|
+
function findProperty(in_, named) {
|
|
340
|
+
for (const property of in_) {
|
|
341
|
+
if (property.type === AST_NODE_TYPES.Property && propertyName(property.key) === named) return property;
|
|
342
|
+
if (property.type === AST_NODE_TYPES.SpreadElement && property.argument.type === AST_NODE_TYPES.ObjectExpression) {
|
|
343
|
+
const found = findProperty(property.argument.properties, named);
|
|
967
344
|
if (found != null) return found;
|
|
968
345
|
}
|
|
969
346
|
}
|
|
@@ -971,4 +348,4 @@ function findProperty(properties, name) {
|
|
|
971
348
|
}
|
|
972
349
|
|
|
973
350
|
//#endregion
|
|
974
|
-
export {
|
|
351
|
+
export { check_exports as Check, compare_exports as Compare, extract_exports as Extract, select_exports as Select, traverse_exports as Traverse, is, isOneOf };
|