@eslint-react/core 1.23.3-next.8 → 1.24.0-beta.1
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.mts +48 -46
- package/dist/index.d.ts +48 -46
- package/dist/index.js +182 -205
- package/dist/index.mjs +136 -159
- package/package.json +10 -10
package/dist/index.mjs
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
import * as AST8 from '@eslint-react/ast';
|
|
2
|
-
import {
|
|
2
|
+
import { flip, birecord, dual, _, returnFalse } from '@eslint-react/eff';
|
|
3
3
|
import * as JSX4 from '@eslint-react/jsx';
|
|
4
4
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
5
|
-
import { match } from 'ts-pattern';
|
|
6
|
-
import { getSettingsFromContext, unsafeDecodeSettings } from '@eslint-react/shared';
|
|
7
5
|
import * as VAR from '@eslint-react/var';
|
|
8
|
-
import {
|
|
6
|
+
import { unsafeDecodeSettings } from '@eslint-react/shared';
|
|
9
7
|
|
|
10
8
|
// src/component/component-collector.ts
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
O.fromNullable(polymorphicPropName),
|
|
23
|
-
O.flatMap(JSX4.findPropInAttributes(node.attributes, context.sourceCode.getScope(node))),
|
|
24
|
-
O.flatMap((attr) => JSX4.getPropValue(attr, context.sourceCode.getScope(attr))),
|
|
25
|
-
O.filter(isString),
|
|
26
|
-
O.getOrElse(() => rawElementName)
|
|
9
|
+
function getElementNameAndRepresentName(node, context, polymorphicPropName, additionalComponents = []) {
|
|
10
|
+
const name = JSX4.getElementName(node);
|
|
11
|
+
if (name === name.toLowerCase()) return [name, name];
|
|
12
|
+
const component = additionalComponents.findLast((c) => c.name === name || c.re.test(name));
|
|
13
|
+
if (component != null) return [name, component.as];
|
|
14
|
+
if (polymorphicPropName == null) return [name, name];
|
|
15
|
+
const initialScope = context.sourceCode.getScope(node);
|
|
16
|
+
const polymorphicProp = JSX4.findPropInAttributes(
|
|
17
|
+
polymorphicPropName,
|
|
18
|
+
initialScope,
|
|
19
|
+
node.attributes
|
|
27
20
|
);
|
|
21
|
+
if (polymorphicProp == null) return [name, name];
|
|
22
|
+
const polymorphicName = VAR.toResolved(JSX4.getPropValue(polymorphicProp, initialScope)).value;
|
|
23
|
+
if (typeof polymorphicName === "string") {
|
|
24
|
+
return [name, polymorphicName];
|
|
25
|
+
}
|
|
26
|
+
return [name, name];
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
// src/utils/get-id.ts
|
|
@@ -87,7 +86,7 @@ function isFromReactMember(memberName, name) {
|
|
|
87
86
|
};
|
|
88
87
|
}
|
|
89
88
|
function isCallFromReact(name) {
|
|
90
|
-
return
|
|
89
|
+
return dual(2, (node, context) => {
|
|
91
90
|
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
92
91
|
return false;
|
|
93
92
|
}
|
|
@@ -98,7 +97,7 @@ function isCallFromReact(name) {
|
|
|
98
97
|
});
|
|
99
98
|
}
|
|
100
99
|
function isCallFromReactMember(pragmaMemberName, name) {
|
|
101
|
-
return
|
|
100
|
+
return dual(2, (node, context) => {
|
|
102
101
|
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
103
102
|
return false;
|
|
104
103
|
}
|
|
@@ -111,10 +110,10 @@ function isCallFromReactMember(pragmaMemberName, name) {
|
|
|
111
110
|
|
|
112
111
|
// src/utils/is-react-api.ts
|
|
113
112
|
function isReactAPIWithName(name, member) {
|
|
114
|
-
return member
|
|
113
|
+
return member != null ? isFromReactMember(name, member) : isFromReact(name);
|
|
115
114
|
}
|
|
116
115
|
function isReactAPICallWithName(name, member) {
|
|
117
|
-
return member
|
|
116
|
+
return member != null ? isCallFromReactMember(name, member) : isCallFromReact(name);
|
|
118
117
|
}
|
|
119
118
|
var isChildrenCount = isReactAPIWithName("Children", "count");
|
|
120
119
|
var isChildrenForEach = isReactAPIWithName("Children", "forEach");
|
|
@@ -141,23 +140,17 @@ var isMemoCall = isReactAPICallWithName("memo");
|
|
|
141
140
|
|
|
142
141
|
// src/element/hierarchy.ts
|
|
143
142
|
function isInsideCreateElementProps(node, context) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
O.exists(({ arg1, prop }) => prop === arg1)
|
|
150
|
-
);
|
|
143
|
+
const call = AST8.findParentNodeGuard(node, isCreateElementCall(context));
|
|
144
|
+
if (call == null) return false;
|
|
145
|
+
const prop = AST8.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.ObjectExpression));
|
|
146
|
+
if (prop == null) return false;
|
|
147
|
+
return prop === call.arguments[1];
|
|
151
148
|
}
|
|
152
149
|
function isChildrenOfCreateElement(node, context) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
O.exists(
|
|
158
|
-
(n) => n.arguments.slice(2).some((arg) => arg === node)
|
|
159
|
-
)
|
|
160
|
-
);
|
|
150
|
+
const parent = node.parent;
|
|
151
|
+
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
152
|
+
if (!isCreateElementCall(parent, context)) return false;
|
|
153
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
161
154
|
}
|
|
162
155
|
|
|
163
156
|
// src/hook/hook-name.ts
|
|
@@ -168,13 +161,12 @@ function isReactHookName(name) {
|
|
|
168
161
|
|
|
169
162
|
// src/hook/is.ts
|
|
170
163
|
function isReactHook(node) {
|
|
171
|
-
return
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
O.exists(isReactHookName)
|
|
175
|
-
);
|
|
164
|
+
if (node == null) return _;
|
|
165
|
+
const id2 = AST8.getFunctionIdentifier(node);
|
|
166
|
+
return id2?.name != null && isReactHookName(id2.name);
|
|
176
167
|
}
|
|
177
168
|
function isReactHookCall(node) {
|
|
169
|
+
if (node == null) return false;
|
|
178
170
|
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
179
171
|
return false;
|
|
180
172
|
}
|
|
@@ -187,6 +179,7 @@ function isReactHookCall(node) {
|
|
|
187
179
|
return false;
|
|
188
180
|
}
|
|
189
181
|
function isReactHookCallWithName(node, context) {
|
|
182
|
+
if (node == null) return returnFalse;
|
|
190
183
|
const settings = unsafeDecodeSettings(context.settings);
|
|
191
184
|
return (name) => {
|
|
192
185
|
const initialScope = context.sourceCode.getScope(node);
|
|
@@ -201,6 +194,7 @@ function isReactHookCallWithName(node, context) {
|
|
|
201
194
|
};
|
|
202
195
|
}
|
|
203
196
|
function isReactHookCallWithNameLoose(node) {
|
|
197
|
+
if (node == null) return returnFalse;
|
|
204
198
|
return (name) => {
|
|
205
199
|
switch (node.callee.type) {
|
|
206
200
|
case AST_NODE_TYPES.Identifier:
|
|
@@ -227,6 +221,7 @@ function isReactHookCallWithNameAlias(name, context, alias) {
|
|
|
227
221
|
};
|
|
228
222
|
}
|
|
229
223
|
function isUseEffectCallLoose(node) {
|
|
224
|
+
if (node == null) return false;
|
|
230
225
|
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
231
226
|
return false;
|
|
232
227
|
}
|
|
@@ -239,35 +234,35 @@ function isUseEffectCallLoose(node) {
|
|
|
239
234
|
return false;
|
|
240
235
|
}
|
|
241
236
|
}
|
|
242
|
-
var isUseCallbackCall =
|
|
243
|
-
var isUseContextCall =
|
|
244
|
-
var isUseDebugValueCall =
|
|
245
|
-
var isUseDeferredValueCall =
|
|
246
|
-
var isUseEffectCall =
|
|
247
|
-
var isUseIdCall =
|
|
248
|
-
var isUseImperativeHandleCall =
|
|
249
|
-
var isUseInsertionEffectCall =
|
|
250
|
-
var isUseLayoutEffectCall =
|
|
251
|
-
var isUseMemoCall =
|
|
252
|
-
var isUseReducerCall =
|
|
253
|
-
var isUseRefCall =
|
|
254
|
-
var isUseStateCall =
|
|
255
|
-
var isUseSyncExternalStoreCall =
|
|
256
|
-
var isUseTransitionCall =
|
|
237
|
+
var isUseCallbackCall = flip(isReactHookCallWithName)("useCallback");
|
|
238
|
+
var isUseContextCall = flip(isReactHookCallWithName)("useContext");
|
|
239
|
+
var isUseDebugValueCall = flip(isReactHookCallWithName)("useDebugValue");
|
|
240
|
+
var isUseDeferredValueCall = flip(isReactHookCallWithName)("useDeferredValue");
|
|
241
|
+
var isUseEffectCall = flip(isReactHookCallWithName)("useEffect");
|
|
242
|
+
var isUseIdCall = flip(isReactHookCallWithName)("useId");
|
|
243
|
+
var isUseImperativeHandleCall = flip(isReactHookCallWithName)("useImperativeHandle");
|
|
244
|
+
var isUseInsertionEffectCall = flip(isReactHookCallWithName)("useInsertionEffect");
|
|
245
|
+
var isUseLayoutEffectCall = flip(isReactHookCallWithName)("useLayoutEffect");
|
|
246
|
+
var isUseMemoCall = flip(isReactHookCallWithName)("useMemo");
|
|
247
|
+
var isUseReducerCall = flip(isReactHookCallWithName)("useReducer");
|
|
248
|
+
var isUseRefCall = flip(isReactHookCallWithName)("useRef");
|
|
249
|
+
var isUseStateCall = flip(isReactHookCallWithName)("useState");
|
|
250
|
+
var isUseSyncExternalStoreCall = flip(isReactHookCallWithName)("useSyncExternalStore");
|
|
251
|
+
var isUseTransitionCall = flip(isReactHookCallWithName)("useTransition");
|
|
257
252
|
|
|
258
253
|
// src/hook/hierarchy.ts
|
|
259
254
|
function isInsideReactHook(node) {
|
|
260
|
-
return
|
|
255
|
+
return isReactHook(AST8.findParentNodeGuard(node, AST8.isFunction));
|
|
261
256
|
}
|
|
262
257
|
function useHookCollector() {
|
|
263
258
|
const hooks = /* @__PURE__ */ new Map();
|
|
264
|
-
const
|
|
259
|
+
const fEntries = [];
|
|
265
260
|
const onFunctionEnter = (node) => {
|
|
266
261
|
const id2 = AST8.getFunctionIdentifier(node);
|
|
267
|
-
const name =
|
|
268
|
-
if (
|
|
262
|
+
const name = id2?.name;
|
|
263
|
+
if (name != null && isReactHookName(name)) {
|
|
269
264
|
const key = getId();
|
|
270
|
-
|
|
265
|
+
fEntries.push({ key, node });
|
|
271
266
|
hooks.set(key, {
|
|
272
267
|
_: key,
|
|
273
268
|
id: id2,
|
|
@@ -280,13 +275,14 @@ function useHookCollector() {
|
|
|
280
275
|
});
|
|
281
276
|
return;
|
|
282
277
|
}
|
|
283
|
-
|
|
278
|
+
fEntries.push({ key: _, node });
|
|
284
279
|
};
|
|
285
280
|
const onFunctionExit = () => {
|
|
286
|
-
|
|
281
|
+
fEntries.pop();
|
|
287
282
|
};
|
|
288
283
|
const ctx = {
|
|
289
|
-
|
|
284
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
285
|
+
getAllHooks(node) {
|
|
290
286
|
return hooks;
|
|
291
287
|
},
|
|
292
288
|
getCurrentHooks() {
|
|
@@ -300,24 +296,21 @@ function useHookCollector() {
|
|
|
300
296
|
if (!isReactHookCall(node)) {
|
|
301
297
|
return;
|
|
302
298
|
}
|
|
303
|
-
const
|
|
304
|
-
if (
|
|
299
|
+
const fEntry = fEntries.at(-1);
|
|
300
|
+
if (fEntry?.key == null) {
|
|
305
301
|
return;
|
|
306
302
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
});
|
|
319
|
-
})
|
|
320
|
-
);
|
|
303
|
+
const hook = hooks.get(fEntry.key);
|
|
304
|
+
if (hook == null) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
hooks.set(hook._, {
|
|
308
|
+
...hook,
|
|
309
|
+
hookCalls: [
|
|
310
|
+
...hook.hookCalls,
|
|
311
|
+
node
|
|
312
|
+
]
|
|
313
|
+
});
|
|
321
314
|
}
|
|
322
315
|
};
|
|
323
316
|
return { ctx, listeners };
|
|
@@ -366,22 +359,21 @@ function isComponentWrapperCall(node, context) {
|
|
|
366
359
|
}
|
|
367
360
|
function getFunctionComponentIdentifier(node, context) {
|
|
368
361
|
const functionId = AST8.getFunctionIdentifier(node);
|
|
369
|
-
if (
|
|
362
|
+
if (functionId != null) {
|
|
370
363
|
return functionId;
|
|
371
364
|
}
|
|
372
365
|
const { parent } = node;
|
|
373
366
|
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) {
|
|
374
|
-
return
|
|
367
|
+
return parent.parent.id;
|
|
375
368
|
}
|
|
376
369
|
if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCall(parent, context) && parent.parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCall(parent.parent, context) && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === AST_NODE_TYPES.Identifier) {
|
|
377
|
-
return
|
|
370
|
+
return parent.parent.parent.id;
|
|
378
371
|
}
|
|
379
|
-
return
|
|
372
|
+
return _;
|
|
380
373
|
}
|
|
381
|
-
|
|
382
|
-
// src/component/component-name.ts
|
|
383
374
|
var RE_COMPONENT_NAME = /^_?[A-Z]/u;
|
|
384
375
|
function getComponentNameFromIdentifier(node) {
|
|
376
|
+
if (node == null) return _;
|
|
385
377
|
return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
|
|
386
378
|
}
|
|
387
379
|
function isComponentName(name) {
|
|
@@ -423,14 +415,13 @@ function isFunctionOfRenderMethod(node) {
|
|
|
423
415
|
return isClassComponent(node.parent.parent.parent);
|
|
424
416
|
}
|
|
425
417
|
function isInsideRenderMethod(node) {
|
|
426
|
-
return
|
|
418
|
+
return AST8.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
427
419
|
}
|
|
420
|
+
|
|
421
|
+
// src/component/misc.ts
|
|
428
422
|
function hasNoneOrValidComponentName(node, context) {
|
|
429
|
-
const
|
|
430
|
-
if (
|
|
431
|
-
return true;
|
|
432
|
-
}
|
|
433
|
-
const id2 = mbIdentifier.value;
|
|
423
|
+
const id2 = getFunctionComponentIdentifier(node, context);
|
|
424
|
+
if (id2 == null) return true;
|
|
434
425
|
const name = Array.isArray(id2) ? id2.at(-1)?.name : id2.name;
|
|
435
426
|
return name != null && isComponentName(name);
|
|
436
427
|
}
|
|
@@ -452,26 +443,24 @@ function hasValidHierarchy(node, context, hint) {
|
|
|
452
443
|
if (hint & ERComponentHint.SkipClassProperty && AST8.isFunctionOfClassProperty(node.parent)) {
|
|
453
444
|
return false;
|
|
454
445
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
])
|
|
465
|
-
),
|
|
466
|
-
AST8.is(AST_NODE_TYPES.JSXExpressionContainer)
|
|
446
|
+
const boundaryNode = AST8.findParentNode(
|
|
447
|
+
node,
|
|
448
|
+
AST8.isOneOf([
|
|
449
|
+
AST_NODE_TYPES.JSXExpressionContainer,
|
|
450
|
+
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
451
|
+
AST_NODE_TYPES.FunctionExpression,
|
|
452
|
+
AST_NODE_TYPES.Property,
|
|
453
|
+
AST_NODE_TYPES.ClassBody
|
|
454
|
+
])
|
|
467
455
|
);
|
|
456
|
+
return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
|
|
468
457
|
}
|
|
469
458
|
function getComponentFlag(initPath) {
|
|
470
459
|
let flag = ERFunctionComponentFlag.None;
|
|
471
|
-
if (AST8.hasCallInFunctionInitPath("memo")(initPath)) {
|
|
460
|
+
if (initPath != null && AST8.hasCallInFunctionInitPath("memo")(initPath)) {
|
|
472
461
|
flag |= ERFunctionComponentFlag.Memo;
|
|
473
462
|
}
|
|
474
|
-
if (AST8.hasCallInFunctionInitPath("forwardRef")(initPath)) {
|
|
463
|
+
if (initPath != null && AST8.hasCallInFunctionInitPath("forwardRef")(initPath)) {
|
|
475
464
|
flag |= ERFunctionComponentFlag.ForwardRef;
|
|
476
465
|
}
|
|
477
466
|
return flag;
|
|
@@ -480,14 +469,15 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
480
469
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
481
470
|
const components = /* @__PURE__ */ new Map();
|
|
482
471
|
const functionEntries = [];
|
|
483
|
-
const
|
|
472
|
+
const getCurrentEntry = () => functionEntries.at(-1);
|
|
484
473
|
const onFunctionEnter = (node) => {
|
|
485
474
|
const key = getId();
|
|
486
475
|
functionEntries.push({ key, node, hookCalls: [], isComponent: false });
|
|
487
476
|
};
|
|
488
477
|
const onFunctionExit = () => {
|
|
489
478
|
const entry = functionEntries.at(-1);
|
|
490
|
-
if (
|
|
479
|
+
if (entry == null) return;
|
|
480
|
+
if (!entry.isComponent) {
|
|
491
481
|
return functionEntries.pop();
|
|
492
482
|
}
|
|
493
483
|
const shouldDrop = AST8.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
@@ -499,23 +489,23 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
499
489
|
return functionEntries.pop();
|
|
500
490
|
};
|
|
501
491
|
const ctx = {
|
|
502
|
-
|
|
492
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
493
|
+
getAllComponents(node) {
|
|
503
494
|
return components;
|
|
504
495
|
},
|
|
505
|
-
|
|
506
|
-
getCurrentFunctionStack() {
|
|
496
|
+
getCurrentEntries() {
|
|
507
497
|
return [...functionEntries];
|
|
508
|
-
}
|
|
498
|
+
},
|
|
499
|
+
getCurrentEntry
|
|
509
500
|
};
|
|
510
501
|
const listeners = {
|
|
511
502
|
":function[type]": onFunctionEnter,
|
|
512
503
|
":function[type]:exit": onFunctionExit,
|
|
513
504
|
"ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
|
|
514
|
-
const
|
|
515
|
-
if (
|
|
505
|
+
const entry = getCurrentEntry();
|
|
506
|
+
if (entry == null) {
|
|
516
507
|
return;
|
|
517
508
|
}
|
|
518
|
-
const entry = mbEntry.value;
|
|
519
509
|
const { body } = entry.node;
|
|
520
510
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
521
511
|
if (!isComponent) {
|
|
@@ -523,7 +513,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
523
513
|
}
|
|
524
514
|
const initPath = AST8.getFunctionInitPath(entry.node);
|
|
525
515
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
526
|
-
const name =
|
|
516
|
+
const name = getComponentNameFromIdentifier(id2);
|
|
527
517
|
const key = getId();
|
|
528
518
|
components.set(key, {
|
|
529
519
|
_: key,
|
|
@@ -531,7 +521,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
531
521
|
kind: "function",
|
|
532
522
|
name,
|
|
533
523
|
node: entry.node,
|
|
534
|
-
displayName:
|
|
524
|
+
displayName: _,
|
|
535
525
|
flag: getComponentFlag(initPath),
|
|
536
526
|
hint,
|
|
537
527
|
hookCalls: entry.hookCalls,
|
|
@@ -540,38 +530,32 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
540
530
|
},
|
|
541
531
|
"AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"(node) {
|
|
542
532
|
const { left, right } = node;
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
const componentName = mbComponentName.value;
|
|
548
|
-
const component = Array.from(components.values()).findLast(({ name }) => O.exists(name, (n) => n === componentName));
|
|
533
|
+
const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : _;
|
|
534
|
+
const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
|
|
549
535
|
if (component == null) {
|
|
550
536
|
return;
|
|
551
537
|
}
|
|
552
538
|
components.set(component._, {
|
|
553
539
|
...component,
|
|
554
|
-
displayName:
|
|
540
|
+
displayName: right
|
|
555
541
|
});
|
|
556
542
|
},
|
|
557
543
|
"CallExpression[type]:exit"(node) {
|
|
558
544
|
if (!isReactHookCall(node)) {
|
|
559
545
|
return;
|
|
560
546
|
}
|
|
561
|
-
const
|
|
562
|
-
if (
|
|
547
|
+
const entry = getCurrentEntry();
|
|
548
|
+
if (entry == null) {
|
|
563
549
|
return;
|
|
564
550
|
}
|
|
565
|
-
const entry = mbEntry.value;
|
|
566
551
|
functionEntries.pop();
|
|
567
552
|
functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
|
|
568
553
|
},
|
|
569
554
|
"ReturnStatement[type]"(node) {
|
|
570
|
-
const
|
|
571
|
-
if (
|
|
555
|
+
const entry = getCurrentEntry();
|
|
556
|
+
if (entry == null) {
|
|
572
557
|
return;
|
|
573
558
|
}
|
|
574
|
-
const entry = mbEntry.value;
|
|
575
559
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
576
560
|
if (!isComponent) {
|
|
577
561
|
return;
|
|
@@ -580,14 +564,14 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
580
564
|
functionEntries.push({ ...entry, isComponent });
|
|
581
565
|
const initPath = AST8.getFunctionInitPath(entry.node);
|
|
582
566
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
583
|
-
const name =
|
|
567
|
+
const name = getComponentNameFromIdentifier(id2);
|
|
584
568
|
components.set(entry.key, {
|
|
585
569
|
_: entry.key,
|
|
586
570
|
id: id2,
|
|
587
571
|
kind: "function",
|
|
588
572
|
name,
|
|
589
573
|
node: entry.node,
|
|
590
|
-
displayName:
|
|
574
|
+
displayName: _,
|
|
591
575
|
flag: getComponentFlag(initPath),
|
|
592
576
|
hint,
|
|
593
577
|
hookCalls: entry.hookCalls,
|
|
@@ -600,7 +584,8 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
600
584
|
function useComponentCollectorLegacy() {
|
|
601
585
|
const components = /* @__PURE__ */ new Map();
|
|
602
586
|
const ctx = {
|
|
603
|
-
|
|
587
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
588
|
+
getAllComponents(node) {
|
|
604
589
|
return components;
|
|
605
590
|
}
|
|
606
591
|
};
|
|
@@ -617,10 +602,10 @@ function useComponentCollectorLegacy() {
|
|
|
617
602
|
_: key,
|
|
618
603
|
id: id2,
|
|
619
604
|
kind: "class",
|
|
620
|
-
name:
|
|
605
|
+
name: id2?.name,
|
|
621
606
|
node,
|
|
622
607
|
// TODO: Get displayName of class component
|
|
623
|
-
displayName:
|
|
608
|
+
displayName: _,
|
|
624
609
|
flag,
|
|
625
610
|
hint: 0n,
|
|
626
611
|
// TODO: Get methods of class component
|
|
@@ -635,18 +620,14 @@ function useComponentCollectorLegacy() {
|
|
|
635
620
|
return { ctx, listeners };
|
|
636
621
|
}
|
|
637
622
|
function isSetupFunction(node) {
|
|
623
|
+
if (node == null) return _;
|
|
638
624
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
639
625
|
}
|
|
640
626
|
function isCleanupFunction(node) {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
O.bind("nearFunctionOfReturn", ({ nearReturn }) => AST8.findParentNodeGuard(nearReturn, AST8.isFunction)),
|
|
646
|
-
O.exists(
|
|
647
|
-
({ nearFunction, nearFunctionOfReturn }) => nearFunction === nearFunctionOfReturn && isSetupFunction(nearFunction)
|
|
648
|
-
)
|
|
649
|
-
);
|
|
627
|
+
const nearReturn = AST8.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.ReturnStatement));
|
|
628
|
+
const nearFunction = AST8.findParentNodeGuard(node, AST8.isFunction);
|
|
629
|
+
const nearFunctionOfReturn = AST8.findParentNodeGuard(nearReturn, AST8.isFunction);
|
|
630
|
+
return nearFunction === nearFunctionOfReturn && isSetupFunction(nearFunction);
|
|
650
631
|
}
|
|
651
632
|
function isComponentDidMount(node) {
|
|
652
633
|
return AST8.isOneOf([AST_NODE_TYPES.MethodDefinition, AST_NODE_TYPES.PropertyDefinition])(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
@@ -664,7 +645,7 @@ var ERPhaseRelevance = birecord({
|
|
|
664
645
|
mount: "unmount",
|
|
665
646
|
setup: "cleanup"
|
|
666
647
|
});
|
|
667
|
-
var isInversePhase =
|
|
648
|
+
var isInversePhase = dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
|
|
668
649
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
669
650
|
const matching = (node2) => {
|
|
670
651
|
return node2.type === AST_NODE_TYPES.Property && node2.key.type === AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
|
|
@@ -675,19 +656,15 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
675
656
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
676
657
|
return true;
|
|
677
658
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
O.exists(
|
|
684
|
-
(n) => n.type === AST_NODE_TYPES.JSXIdentifier && n.name.startsWith("render")
|
|
685
|
-
)
|
|
686
|
-
);
|
|
659
|
+
const parent = AST8.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
660
|
+
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
|
|
661
|
+
return false;
|
|
662
|
+
}
|
|
663
|
+
return parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
|
|
687
664
|
}
|
|
688
665
|
function isRenderFunctionLoose(node, context) {
|
|
689
666
|
const { body, parent } = node;
|
|
690
|
-
if (
|
|
667
|
+
if (AST8.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
691
668
|
return parent.type === AST_NODE_TYPES.JSXExpressionContainer && parent.parent.type === AST_NODE_TYPES.JSXAttribute && parent.parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.parent.name.name.startsWith("render");
|
|
692
669
|
}
|
|
693
670
|
return JSX4.isJSXValue(
|
|
@@ -709,4 +686,4 @@ function isThisSetState(node) {
|
|
|
709
686
|
return callee.type === AST_NODE_TYPES.MemberExpression && AST8.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
710
687
|
}
|
|
711
688
|
|
|
712
|
-
export { DEFAULT_COMPONENT_HINT, ERClassComponentFlag, ERComponentHint, ERFunctionComponentFlag, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier,
|
|
689
|
+
export { DEFAULT_COMPONENT_HINT, ERClassComponentFlag, ERComponentHint, ERFunctionComponentFlag, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getElementNameAndRepresentName, getFunctionComponentIdentifier, getId, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCleanupFunction, isCloneElement, isCloneElementCall, isComponentDidMount, isComponentDidMountFunction, isComponentName, isComponentWillUnmount, isComponentWillUnmountFunction, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfRenderMethod, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isSetupFunction, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0-beta.1",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and Patterns.",
|
|
5
|
-
"homepage": "https://github.com/
|
|
5
|
+
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
7
|
-
"url": "https://github.com/
|
|
7
|
+
"url": "https://github.com/Rel1cx/eslint-react/issues"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/
|
|
11
|
+
"url": "git+https://github.com/Rel1cx/eslint-react.git",
|
|
12
12
|
"directory": "packages/core"
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"@typescript-eslint/types": "^8.19.1",
|
|
39
39
|
"@typescript-eslint/utils": "^8.19.1",
|
|
40
40
|
"ts-pattern": "^5.6.0",
|
|
41
|
-
"@eslint-react/ast": "1.
|
|
42
|
-
"@eslint-react/eff": "1.
|
|
43
|
-
"@eslint-react/
|
|
44
|
-
"@eslint-react/types": "1.
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/var": "1.
|
|
41
|
+
"@eslint-react/ast": "1.24.0-beta.1",
|
|
42
|
+
"@eslint-react/eff": "1.24.0-beta.1",
|
|
43
|
+
"@eslint-react/jsx": "1.24.0-beta.1",
|
|
44
|
+
"@eslint-react/types": "1.24.0-beta.1",
|
|
45
|
+
"@eslint-react/shared": "1.24.0-beta.1",
|
|
46
|
+
"@eslint-react/var": "1.24.0-beta.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"tsup": "^8.3.5",
|