@eslint-react/core 1.24.0-beta.0 → 1.24.0-beta.16
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 +152 -140
- package/dist/index.d.ts +152 -140
- package/dist/index.js +179 -178
- package/dist/index.mjs +163 -168
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var AST8 = require('@eslint-react/ast');
|
|
4
4
|
var eff = require('@eslint-react/eff');
|
|
5
|
-
var
|
|
5
|
+
var JSX3 = require('@eslint-react/jsx');
|
|
6
|
+
var shared = require('@eslint-react/shared');
|
|
6
7
|
var types = require('@typescript-eslint/types');
|
|
7
8
|
var VAR = require('@eslint-react/var');
|
|
8
|
-
var
|
|
9
|
+
var birecord = require('birecord');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
12
|
|
|
10
13
|
function _interopNamespace(e) {
|
|
11
14
|
if (e && e.__esModule) return e;
|
|
@@ -26,34 +29,12 @@ function _interopNamespace(e) {
|
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
var AST8__namespace = /*#__PURE__*/_interopNamespace(AST8);
|
|
29
|
-
var
|
|
32
|
+
var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
|
|
30
33
|
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
34
|
+
var birecord__default = /*#__PURE__*/_interopDefault(birecord);
|
|
31
35
|
|
|
32
36
|
// src/component/component-collector.ts
|
|
33
|
-
function
|
|
34
|
-
const name = JSX4__namespace.getElementName(node);
|
|
35
|
-
if (name === name.toLowerCase()) return [name, name];
|
|
36
|
-
const component = additionalComponents.findLast((c) => c.name === name || c.re.test(name));
|
|
37
|
-
if (component !== eff._) return [name, component.as];
|
|
38
|
-
if (polymorphicPropName == null) return [name, name];
|
|
39
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
40
|
-
const polymorphicProp = JSX4__namespace.findPropInAttributes(
|
|
41
|
-
polymorphicPropName,
|
|
42
|
-
initialScope,
|
|
43
|
-
node.attributes
|
|
44
|
-
);
|
|
45
|
-
if (polymorphicProp === eff._) return [name, name];
|
|
46
|
-
const polymorphicName = VAR__namespace.toResolved(JSX4__namespace.getPropValue(polymorphicProp, initialScope)).value;
|
|
47
|
-
if (typeof polymorphicName === "string") {
|
|
48
|
-
return [name, polymorphicName];
|
|
49
|
-
}
|
|
50
|
-
return [name, name];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/utils/get-id.ts
|
|
54
|
-
var id = 0n;
|
|
55
|
-
var getId = () => (id++).toString();
|
|
56
|
-
function isInitializedFromReact(name, initialScope, importSource = "react") {
|
|
37
|
+
function isInitializedFromReact(name, importSource, initialScope) {
|
|
57
38
|
return name.toLowerCase() === "react" || VAR__namespace.isInitializedFromSource(
|
|
58
39
|
name,
|
|
59
40
|
importSource,
|
|
@@ -71,12 +52,13 @@ function isFromReact(name) {
|
|
|
71
52
|
}
|
|
72
53
|
return node.name === name;
|
|
73
54
|
}
|
|
55
|
+
const importSource = settings.importSource ?? shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
|
|
74
56
|
const initialScope = context.sourceCode.getScope(node);
|
|
75
57
|
if (node.type === types.AST_NODE_TYPES.MemberExpression) {
|
|
76
|
-
return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name,
|
|
58
|
+
return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
|
|
77
59
|
}
|
|
78
60
|
if (node.name === name) {
|
|
79
|
-
return isInitializedFromReact(name,
|
|
61
|
+
return isInitializedFromReact(name, importSource, initialScope);
|
|
80
62
|
}
|
|
81
63
|
return false;
|
|
82
64
|
};
|
|
@@ -96,14 +78,15 @@ function isFromReactMember(memberName, name) {
|
|
|
96
78
|
}
|
|
97
79
|
return false;
|
|
98
80
|
}
|
|
81
|
+
const importSource = settings.importSource ?? shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
|
|
99
82
|
const initialScope = context.sourceCode.getScope(node);
|
|
100
83
|
if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name) {
|
|
101
84
|
return false;
|
|
102
85
|
}
|
|
103
86
|
if (node.object.type === types.AST_NODE_TYPES.Identifier && node.object.name === memberName) {
|
|
104
|
-
return isInitializedFromReact(node.object.name,
|
|
87
|
+
return isInitializedFromReact(node.object.name, importSource, initialScope);
|
|
105
88
|
}
|
|
106
|
-
if (node.object.type === types.AST_NODE_TYPES.MemberExpression && node.object.object.type === types.AST_NODE_TYPES.Identifier && isInitializedFromReact(node.object.object.name,
|
|
89
|
+
if (node.object.type === types.AST_NODE_TYPES.MemberExpression && node.object.object.type === types.AST_NODE_TYPES.Identifier && isInitializedFromReact(node.object.object.name, importSource, initialScope) && node.object.property.type === types.AST_NODE_TYPES.Identifier) {
|
|
107
90
|
return node.object.property.name === memberName;
|
|
108
91
|
}
|
|
109
92
|
return false;
|
|
@@ -164,15 +147,15 @@ var isMemoCall = isReactAPICallWithName("memo");
|
|
|
164
147
|
|
|
165
148
|
// src/element/hierarchy.ts
|
|
166
149
|
function isInsideCreateElementProps(node, context) {
|
|
167
|
-
const call = AST8__namespace.
|
|
168
|
-
if (
|
|
169
|
-
const prop = AST8__namespace.
|
|
170
|
-
if (
|
|
150
|
+
const call = AST8__namespace.findParentNode(node, isCreateElementCall(context));
|
|
151
|
+
if (call == null) return false;
|
|
152
|
+
const prop = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
|
|
153
|
+
if (prop == null) return false;
|
|
171
154
|
return prop === call.arguments[1];
|
|
172
155
|
}
|
|
173
156
|
function isChildrenOfCreateElement(node, context) {
|
|
174
157
|
const parent = node.parent;
|
|
175
|
-
if (
|
|
158
|
+
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
176
159
|
if (!isCreateElementCall(parent, context)) return false;
|
|
177
160
|
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
178
161
|
}
|
|
@@ -185,12 +168,12 @@ function isReactHookName(name) {
|
|
|
185
168
|
|
|
186
169
|
// src/hook/is.ts
|
|
187
170
|
function isReactHook(node) {
|
|
188
|
-
if (node
|
|
189
|
-
const
|
|
190
|
-
return
|
|
171
|
+
if (node == null) return eff._;
|
|
172
|
+
const id = AST8__namespace.getFunctionIdentifier(node);
|
|
173
|
+
return id?.name != null && isReactHookName(id.name);
|
|
191
174
|
}
|
|
192
175
|
function isReactHookCall(node) {
|
|
193
|
-
if (node
|
|
176
|
+
if (node == null) return false;
|
|
194
177
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
195
178
|
return false;
|
|
196
179
|
}
|
|
@@ -203,22 +186,23 @@ function isReactHookCall(node) {
|
|
|
203
186
|
return false;
|
|
204
187
|
}
|
|
205
188
|
function isReactHookCallWithName(node, context) {
|
|
206
|
-
if (node
|
|
189
|
+
if (node == null) return eff.returnFalse;
|
|
207
190
|
const settings = shared.unsafeDecodeSettings(context.settings);
|
|
191
|
+
const importSource = settings.importSource ?? "react";
|
|
192
|
+
const initialScope = context.sourceCode.getScope(node);
|
|
208
193
|
return (name) => {
|
|
209
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
210
194
|
switch (true) {
|
|
211
195
|
case (node.callee.type === types.AST_NODE_TYPES.Identifier && node.callee.name === name):
|
|
212
|
-
return !settings.strictImportCheck || isInitializedFromReact(name,
|
|
196
|
+
return !settings.strictImportCheck || isInitializedFromReact(name, importSource, initialScope);
|
|
213
197
|
case (node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === name && "name" in node.callee.object):
|
|
214
|
-
return !settings.strictImportCheck || isInitializedFromReact(node.callee.object.name,
|
|
198
|
+
return !settings.strictImportCheck || isInitializedFromReact(node.callee.object.name, importSource, initialScope);
|
|
215
199
|
default:
|
|
216
200
|
return false;
|
|
217
201
|
}
|
|
218
202
|
};
|
|
219
203
|
}
|
|
220
204
|
function isReactHookCallWithNameLoose(node) {
|
|
221
|
-
if (node
|
|
205
|
+
if (node == null) return eff.returnFalse;
|
|
222
206
|
return (name) => {
|
|
223
207
|
switch (node.callee.type) {
|
|
224
208
|
case types.AST_NODE_TYPES.Identifier:
|
|
@@ -232,20 +216,21 @@ function isReactHookCallWithNameLoose(node) {
|
|
|
232
216
|
}
|
|
233
217
|
function isReactHookCallWithNameAlias(name, context, alias) {
|
|
234
218
|
const settings = shared.unsafeDecodeSettings(context);
|
|
219
|
+
const importSource = settings.importSource ?? "react";
|
|
235
220
|
return (node) => {
|
|
236
221
|
const initialScope = context.sourceCode.getScope(node);
|
|
237
222
|
switch (true) {
|
|
238
223
|
case (node.callee.type === types.AST_NODE_TYPES.Identifier && node.callee.name === name):
|
|
239
|
-
return !settings.strictImportCheck || isInitializedFromReact(name,
|
|
224
|
+
return !settings.strictImportCheck || isInitializedFromReact(name, importSource, initialScope);
|
|
240
225
|
case (node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === name && "name" in node.callee.object):
|
|
241
|
-
return !settings.strictImportCheck || isInitializedFromReact(node.callee.object.name,
|
|
226
|
+
return !settings.strictImportCheck || isInitializedFromReact(node.callee.object.name, importSource, initialScope);
|
|
242
227
|
default:
|
|
243
228
|
return alias.some(isReactHookCallWithNameLoose(node));
|
|
244
229
|
}
|
|
245
230
|
};
|
|
246
231
|
}
|
|
247
232
|
function isUseEffectCallLoose(node) {
|
|
248
|
-
if (node
|
|
233
|
+
if (node == null) return false;
|
|
249
234
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
250
235
|
return false;
|
|
251
236
|
}
|
|
@@ -276,20 +261,20 @@ var isUseTransitionCall = eff.flip(isReactHookCallWithName)("useTransition");
|
|
|
276
261
|
|
|
277
262
|
// src/hook/hierarchy.ts
|
|
278
263
|
function isInsideReactHook(node) {
|
|
279
|
-
return isReactHook(AST8__namespace.
|
|
264
|
+
return isReactHook(AST8__namespace.findParentNode(node, AST8__namespace.isFunction));
|
|
280
265
|
}
|
|
281
266
|
function useHookCollector() {
|
|
282
267
|
const hooks = /* @__PURE__ */ new Map();
|
|
283
268
|
const fEntries = [];
|
|
284
269
|
const onFunctionEnter = (node) => {
|
|
285
|
-
const
|
|
286
|
-
const name =
|
|
287
|
-
if (name
|
|
288
|
-
const key = getId();
|
|
270
|
+
const id = AST8__namespace.getFunctionIdentifier(node);
|
|
271
|
+
const name = id?.name;
|
|
272
|
+
if (name != null && isReactHookName(name)) {
|
|
273
|
+
const key = shared.getId();
|
|
289
274
|
fEntries.push({ key, node });
|
|
290
275
|
hooks.set(key, {
|
|
291
|
-
|
|
292
|
-
|
|
276
|
+
id,
|
|
277
|
+
key,
|
|
293
278
|
kind: "function",
|
|
294
279
|
name,
|
|
295
280
|
node,
|
|
@@ -321,26 +306,20 @@ function useHookCollector() {
|
|
|
321
306
|
return;
|
|
322
307
|
}
|
|
323
308
|
const fEntry = fEntries.at(-1);
|
|
324
|
-
if (fEntry?.key
|
|
309
|
+
if (fEntry?.key == null) {
|
|
325
310
|
return;
|
|
326
311
|
}
|
|
327
312
|
const hook = hooks.get(fEntry.key);
|
|
328
|
-
if (hook
|
|
313
|
+
if (hook == null) {
|
|
329
314
|
return;
|
|
330
315
|
}
|
|
331
|
-
|
|
332
|
-
...hook,
|
|
333
|
-
hookCalls: [
|
|
334
|
-
...hook.hookCalls,
|
|
335
|
-
node
|
|
336
|
-
]
|
|
337
|
-
});
|
|
316
|
+
hook.hookCalls.push(node);
|
|
338
317
|
}
|
|
339
318
|
};
|
|
340
319
|
return { ctx, listeners };
|
|
341
320
|
}
|
|
342
321
|
var ERComponentHint = {
|
|
343
|
-
...
|
|
322
|
+
...JSX3__namespace.JSXValueHint,
|
|
344
323
|
// 1n << 0n - 1n << 63n are reserved for JSXValueHint
|
|
345
324
|
// Skip function component created by React.memo
|
|
346
325
|
SkipMemo: 1n << 64n,
|
|
@@ -356,6 +335,17 @@ var ERComponentHint = {
|
|
|
356
335
|
SkipClassProperty: 1n << 69n
|
|
357
336
|
};
|
|
358
337
|
var DEFAULT_COMPONENT_HINT = 0n | ERComponentHint.SkipBooleanLiteral | ERComponentHint.SkipMapCallback | ERComponentHint.SkipNumberLiteral | ERComponentHint.SkipStringLiteral | ERComponentHint.SkipUndefined | ERComponentHint.SkipEmptyArray | ERComponentHint.StrictArray | ERComponentHint.StrictConditional | ERComponentHint.StrictLogical;
|
|
338
|
+
var COMPONENT_DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
339
|
+
"AssignmentExpression",
|
|
340
|
+
"[type]",
|
|
341
|
+
"[operator='=']",
|
|
342
|
+
"[left.type='MemberExpression']",
|
|
343
|
+
"[left.property.name='displayName']"
|
|
344
|
+
].join("");
|
|
345
|
+
function isComponentDisplayNameAssignment(node) {
|
|
346
|
+
if (node == null) return false;
|
|
347
|
+
return node.type === types.AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === types.AST_NODE_TYPES.MemberExpression && node.left.property.type === types.AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
|
|
348
|
+
}
|
|
359
349
|
|
|
360
350
|
// src/component/component-flag.ts
|
|
361
351
|
var ERClassComponentFlag = {
|
|
@@ -383,7 +373,7 @@ function isComponentWrapperCall(node, context) {
|
|
|
383
373
|
}
|
|
384
374
|
function getFunctionComponentIdentifier(node, context) {
|
|
385
375
|
const functionId = AST8__namespace.getFunctionIdentifier(node);
|
|
386
|
-
if (functionId) {
|
|
376
|
+
if (functionId != null) {
|
|
387
377
|
return functionId;
|
|
388
378
|
}
|
|
389
379
|
const { parent } = node;
|
|
@@ -395,17 +385,8 @@ function getFunctionComponentIdentifier(node, context) {
|
|
|
395
385
|
}
|
|
396
386
|
return eff._;
|
|
397
387
|
}
|
|
398
|
-
|
|
399
|
-
// src/component/component-name.ts
|
|
400
|
-
var RE_COMPONENT_NAME = /^_?[A-Z]/u;
|
|
401
|
-
function getComponentNameFromIdentifier(node) {
|
|
402
|
-
return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
|
|
403
|
-
}
|
|
404
|
-
function isComponentName(name) {
|
|
405
|
-
return RE_COMPONENT_NAME.test(name);
|
|
406
|
-
}
|
|
407
388
|
function isClassComponent(node) {
|
|
408
|
-
if ("superClass" in node && node.superClass) {
|
|
389
|
+
if ("superClass" in node && node.superClass != null) {
|
|
409
390
|
const re = /^(?:Pure)?Component$/u;
|
|
410
391
|
switch (true) {
|
|
411
392
|
case node.superClass.type === types.AST_NODE_TYPES.Identifier:
|
|
@@ -417,7 +398,7 @@ function isClassComponent(node) {
|
|
|
417
398
|
return false;
|
|
418
399
|
}
|
|
419
400
|
function isPureComponent(node) {
|
|
420
|
-
if ("superClass" in node && node.superClass) {
|
|
401
|
+
if ("superClass" in node && node.superClass != null) {
|
|
421
402
|
const re = /^PureComponent$/u;
|
|
422
403
|
switch (true) {
|
|
423
404
|
case node.superClass.type === types.AST_NODE_TYPES.Identifier:
|
|
@@ -429,9 +410,30 @@ function isPureComponent(node) {
|
|
|
429
410
|
return false;
|
|
430
411
|
}
|
|
431
412
|
|
|
432
|
-
// src/component/component-
|
|
413
|
+
// src/component/component-lifecycle.ts
|
|
414
|
+
function isComponentDidMount(node) {
|
|
415
|
+
return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
416
|
+
}
|
|
417
|
+
function isComponentWillUnmount(node) {
|
|
418
|
+
return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
419
|
+
}
|
|
420
|
+
function isComponentDidCatch(node) {
|
|
421
|
+
return AST8__namespace.isMethodOrProperty(node) && !node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
422
|
+
}
|
|
423
|
+
function isGetDerivedStateFromError(node) {
|
|
424
|
+
return AST8__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
425
|
+
}
|
|
426
|
+
function isGetDerivedStateFromProps(node) {
|
|
427
|
+
return AST8__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
428
|
+
}
|
|
429
|
+
function isFunctionOfComponentDidMount(node) {
|
|
430
|
+
return AST8__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
431
|
+
}
|
|
432
|
+
function isFunctionOfComponentWillUnmount(node) {
|
|
433
|
+
return AST8__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
434
|
+
}
|
|
433
435
|
function isRenderMethodLike(node) {
|
|
434
|
-
return (node
|
|
436
|
+
return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration;
|
|
435
437
|
}
|
|
436
438
|
function isFunctionOfRenderMethod(node) {
|
|
437
439
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -440,14 +442,20 @@ function isFunctionOfRenderMethod(node) {
|
|
|
440
442
|
return isClassComponent(node.parent.parent.parent);
|
|
441
443
|
}
|
|
442
444
|
function isInsideRenderMethod(node) {
|
|
443
|
-
return
|
|
445
|
+
return AST8__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
446
|
+
}
|
|
447
|
+
var RE_COMPONENT_NAME = /^_?[A-Z]/u;
|
|
448
|
+
function getComponentNameFromIdentifier(node) {
|
|
449
|
+
if (node == null) return eff._;
|
|
450
|
+
return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
|
|
451
|
+
}
|
|
452
|
+
function isComponentName(name) {
|
|
453
|
+
return RE_COMPONENT_NAME.test(name);
|
|
444
454
|
}
|
|
445
|
-
|
|
446
|
-
// src/component/misc.ts
|
|
447
455
|
function hasNoneOrValidComponentName(node, context) {
|
|
448
|
-
const
|
|
449
|
-
if (
|
|
450
|
-
const name = Array.isArray(
|
|
456
|
+
const id = getFunctionComponentIdentifier(node, context);
|
|
457
|
+
if (id == null) return true;
|
|
458
|
+
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
451
459
|
return name != null && isComponentName(name);
|
|
452
460
|
}
|
|
453
461
|
|
|
@@ -478,35 +486,36 @@ function hasValidHierarchy(node, context, hint) {
|
|
|
478
486
|
types.AST_NODE_TYPES.ClassBody
|
|
479
487
|
])
|
|
480
488
|
);
|
|
481
|
-
return
|
|
489
|
+
return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
|
|
482
490
|
}
|
|
483
491
|
function getComponentFlag(initPath) {
|
|
484
492
|
let flag = ERFunctionComponentFlag.None;
|
|
485
|
-
if (initPath && AST8__namespace.hasCallInFunctionInitPath("memo"
|
|
493
|
+
if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("memo", initPath)) {
|
|
486
494
|
flag |= ERFunctionComponentFlag.Memo;
|
|
487
495
|
}
|
|
488
|
-
if (initPath && AST8__namespace.hasCallInFunctionInitPath("forwardRef"
|
|
496
|
+
if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
489
497
|
flag |= ERFunctionComponentFlag.ForwardRef;
|
|
490
498
|
}
|
|
491
499
|
return flag;
|
|
492
500
|
}
|
|
493
|
-
function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
501
|
+
function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options = {}) {
|
|
502
|
+
const { collectDisplayName = false, collectHookCalls = false } = options;
|
|
494
503
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
495
504
|
const components = /* @__PURE__ */ new Map();
|
|
496
505
|
const functionEntries = [];
|
|
497
506
|
const getCurrentEntry = () => functionEntries.at(-1);
|
|
498
507
|
const onFunctionEnter = (node) => {
|
|
499
|
-
const key = getId();
|
|
508
|
+
const key = shared.getId();
|
|
500
509
|
functionEntries.push({ key, node, hookCalls: [], isComponent: false });
|
|
501
510
|
};
|
|
502
511
|
const onFunctionExit = () => {
|
|
503
512
|
const entry = functionEntries.at(-1);
|
|
504
|
-
if (
|
|
513
|
+
if (entry == null) return;
|
|
505
514
|
if (!entry.isComponent) {
|
|
506
515
|
return functionEntries.pop();
|
|
507
516
|
}
|
|
508
517
|
const shouldDrop = AST8__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
509
|
-
return context.sourceCode.getScope(r).block === entry.node &&
|
|
518
|
+
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3__namespace.isJSXValue(r.argument, jsxCtx, hint);
|
|
510
519
|
});
|
|
511
520
|
if (shouldDrop) {
|
|
512
521
|
components.delete(entry.key);
|
|
@@ -528,21 +537,21 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
528
537
|
":function[type]:exit": onFunctionExit,
|
|
529
538
|
"ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
|
|
530
539
|
const entry = getCurrentEntry();
|
|
531
|
-
if (
|
|
540
|
+
if (entry == null) {
|
|
532
541
|
return;
|
|
533
542
|
}
|
|
534
543
|
const { body } = entry.node;
|
|
535
|
-
const isComponent = hasNoneOrValidComponentName(entry.node, context) &&
|
|
544
|
+
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3__namespace.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
536
545
|
if (!isComponent) {
|
|
537
546
|
return;
|
|
538
547
|
}
|
|
539
548
|
const initPath = AST8__namespace.getFunctionInitPath(entry.node);
|
|
540
|
-
const
|
|
541
|
-
const name =
|
|
542
|
-
const key = getId();
|
|
549
|
+
const id = getFunctionComponentIdentifier(entry.node, context);
|
|
550
|
+
const name = getComponentNameFromIdentifier(id);
|
|
551
|
+
const key = shared.getId();
|
|
543
552
|
components.set(key, {
|
|
544
|
-
|
|
545
|
-
|
|
553
|
+
id,
|
|
554
|
+
key,
|
|
546
555
|
kind: "function",
|
|
547
556
|
name,
|
|
548
557
|
node: entry.node,
|
|
@@ -553,46 +562,47 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
553
562
|
initPath
|
|
554
563
|
});
|
|
555
564
|
},
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
565
|
+
...collectDisplayName ? {
|
|
566
|
+
[COMPONENT_DISPLAY_NAME_ASSIGNMENT_SELECTOR](node) {
|
|
567
|
+
const { left, right } = node;
|
|
568
|
+
if (left.type !== types.AST_NODE_TYPES.MemberExpression) return;
|
|
569
|
+
const componentName = left.object.type === types.AST_NODE_TYPES.Identifier ? left.object.name : eff._;
|
|
570
|
+
const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
|
|
571
|
+
if (component == null) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
component.displayName = right;
|
|
562
575
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
576
|
+
} : {},
|
|
577
|
+
...collectHookCalls ? {
|
|
578
|
+
"CallExpression[type]:exit"(node) {
|
|
579
|
+
if (!isReactHookCall(node)) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
const entry = getCurrentEntry();
|
|
583
|
+
if (entry == null) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
entry.hookCalls.push(node);
|
|
571
587
|
}
|
|
572
|
-
|
|
573
|
-
if (!entry) {
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
functionEntries.pop();
|
|
577
|
-
functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
|
|
578
|
-
},
|
|
588
|
+
} : {},
|
|
579
589
|
"ReturnStatement[type]"(node) {
|
|
580
590
|
const entry = getCurrentEntry();
|
|
581
|
-
if (
|
|
591
|
+
if (entry == null) {
|
|
582
592
|
return;
|
|
583
593
|
}
|
|
584
|
-
const isComponent = hasNoneOrValidComponentName(entry.node, context) &&
|
|
594
|
+
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3__namespace.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
585
595
|
if (!isComponent) {
|
|
586
596
|
return;
|
|
587
597
|
}
|
|
588
598
|
functionEntries.pop();
|
|
589
599
|
functionEntries.push({ ...entry, isComponent });
|
|
590
600
|
const initPath = AST8__namespace.getFunctionInitPath(entry.node);
|
|
591
|
-
const
|
|
592
|
-
const name =
|
|
601
|
+
const id = getFunctionComponentIdentifier(entry.node, context);
|
|
602
|
+
const name = getComponentNameFromIdentifier(id);
|
|
593
603
|
components.set(entry.key, {
|
|
594
|
-
|
|
595
|
-
|
|
604
|
+
id,
|
|
605
|
+
key: entry.key,
|
|
596
606
|
kind: "function",
|
|
597
607
|
name,
|
|
598
608
|
node: entry.node,
|
|
@@ -618,16 +628,16 @@ function useComponentCollectorLegacy() {
|
|
|
618
628
|
if (!isClassComponent(node)) {
|
|
619
629
|
return;
|
|
620
630
|
}
|
|
621
|
-
const
|
|
622
|
-
const key = getId();
|
|
631
|
+
const id = AST8__namespace.getClassIdentifier(node);
|
|
632
|
+
const key = shared.getId();
|
|
623
633
|
const flag = isPureComponent(node) ? ERClassComponentFlag.PureComponent : ERClassComponentFlag.None;
|
|
624
634
|
components.set(
|
|
625
635
|
key,
|
|
626
636
|
{
|
|
627
|
-
|
|
628
|
-
|
|
637
|
+
id,
|
|
638
|
+
key,
|
|
629
639
|
kind: "class",
|
|
630
|
-
name:
|
|
640
|
+
name: id?.name,
|
|
631
641
|
node,
|
|
632
642
|
// TODO: Get displayName of class component
|
|
633
643
|
displayName: eff._,
|
|
@@ -644,60 +654,22 @@ function useComponentCollectorLegacy() {
|
|
|
644
654
|
};
|
|
645
655
|
return { ctx, listeners };
|
|
646
656
|
}
|
|
647
|
-
|
|
648
|
-
if (node === eff._) return eff._;
|
|
649
|
-
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === types.AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
650
|
-
}
|
|
651
|
-
function isCleanupFunction(node) {
|
|
652
|
-
const nearReturn = AST8__namespace.findParentNodeGuard(node, AST8__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
|
|
653
|
-
const nearFunction = AST8__namespace.findParentNodeGuard(node, AST8__namespace.isFunction);
|
|
654
|
-
const nearFunctionOfReturn = AST8__namespace.findParentNodeGuard(nearReturn, AST8__namespace.isFunction);
|
|
655
|
-
return nearFunction === nearFunctionOfReturn && isSetupFunction(nearFunction);
|
|
656
|
-
}
|
|
657
|
-
function isComponentDidMount(node) {
|
|
658
|
-
return AST8__namespace.isOneOf([types.AST_NODE_TYPES.MethodDefinition, types.AST_NODE_TYPES.PropertyDefinition])(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
659
|
-
}
|
|
660
|
-
function isComponentWillUnmount(node) {
|
|
661
|
-
return AST8__namespace.isOneOf([types.AST_NODE_TYPES.MethodDefinition, types.AST_NODE_TYPES.PropertyDefinition])(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
662
|
-
}
|
|
663
|
-
function isComponentDidMountFunction(node) {
|
|
664
|
-
return AST8__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
665
|
-
}
|
|
666
|
-
function isComponentWillUnmountFunction(node) {
|
|
667
|
-
return AST8__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
668
|
-
}
|
|
669
|
-
var ERPhaseRelevance = eff.birecord({
|
|
657
|
+
var ERPhaseRelevance = birecord__default.default({
|
|
670
658
|
mount: "unmount",
|
|
671
659
|
setup: "cleanup"
|
|
672
660
|
});
|
|
673
661
|
var isInversePhase = eff.dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
|
|
674
|
-
function isDirectValueOfRenderPropertyLoose(node) {
|
|
675
|
-
const matching = (node2) => {
|
|
676
|
-
return node2.type === types.AST_NODE_TYPES.Property && node2.key.type === types.AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
|
|
677
|
-
};
|
|
678
|
-
return matching(node) || !!node.parent && matching(node.parent);
|
|
679
|
-
}
|
|
680
|
-
function isDeclaredInRenderPropLoose(node) {
|
|
681
|
-
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
682
|
-
return true;
|
|
683
|
-
}
|
|
684
|
-
const parent = AST8__namespace.findParentNodeGuard(node, AST8__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
685
|
-
if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
|
|
686
|
-
return false;
|
|
687
|
-
}
|
|
688
|
-
return parent.name.type === types.AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
|
|
689
|
-
}
|
|
690
662
|
function isRenderFunctionLoose(node, context) {
|
|
691
663
|
const { body, parent } = node;
|
|
692
664
|
if (AST8__namespace.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
693
665
|
return parent.type === types.AST_NODE_TYPES.JSXExpressionContainer && parent.parent.type === types.AST_NODE_TYPES.JSXAttribute && parent.parent.name.type === types.AST_NODE_TYPES.JSXIdentifier && parent.parent.name.name.startsWith("render");
|
|
694
666
|
}
|
|
695
|
-
return
|
|
667
|
+
return JSX3__namespace.isJSXValue(
|
|
696
668
|
body,
|
|
697
669
|
{
|
|
698
670
|
getScope: (node2) => context.sourceCode.getScope(node2)
|
|
699
671
|
},
|
|
700
|
-
|
|
672
|
+
JSX3__namespace.JSXValueHint.SkipNullLiteral | JSX3__namespace.JSXValueHint.SkipUndefined | JSX3__namespace.JSXValueHint.StrictLogical | JSX3__namespace.JSXValueHint.StrictConditional
|
|
701
673
|
);
|
|
702
674
|
}
|
|
703
675
|
function isRenderPropLoose(node, context) {
|
|
@@ -706,11 +678,38 @@ function isRenderPropLoose(node, context) {
|
|
|
706
678
|
}
|
|
707
679
|
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && AST8__namespace.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
|
|
708
680
|
}
|
|
681
|
+
function isDirectValueOfRenderPropertyLoose(node) {
|
|
682
|
+
const matching = (node2) => {
|
|
683
|
+
return node2.type === types.AST_NODE_TYPES.Property && node2.key.type === types.AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
|
|
684
|
+
};
|
|
685
|
+
return matching(node) || node.parent != null && matching(node.parent);
|
|
686
|
+
}
|
|
687
|
+
function isDeclaredInRenderPropLoose(node) {
|
|
688
|
+
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
689
|
+
return true;
|
|
690
|
+
}
|
|
691
|
+
const parent = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
692
|
+
if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
return parent.name.type === types.AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
|
|
696
|
+
}
|
|
709
697
|
function isThisSetState(node) {
|
|
710
698
|
const { callee } = node;
|
|
711
699
|
return callee.type === types.AST_NODE_TYPES.MemberExpression && AST8__namespace.isThisExpression(callee.object) && callee.property.type === types.AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
712
700
|
}
|
|
701
|
+
function isFunctionOfUseEffectSetup(node) {
|
|
702
|
+
if (node == null) return eff._;
|
|
703
|
+
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === types.AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
704
|
+
}
|
|
705
|
+
function isFunctionOfUseEffectCleanup(node) {
|
|
706
|
+
const nearReturn = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
|
|
707
|
+
const nearFunction = AST8__namespace.findParentNode(node, AST8__namespace.isFunction);
|
|
708
|
+
const nearFunctionOfReturn = AST8__namespace.findParentNode(nearReturn, AST8__namespace.isFunction);
|
|
709
|
+
return nearFunction === nearFunctionOfReturn && isFunctionOfUseEffectSetup(nearFunction);
|
|
710
|
+
}
|
|
713
711
|
|
|
712
|
+
exports.COMPONENT_DISPLAY_NAME_ASSIGNMENT_SELECTOR = COMPONENT_DISPLAY_NAME_ASSIGNMENT_SELECTOR;
|
|
714
713
|
exports.DEFAULT_COMPONENT_HINT = DEFAULT_COMPONENT_HINT;
|
|
715
714
|
exports.ERClassComponentFlag = ERClassComponentFlag;
|
|
716
715
|
exports.ERComponentHint = ERComponentHint;
|
|
@@ -719,9 +718,7 @@ exports.ERPhaseRelevance = ERPhaseRelevance;
|
|
|
719
718
|
exports.RE_COMPONENT_NAME = RE_COMPONENT_NAME;
|
|
720
719
|
exports.RE_HOOK_NAME = RE_HOOK_NAME;
|
|
721
720
|
exports.getComponentNameFromIdentifier = getComponentNameFromIdentifier;
|
|
722
|
-
exports.getElementNameAndRepresentName = getElementNameAndRepresentName;
|
|
723
721
|
exports.getFunctionComponentIdentifier = getFunctionComponentIdentifier;
|
|
724
|
-
exports.getId = getId;
|
|
725
722
|
exports.hasNoneOrValidComponentName = hasNoneOrValidComponentName;
|
|
726
723
|
exports.isCallFromReact = isCallFromReact;
|
|
727
724
|
exports.isCallFromReactMember = isCallFromReactMember;
|
|
@@ -737,14 +734,13 @@ exports.isChildrenOnlyCall = isChildrenOnlyCall;
|
|
|
737
734
|
exports.isChildrenToArray = isChildrenToArray;
|
|
738
735
|
exports.isChildrenToArrayCall = isChildrenToArrayCall;
|
|
739
736
|
exports.isClassComponent = isClassComponent;
|
|
740
|
-
exports.isCleanupFunction = isCleanupFunction;
|
|
741
737
|
exports.isCloneElement = isCloneElement;
|
|
742
738
|
exports.isCloneElementCall = isCloneElementCall;
|
|
739
|
+
exports.isComponentDidCatch = isComponentDidCatch;
|
|
743
740
|
exports.isComponentDidMount = isComponentDidMount;
|
|
744
|
-
exports.
|
|
741
|
+
exports.isComponentDisplayNameAssignment = isComponentDisplayNameAssignment;
|
|
745
742
|
exports.isComponentName = isComponentName;
|
|
746
743
|
exports.isComponentWillUnmount = isComponentWillUnmount;
|
|
747
|
-
exports.isComponentWillUnmountFunction = isComponentWillUnmountFunction;
|
|
748
744
|
exports.isCreateContext = isCreateContext;
|
|
749
745
|
exports.isCreateContextCall = isCreateContextCall;
|
|
750
746
|
exports.isCreateElement = isCreateElement;
|
|
@@ -757,7 +753,13 @@ exports.isForwardRef = isForwardRef;
|
|
|
757
753
|
exports.isForwardRefCall = isForwardRefCall;
|
|
758
754
|
exports.isFromReact = isFromReact;
|
|
759
755
|
exports.isFromReactMember = isFromReactMember;
|
|
756
|
+
exports.isFunctionOfComponentDidMount = isFunctionOfComponentDidMount;
|
|
757
|
+
exports.isFunctionOfComponentWillUnmount = isFunctionOfComponentWillUnmount;
|
|
760
758
|
exports.isFunctionOfRenderMethod = isFunctionOfRenderMethod;
|
|
759
|
+
exports.isFunctionOfUseEffectCleanup = isFunctionOfUseEffectCleanup;
|
|
760
|
+
exports.isFunctionOfUseEffectSetup = isFunctionOfUseEffectSetup;
|
|
761
|
+
exports.isGetDerivedStateFromError = isGetDerivedStateFromError;
|
|
762
|
+
exports.isGetDerivedStateFromProps = isGetDerivedStateFromProps;
|
|
761
763
|
exports.isInitializedFromReact = isInitializedFromReact;
|
|
762
764
|
exports.isInsideCreateElementProps = isInsideCreateElementProps;
|
|
763
765
|
exports.isInsideReactHook = isInsideReactHook;
|
|
@@ -777,7 +779,6 @@ exports.isReactHookName = isReactHookName;
|
|
|
777
779
|
exports.isRenderFunctionLoose = isRenderFunctionLoose;
|
|
778
780
|
exports.isRenderMethodLike = isRenderMethodLike;
|
|
779
781
|
exports.isRenderPropLoose = isRenderPropLoose;
|
|
780
|
-
exports.isSetupFunction = isSetupFunction;
|
|
781
782
|
exports.isThisSetState = isThisSetState;
|
|
782
783
|
exports.isUseCallbackCall = isUseCallbackCall;
|
|
783
784
|
exports.isUseContextCall = isUseContextCall;
|