@eslint-react/core 1.23.2 → 1.23.3-next.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/index.js +96 -32
- package/dist/index.mjs +96 -32
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -34,10 +34,14 @@ var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
|
34
34
|
// src/component/component-collector.ts
|
|
35
35
|
function getElementRepresentName(node, context) {
|
|
36
36
|
const rawElementName = JSX4__namespace.getElementName(node);
|
|
37
|
-
if (rawElementName === rawElementName.toLowerCase())
|
|
37
|
+
if (rawElementName === rawElementName.toLowerCase()) {
|
|
38
|
+
return rawElementName;
|
|
39
|
+
}
|
|
38
40
|
const { components, polymorphicPropName } = shared.getSettingsFromContext(context);
|
|
39
41
|
const asElementName = components.get(rawElementName);
|
|
40
|
-
if (eff.isString(asElementName))
|
|
42
|
+
if (eff.isString(asElementName)) {
|
|
43
|
+
return asElementName;
|
|
44
|
+
}
|
|
41
45
|
return eff.F.pipe(
|
|
42
46
|
eff.O.fromNullable(polymorphicPropName),
|
|
43
47
|
eff.O.flatMap(JSX4__namespace.findPropInAttributes(node.attributes, context.sourceCode.getScope(node))),
|
|
@@ -82,15 +86,21 @@ function isFromReactMember(memberName, name) {
|
|
|
82
86
|
return (node, context) => {
|
|
83
87
|
const settings = shared.unsafeDecodeSettings(context.settings);
|
|
84
88
|
if (!settings.strictImportCheck) {
|
|
85
|
-
if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name)
|
|
86
|
-
|
|
89
|
+
if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (node.object.type === types.AST_NODE_TYPES.Identifier && node.object.name === memberName) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
87
95
|
if (node.object.type === types.AST_NODE_TYPES.MemberExpression && node.object.object.type === types.AST_NODE_TYPES.Identifier && node.object.property.type === types.AST_NODE_TYPES.Identifier) {
|
|
88
96
|
return node.object.property.name === memberName;
|
|
89
97
|
}
|
|
90
98
|
return false;
|
|
91
99
|
}
|
|
92
100
|
const initialScope = context.sourceCode.getScope(node);
|
|
93
|
-
if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name)
|
|
101
|
+
if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
94
104
|
if (node.object.type === types.AST_NODE_TYPES.Identifier && node.object.name === memberName) {
|
|
95
105
|
return isInitializedFromReact(node.object.name, initialScope, settings.importSource);
|
|
96
106
|
}
|
|
@@ -102,15 +112,23 @@ function isFromReactMember(memberName, name) {
|
|
|
102
112
|
}
|
|
103
113
|
function isCallFromReact(name) {
|
|
104
114
|
return eff.F.dual(2, (node, context) => {
|
|
105
|
-
if (node.type !== types.AST_NODE_TYPES.CallExpression)
|
|
106
|
-
|
|
115
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
if (!AST9__namespace.isOneOf([types.AST_NODE_TYPES.Identifier, types.AST_NODE_TYPES.MemberExpression])(node.callee)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
107
121
|
return isFromReact(name)(node.callee, context);
|
|
108
122
|
});
|
|
109
123
|
}
|
|
110
124
|
function isCallFromReactMember(pragmaMemberName, name) {
|
|
111
125
|
return eff.F.dual(2, (node, context) => {
|
|
112
|
-
if (node.type !== types.AST_NODE_TYPES.CallExpression)
|
|
113
|
-
|
|
126
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
if (!AST9__namespace.is(types.AST_NODE_TYPES.MemberExpression)(node.callee)) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
114
132
|
return isFromReactMember(pragmaMemberName, name)(node.callee, context);
|
|
115
133
|
});
|
|
116
134
|
}
|
|
@@ -181,8 +199,12 @@ function isReactHook(node) {
|
|
|
181
199
|
);
|
|
182
200
|
}
|
|
183
201
|
function isReactHookCall(node) {
|
|
184
|
-
if (node.type !== types.AST_NODE_TYPES.CallExpression)
|
|
185
|
-
|
|
202
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
if (node.callee.type === types.AST_NODE_TYPES.Identifier) {
|
|
206
|
+
return isReactHookName(node.callee.name);
|
|
207
|
+
}
|
|
186
208
|
if (node.callee.type === types.AST_NODE_TYPES.MemberExpression) {
|
|
187
209
|
return node.callee.property.type === types.AST_NODE_TYPES.Identifier && isReactHookName(node.callee.property.name);
|
|
188
210
|
}
|
|
@@ -229,7 +251,9 @@ function isReactHookCallWithNameAlias(name, context, alias) {
|
|
|
229
251
|
};
|
|
230
252
|
}
|
|
231
253
|
function isUseEffectCallLoose(node) {
|
|
232
|
-
if (node.type !== types.AST_NODE_TYPES.CallExpression)
|
|
254
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
233
257
|
switch (node.callee.type) {
|
|
234
258
|
case types.AST_NODE_TYPES.Identifier:
|
|
235
259
|
return /^use\w*Effect$/u.test(node.callee.name);
|
|
@@ -297,9 +321,13 @@ function useHookCollector() {
|
|
|
297
321
|
":function[type]": onFunctionEnter,
|
|
298
322
|
":function[type]:exit": onFunctionExit,
|
|
299
323
|
"CallExpression[type]"(node) {
|
|
300
|
-
if (!isReactHookCall(node))
|
|
324
|
+
if (!isReactHookCall(node)) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
301
327
|
const [fNode, hookId] = fStack.at(-1) ?? [];
|
|
302
|
-
if (!fNode || !hookId)
|
|
328
|
+
if (!fNode || !hookId) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
303
331
|
eff.F.pipe(
|
|
304
332
|
eff.O.Do,
|
|
305
333
|
eff.O.bind("id", () => hookId),
|
|
@@ -355,12 +383,16 @@ var ERFunctionComponentFlag = {
|
|
|
355
383
|
// Async: 1n << 4n,
|
|
356
384
|
};
|
|
357
385
|
function isComponentWrapperCall(node, context) {
|
|
358
|
-
if (node.type !== types.AST_NODE_TYPES.CallExpression)
|
|
386
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
359
389
|
return isMemoCall(node, context) || isForwardRefCall(node, context) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
360
390
|
}
|
|
361
391
|
function getFunctionComponentIdentifier(node, context) {
|
|
362
392
|
const functionId = AST9__namespace.getFunctionIdentifier(node);
|
|
363
|
-
if (eff.O.isSome(functionId))
|
|
393
|
+
if (eff.O.isSome(functionId)) {
|
|
394
|
+
return functionId;
|
|
395
|
+
}
|
|
364
396
|
const { parent } = node;
|
|
365
397
|
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(parent, context) && parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
366
398
|
return eff.O.some(parent.parent.id);
|
|
@@ -380,7 +412,9 @@ function isComponentName(name) {
|
|
|
380
412
|
return !!name && RE_COMPONENT_NAME.test(name);
|
|
381
413
|
}
|
|
382
414
|
function isClassComponent(node) {
|
|
383
|
-
if (!("superClass" in node && node.superClass))
|
|
415
|
+
if (!("superClass" in node && node.superClass)) {
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
384
418
|
const { superClass } = node;
|
|
385
419
|
return tsPattern.match(superClass).with({
|
|
386
420
|
type: types.AST_NODE_TYPES.Identifier,
|
|
@@ -422,7 +456,9 @@ function useComponentCollectorLegacy() {
|
|
|
422
456
|
}
|
|
423
457
|
};
|
|
424
458
|
const collect = (node) => {
|
|
425
|
-
if (!isClassComponent(node))
|
|
459
|
+
if (!isClassComponent(node)) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
426
462
|
const id2 = AST9__namespace.getClassIdentifier(node);
|
|
427
463
|
const key = getId();
|
|
428
464
|
const flag = isPureComponent(node) ? ERClassComponentFlag.PureComponent : ERClassComponentFlag.None;
|
|
@@ -465,7 +501,9 @@ var isRenderMethodLike = tsPattern.isMatching({
|
|
|
465
501
|
}
|
|
466
502
|
});
|
|
467
503
|
function isFunctionOfRenderMethod(node) {
|
|
468
|
-
if (!isRenderMethodLike(node.parent))
|
|
504
|
+
if (!isRenderMethodLike(node.parent)) {
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
469
507
|
return isClassComponent(node.parent.parent.parent);
|
|
470
508
|
}
|
|
471
509
|
function isInsideRenderMethod(node) {
|
|
@@ -535,11 +573,15 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
535
573
|
};
|
|
536
574
|
const onFunctionExit = () => {
|
|
537
575
|
const { key, node, isComponent } = functionEntries.at(-1) ?? {};
|
|
538
|
-
if (!key || !node || !isComponent)
|
|
576
|
+
if (!key || !node || !isComponent) {
|
|
577
|
+
return functionEntries.pop();
|
|
578
|
+
}
|
|
539
579
|
const shouldDrop = AST9__namespace.getNestedReturnStatements(node.body).slice().reverse().some((r) => {
|
|
540
580
|
return context.sourceCode.getScope(r).block === node && r.argument !== null && !JSX4__namespace.isJSXValue(r.argument, jsxCtx, hint);
|
|
541
581
|
});
|
|
542
|
-
if (shouldDrop)
|
|
582
|
+
if (shouldDrop) {
|
|
583
|
+
components.delete(key);
|
|
584
|
+
}
|
|
543
585
|
return functionEntries.pop();
|
|
544
586
|
};
|
|
545
587
|
const ctx = {
|
|
@@ -556,11 +598,15 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
556
598
|
":function[type]:exit": onFunctionExit,
|
|
557
599
|
"ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
|
|
558
600
|
const mbEntry = getCurrentFunction();
|
|
559
|
-
if (eff.O.isNone(mbEntry))
|
|
601
|
+
if (eff.O.isNone(mbEntry)) {
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
560
604
|
const entry = mbEntry.value;
|
|
561
605
|
const { body } = entry.node;
|
|
562
606
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4__namespace.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
563
|
-
if (!isComponent)
|
|
607
|
+
if (!isComponent) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
564
610
|
const initPath = AST9__namespace.getFunctionInitPath(entry.node);
|
|
565
611
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
566
612
|
const name = eff.O.flatMapNullable(id2, getComponentNameFromIdentifier);
|
|
@@ -581,29 +627,41 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
581
627
|
"AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"(node) {
|
|
582
628
|
const { left, right } = node;
|
|
583
629
|
const mbComponentName = tsPattern.match(left.object).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => eff.O.some(n.name)).otherwise(eff.O.none);
|
|
584
|
-
if (eff.O.isNone(mbComponentName))
|
|
630
|
+
if (eff.O.isNone(mbComponentName)) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
585
633
|
const componentName = mbComponentName.value;
|
|
586
634
|
const component = Array.from(components.values()).findLast(({ name }) => eff.O.exists(name, (n) => n === componentName));
|
|
587
|
-
if (!component)
|
|
635
|
+
if (!component) {
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
588
638
|
components.set(component._, {
|
|
589
639
|
...component,
|
|
590
640
|
displayName: eff.O.some(right)
|
|
591
641
|
});
|
|
592
642
|
},
|
|
593
643
|
"CallExpression[type]:exit"(node) {
|
|
594
|
-
if (!isReactHookCall(node))
|
|
644
|
+
if (!isReactHookCall(node)) {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
595
647
|
const mbEntry = getCurrentFunction();
|
|
596
|
-
if (eff.O.isNone(mbEntry))
|
|
648
|
+
if (eff.O.isNone(mbEntry)) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
597
651
|
const entry = mbEntry.value;
|
|
598
652
|
functionEntries.pop();
|
|
599
653
|
functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
|
|
600
654
|
},
|
|
601
655
|
"ReturnStatement[type]"(node) {
|
|
602
656
|
const mbEntry = getCurrentFunction();
|
|
603
|
-
if (eff.O.isNone(mbEntry))
|
|
657
|
+
if (eff.O.isNone(mbEntry)) {
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
604
660
|
const entry = mbEntry.value;
|
|
605
661
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4__namespace.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
606
|
-
if (!isComponent)
|
|
662
|
+
if (!isComponent) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
607
665
|
functionEntries.pop();
|
|
608
666
|
functionEntries.push({ ...entry, isComponent });
|
|
609
667
|
const initPath = AST9__namespace.getFunctionInitPath(entry.node);
|
|
@@ -630,10 +688,14 @@ function isSetupFunction(node) {
|
|
|
630
688
|
}
|
|
631
689
|
function isCleanupFunction(node) {
|
|
632
690
|
const nearestRet = eff.O.getOrNull(AST9__namespace.findParentNodeGuard(node, AST9__namespace.is(types.AST_NODE_TYPES.ReturnStatement)));
|
|
633
|
-
if (!nearestRet)
|
|
691
|
+
if (!nearestRet) {
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
634
694
|
const nearestFunction = eff.O.getOrNull(AST9__namespace.findParentNodeGuard(node, AST9__namespace.isFunction));
|
|
635
695
|
const nearestFunctionOfRet = eff.O.getOrNull(AST9__namespace.findParentNodeGuard(nearestRet, AST9__namespace.isFunction));
|
|
636
|
-
if (!nearestFunction || !nearestFunctionOfRet)
|
|
696
|
+
if (!nearestFunction || !nearestFunctionOfRet) {
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
637
699
|
return nearestFunction === nearestFunctionOfRet && isSetupFunction(nearestFunction);
|
|
638
700
|
}
|
|
639
701
|
var ERPhaseRelevance = types$1.birecord({
|
|
@@ -680,7 +742,9 @@ function isRenderFunctionLoose(node, context) {
|
|
|
680
742
|
);
|
|
681
743
|
}
|
|
682
744
|
function isRenderPropLoose(node, context) {
|
|
683
|
-
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier)
|
|
745
|
+
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier) {
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
684
748
|
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && AST9__namespace.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
|
|
685
749
|
}
|
|
686
750
|
function isThisSetState(node) {
|
package/dist/index.mjs
CHANGED
|
@@ -10,10 +10,14 @@ import { birecord } from '@eslint-react/types';
|
|
|
10
10
|
// src/component/component-collector.ts
|
|
11
11
|
function getElementRepresentName(node, context) {
|
|
12
12
|
const rawElementName = JSX4.getElementName(node);
|
|
13
|
-
if (rawElementName === rawElementName.toLowerCase())
|
|
13
|
+
if (rawElementName === rawElementName.toLowerCase()) {
|
|
14
|
+
return rawElementName;
|
|
15
|
+
}
|
|
14
16
|
const { components, polymorphicPropName } = getSettingsFromContext(context);
|
|
15
17
|
const asElementName = components.get(rawElementName);
|
|
16
|
-
if (isString(asElementName))
|
|
18
|
+
if (isString(asElementName)) {
|
|
19
|
+
return asElementName;
|
|
20
|
+
}
|
|
17
21
|
return F.pipe(
|
|
18
22
|
O.fromNullable(polymorphicPropName),
|
|
19
23
|
O.flatMap(JSX4.findPropInAttributes(node.attributes, context.sourceCode.getScope(node))),
|
|
@@ -58,15 +62,21 @@ function isFromReactMember(memberName, name) {
|
|
|
58
62
|
return (node, context) => {
|
|
59
63
|
const settings = unsafeDecodeSettings(context.settings);
|
|
60
64
|
if (!settings.strictImportCheck) {
|
|
61
|
-
if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== name)
|
|
62
|
-
|
|
65
|
+
if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== name) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (node.object.type === AST_NODE_TYPES.Identifier && node.object.name === memberName) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
63
71
|
if (node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.Identifier && node.object.property.type === AST_NODE_TYPES.Identifier) {
|
|
64
72
|
return node.object.property.name === memberName;
|
|
65
73
|
}
|
|
66
74
|
return false;
|
|
67
75
|
}
|
|
68
76
|
const initialScope = context.sourceCode.getScope(node);
|
|
69
|
-
if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== name)
|
|
77
|
+
if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== name) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
70
80
|
if (node.object.type === AST_NODE_TYPES.Identifier && node.object.name === memberName) {
|
|
71
81
|
return isInitializedFromReact(node.object.name, initialScope, settings.importSource);
|
|
72
82
|
}
|
|
@@ -78,15 +88,23 @@ function isFromReactMember(memberName, name) {
|
|
|
78
88
|
}
|
|
79
89
|
function isCallFromReact(name) {
|
|
80
90
|
return F.dual(2, (node, context) => {
|
|
81
|
-
if (node.type !== AST_NODE_TYPES.CallExpression)
|
|
82
|
-
|
|
91
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
if (!AST9.isOneOf([AST_NODE_TYPES.Identifier, AST_NODE_TYPES.MemberExpression])(node.callee)) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
83
97
|
return isFromReact(name)(node.callee, context);
|
|
84
98
|
});
|
|
85
99
|
}
|
|
86
100
|
function isCallFromReactMember(pragmaMemberName, name) {
|
|
87
101
|
return F.dual(2, (node, context) => {
|
|
88
|
-
if (node.type !== AST_NODE_TYPES.CallExpression)
|
|
89
|
-
|
|
102
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (!AST9.is(AST_NODE_TYPES.MemberExpression)(node.callee)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
90
108
|
return isFromReactMember(pragmaMemberName, name)(node.callee, context);
|
|
91
109
|
});
|
|
92
110
|
}
|
|
@@ -157,8 +175,12 @@ function isReactHook(node) {
|
|
|
157
175
|
);
|
|
158
176
|
}
|
|
159
177
|
function isReactHookCall(node) {
|
|
160
|
-
if (node.type !== AST_NODE_TYPES.CallExpression)
|
|
161
|
-
|
|
178
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
if (node.callee.type === AST_NODE_TYPES.Identifier) {
|
|
182
|
+
return isReactHookName(node.callee.name);
|
|
183
|
+
}
|
|
162
184
|
if (node.callee.type === AST_NODE_TYPES.MemberExpression) {
|
|
163
185
|
return node.callee.property.type === AST_NODE_TYPES.Identifier && isReactHookName(node.callee.property.name);
|
|
164
186
|
}
|
|
@@ -205,7 +227,9 @@ function isReactHookCallWithNameAlias(name, context, alias) {
|
|
|
205
227
|
};
|
|
206
228
|
}
|
|
207
229
|
function isUseEffectCallLoose(node) {
|
|
208
|
-
if (node.type !== AST_NODE_TYPES.CallExpression)
|
|
230
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
209
233
|
switch (node.callee.type) {
|
|
210
234
|
case AST_NODE_TYPES.Identifier:
|
|
211
235
|
return /^use\w*Effect$/u.test(node.callee.name);
|
|
@@ -273,9 +297,13 @@ function useHookCollector() {
|
|
|
273
297
|
":function[type]": onFunctionEnter,
|
|
274
298
|
":function[type]:exit": onFunctionExit,
|
|
275
299
|
"CallExpression[type]"(node) {
|
|
276
|
-
if (!isReactHookCall(node))
|
|
300
|
+
if (!isReactHookCall(node)) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
277
303
|
const [fNode, hookId] = fStack.at(-1) ?? [];
|
|
278
|
-
if (!fNode || !hookId)
|
|
304
|
+
if (!fNode || !hookId) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
279
307
|
F.pipe(
|
|
280
308
|
O.Do,
|
|
281
309
|
O.bind("id", () => hookId),
|
|
@@ -331,12 +359,16 @@ var ERFunctionComponentFlag = {
|
|
|
331
359
|
// Async: 1n << 4n,
|
|
332
360
|
};
|
|
333
361
|
function isComponentWrapperCall(node, context) {
|
|
334
|
-
if (node.type !== AST_NODE_TYPES.CallExpression)
|
|
362
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
335
365
|
return isMemoCall(node, context) || isForwardRefCall(node, context) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
336
366
|
}
|
|
337
367
|
function getFunctionComponentIdentifier(node, context) {
|
|
338
368
|
const functionId = AST9.getFunctionIdentifier(node);
|
|
339
|
-
if (O.isSome(functionId))
|
|
369
|
+
if (O.isSome(functionId)) {
|
|
370
|
+
return functionId;
|
|
371
|
+
}
|
|
340
372
|
const { parent } = node;
|
|
341
373
|
if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCall(parent, context) && parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === AST_NODE_TYPES.Identifier) {
|
|
342
374
|
return O.some(parent.parent.id);
|
|
@@ -356,7 +388,9 @@ function isComponentName(name) {
|
|
|
356
388
|
return !!name && RE_COMPONENT_NAME.test(name);
|
|
357
389
|
}
|
|
358
390
|
function isClassComponent(node) {
|
|
359
|
-
if (!("superClass" in node && node.superClass))
|
|
391
|
+
if (!("superClass" in node && node.superClass)) {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
360
394
|
const { superClass } = node;
|
|
361
395
|
return match(superClass).with({
|
|
362
396
|
type: AST_NODE_TYPES.Identifier,
|
|
@@ -398,7 +432,9 @@ function useComponentCollectorLegacy() {
|
|
|
398
432
|
}
|
|
399
433
|
};
|
|
400
434
|
const collect = (node) => {
|
|
401
|
-
if (!isClassComponent(node))
|
|
435
|
+
if (!isClassComponent(node)) {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
402
438
|
const id2 = AST9.getClassIdentifier(node);
|
|
403
439
|
const key = getId();
|
|
404
440
|
const flag = isPureComponent(node) ? ERClassComponentFlag.PureComponent : ERClassComponentFlag.None;
|
|
@@ -441,7 +477,9 @@ var isRenderMethodLike = isMatching({
|
|
|
441
477
|
}
|
|
442
478
|
});
|
|
443
479
|
function isFunctionOfRenderMethod(node) {
|
|
444
|
-
if (!isRenderMethodLike(node.parent))
|
|
480
|
+
if (!isRenderMethodLike(node.parent)) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
445
483
|
return isClassComponent(node.parent.parent.parent);
|
|
446
484
|
}
|
|
447
485
|
function isInsideRenderMethod(node) {
|
|
@@ -511,11 +549,15 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
511
549
|
};
|
|
512
550
|
const onFunctionExit = () => {
|
|
513
551
|
const { key, node, isComponent } = functionEntries.at(-1) ?? {};
|
|
514
|
-
if (!key || !node || !isComponent)
|
|
552
|
+
if (!key || !node || !isComponent) {
|
|
553
|
+
return functionEntries.pop();
|
|
554
|
+
}
|
|
515
555
|
const shouldDrop = AST9.getNestedReturnStatements(node.body).slice().reverse().some((r) => {
|
|
516
556
|
return context.sourceCode.getScope(r).block === node && r.argument !== null && !JSX4.isJSXValue(r.argument, jsxCtx, hint);
|
|
517
557
|
});
|
|
518
|
-
if (shouldDrop)
|
|
558
|
+
if (shouldDrop) {
|
|
559
|
+
components.delete(key);
|
|
560
|
+
}
|
|
519
561
|
return functionEntries.pop();
|
|
520
562
|
};
|
|
521
563
|
const ctx = {
|
|
@@ -532,11 +574,15 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
532
574
|
":function[type]:exit": onFunctionExit,
|
|
533
575
|
"ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
|
|
534
576
|
const mbEntry = getCurrentFunction();
|
|
535
|
-
if (O.isNone(mbEntry))
|
|
577
|
+
if (O.isNone(mbEntry)) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
536
580
|
const entry = mbEntry.value;
|
|
537
581
|
const { body } = entry.node;
|
|
538
582
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
539
|
-
if (!isComponent)
|
|
583
|
+
if (!isComponent) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
540
586
|
const initPath = AST9.getFunctionInitPath(entry.node);
|
|
541
587
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
542
588
|
const name = O.flatMapNullable(id2, getComponentNameFromIdentifier);
|
|
@@ -557,29 +603,41 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
557
603
|
"AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"(node) {
|
|
558
604
|
const { left, right } = node;
|
|
559
605
|
const mbComponentName = match(left.object).with({ type: AST_NODE_TYPES.Identifier }, (n) => O.some(n.name)).otherwise(O.none);
|
|
560
|
-
if (O.isNone(mbComponentName))
|
|
606
|
+
if (O.isNone(mbComponentName)) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
561
609
|
const componentName = mbComponentName.value;
|
|
562
610
|
const component = Array.from(components.values()).findLast(({ name }) => O.exists(name, (n) => n === componentName));
|
|
563
|
-
if (!component)
|
|
611
|
+
if (!component) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
564
614
|
components.set(component._, {
|
|
565
615
|
...component,
|
|
566
616
|
displayName: O.some(right)
|
|
567
617
|
});
|
|
568
618
|
},
|
|
569
619
|
"CallExpression[type]:exit"(node) {
|
|
570
|
-
if (!isReactHookCall(node))
|
|
620
|
+
if (!isReactHookCall(node)) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
571
623
|
const mbEntry = getCurrentFunction();
|
|
572
|
-
if (O.isNone(mbEntry))
|
|
624
|
+
if (O.isNone(mbEntry)) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
573
627
|
const entry = mbEntry.value;
|
|
574
628
|
functionEntries.pop();
|
|
575
629
|
functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
|
|
576
630
|
},
|
|
577
631
|
"ReturnStatement[type]"(node) {
|
|
578
632
|
const mbEntry = getCurrentFunction();
|
|
579
|
-
if (O.isNone(mbEntry))
|
|
633
|
+
if (O.isNone(mbEntry)) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
580
636
|
const entry = mbEntry.value;
|
|
581
637
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
582
|
-
if (!isComponent)
|
|
638
|
+
if (!isComponent) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
583
641
|
functionEntries.pop();
|
|
584
642
|
functionEntries.push({ ...entry, isComponent });
|
|
585
643
|
const initPath = AST9.getFunctionInitPath(entry.node);
|
|
@@ -606,10 +664,14 @@ function isSetupFunction(node) {
|
|
|
606
664
|
}
|
|
607
665
|
function isCleanupFunction(node) {
|
|
608
666
|
const nearestRet = O.getOrNull(AST9.findParentNodeGuard(node, AST9.is(AST_NODE_TYPES.ReturnStatement)));
|
|
609
|
-
if (!nearestRet)
|
|
667
|
+
if (!nearestRet) {
|
|
668
|
+
return false;
|
|
669
|
+
}
|
|
610
670
|
const nearestFunction = O.getOrNull(AST9.findParentNodeGuard(node, AST9.isFunction));
|
|
611
671
|
const nearestFunctionOfRet = O.getOrNull(AST9.findParentNodeGuard(nearestRet, AST9.isFunction));
|
|
612
|
-
if (!nearestFunction || !nearestFunctionOfRet)
|
|
672
|
+
if (!nearestFunction || !nearestFunctionOfRet) {
|
|
673
|
+
return false;
|
|
674
|
+
}
|
|
613
675
|
return nearestFunction === nearestFunctionOfRet && isSetupFunction(nearestFunction);
|
|
614
676
|
}
|
|
615
677
|
var ERPhaseRelevance = birecord({
|
|
@@ -656,7 +718,9 @@ function isRenderFunctionLoose(node, context) {
|
|
|
656
718
|
);
|
|
657
719
|
}
|
|
658
720
|
function isRenderPropLoose(node, context) {
|
|
659
|
-
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier)
|
|
721
|
+
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) {
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
660
724
|
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST9.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
|
|
661
725
|
}
|
|
662
726
|
function isThisSetState(node) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.3-next.0",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and Patterns.",
|
|
5
5
|
"homepage": "https://github.com/rEl1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"author": "Eva1ent<rel1cx@proton.me>",
|
|
16
|
+
"sideEffects": false,
|
|
16
17
|
"exports": {
|
|
17
18
|
".": {
|
|
18
19
|
"import": {
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"./package.json": "./package.json"
|
|
28
29
|
},
|
|
29
30
|
"main": "dist/index.js",
|
|
31
|
+
"module": "dist/index.mjs",
|
|
30
32
|
"types": "dist/index.d.ts",
|
|
31
33
|
"files": [
|
|
32
34
|
"dist",
|
|
@@ -38,12 +40,12 @@
|
|
|
38
40
|
"@typescript-eslint/types": "^8.19.1",
|
|
39
41
|
"@typescript-eslint/utils": "^8.19.1",
|
|
40
42
|
"ts-pattern": "^5.6.0",
|
|
41
|
-
"@eslint-react/ast": "1.23.
|
|
42
|
-
"@eslint-react/eff": "1.23.
|
|
43
|
-
"@eslint-react/
|
|
44
|
-
"@eslint-react/
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/types": "1.23.
|
|
43
|
+
"@eslint-react/ast": "1.23.3-next.0",
|
|
44
|
+
"@eslint-react/eff": "1.23.3-next.0",
|
|
45
|
+
"@eslint-react/jsx": "1.23.3-next.0",
|
|
46
|
+
"@eslint-react/shared": "1.23.3-next.0",
|
|
47
|
+
"@eslint-react/var": "1.23.3-next.0",
|
|
48
|
+
"@eslint-react/types": "1.23.3-next.0"
|
|
47
49
|
},
|
|
48
50
|
"devDependencies": {
|
|
49
51
|
"tsup": "^8.3.5",
|
|
@@ -53,8 +55,6 @@
|
|
|
53
55
|
"bun": ">=1.0.15",
|
|
54
56
|
"node": ">=18.18.0"
|
|
55
57
|
},
|
|
56
|
-
"sideEffects": false,
|
|
57
|
-
"module": "dist/index.mjs",
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "tsup",
|
|
60
60
|
"build:docs": "typedoc",
|