eslint-plugin-react-x 5.2.1-next.3 → 5.2.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +115 -111
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_ESLINT_REACT_SETTINGS, getSettingsFromContext, toRegExp } from "@eslint-react/shared";
|
|
2
|
-
import
|
|
3
|
-
import { findParent, is, isFunction } from "@eslint-react/ast";
|
|
2
|
+
import { Check, Compare, Extract, Select, Traverse, is, isOneOf } from "@eslint-react/ast";
|
|
4
3
|
import * as core from "@eslint-react/core";
|
|
5
4
|
import { isUseRefCall } from "@eslint-react/core";
|
|
6
5
|
import { merge } from "@eslint-react/eslint";
|
|
@@ -144,7 +143,7 @@ const rules$7 = {
|
|
|
144
143
|
//#endregion
|
|
145
144
|
//#region package.json
|
|
146
145
|
var name$6 = "eslint-plugin-react-x";
|
|
147
|
-
var version = "5.2.
|
|
146
|
+
var version = "5.2.2-beta.0";
|
|
148
147
|
|
|
149
148
|
//#endregion
|
|
150
149
|
//#region src/rules/component-hook-factories/lib.ts
|
|
@@ -188,7 +187,7 @@ function isTestMock$1(node) {
|
|
|
188
187
|
return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "mock";
|
|
189
188
|
}
|
|
190
189
|
function isTestMockCallback$1(node) {
|
|
191
|
-
return node != null &&
|
|
190
|
+
return node != null && Check.isFunction(node) && node.parent.type === AST_NODE_TYPES.CallExpression && isTestMock$1(node.parent.callee) && node.parent.arguments[1] === node;
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
//#endregion
|
|
@@ -227,9 +226,9 @@ function create$48(context) {
|
|
|
227
226
|
const hooks = [...hCollector.api.getAllHooks(program)];
|
|
228
227
|
for (const { name, node } of fComponents) {
|
|
229
228
|
if (name == null) continue;
|
|
230
|
-
const parentFn =
|
|
229
|
+
const parentFn = Traverse.findParent(node, Check.isFunction);
|
|
231
230
|
if (parentFn == null) continue;
|
|
232
|
-
if (
|
|
231
|
+
if (Traverse.findParent(node, isTestMockCallback$1) != null) continue;
|
|
233
232
|
if (isHigherOrderComponent(parentFn)) continue;
|
|
234
233
|
if (reported.has(node)) continue;
|
|
235
234
|
context.report({
|
|
@@ -240,9 +239,9 @@ function create$48(context) {
|
|
|
240
239
|
reported.add(node);
|
|
241
240
|
}
|
|
242
241
|
for (const { name = "unknown", node } of cComponents) {
|
|
243
|
-
const parentFn =
|
|
242
|
+
const parentFn = Traverse.findParent(node, Check.isFunction);
|
|
244
243
|
if (parentFn == null) continue;
|
|
245
|
-
if (
|
|
244
|
+
if (Traverse.findParent(node, isTestMockCallback$1) != null) continue;
|
|
246
245
|
if (isHigherOrderComponent(parentFn)) continue;
|
|
247
246
|
context.report({
|
|
248
247
|
data: { name },
|
|
@@ -251,8 +250,8 @@ function create$48(context) {
|
|
|
251
250
|
});
|
|
252
251
|
}
|
|
253
252
|
for (const { name, node } of hooks) {
|
|
254
|
-
if (
|
|
255
|
-
if (
|
|
253
|
+
if (Traverse.findParent(node, Check.isFunction) == null) continue;
|
|
254
|
+
if (Traverse.findParent(node, isTestMockCallback$1) != null) continue;
|
|
256
255
|
if (reported.has(node)) continue;
|
|
257
256
|
context.report({
|
|
258
257
|
data: { name },
|
|
@@ -298,8 +297,8 @@ function create$47(context) {
|
|
|
298
297
|
const hooks = hCollector.api.getAllHooks(node);
|
|
299
298
|
const funcs = [...comps, ...hooks];
|
|
300
299
|
for (const call of useCalls) {
|
|
301
|
-
const stmt =
|
|
302
|
-
const func =
|
|
300
|
+
const stmt = Traverse.findParent(call, is(AST_NODE_TYPES.TryStatement));
|
|
301
|
+
const func = Traverse.findParent(stmt, (n) => funcs.some((f) => f.node === n));
|
|
303
302
|
if (stmt != null && func != null && !reported.has(stmt)) {
|
|
304
303
|
context.report({
|
|
305
304
|
messageId: "tryCatchWithUse",
|
|
@@ -311,7 +310,7 @@ function create$47(context) {
|
|
|
311
310
|
for (const { rets } of funcs) for (const ret of rets) {
|
|
312
311
|
if (ret == null) continue;
|
|
313
312
|
if (!isJsxLike(context, ret, hint)) continue;
|
|
314
|
-
const stmt =
|
|
313
|
+
const stmt = Traverse.findParent(ret, is(AST_NODE_TYPES.TryStatement));
|
|
315
314
|
if (stmt != null && !reported.has(stmt)) {
|
|
316
315
|
context.report({
|
|
317
316
|
messageId: "tryCatchWithJsx",
|
|
@@ -1313,7 +1312,7 @@ function create$46(context) {
|
|
|
1313
1312
|
if (variable == null) return null;
|
|
1314
1313
|
for (const def of variable.defs) {
|
|
1315
1314
|
if (def.type !== DefinitionType.Parameter) continue;
|
|
1316
|
-
if (!
|
|
1315
|
+
if (!Check.isFunction(def.node)) continue;
|
|
1317
1316
|
const fn = def.node;
|
|
1318
1317
|
const firstParam = fn.params.at(0);
|
|
1319
1318
|
if (firstParam?.type === AST_NODE_TYPES.Identifier && firstParam.name === id.name) return fn;
|
|
@@ -1326,10 +1325,10 @@ function create$46(context) {
|
|
|
1326
1325
|
const { object, property } = node.callee;
|
|
1327
1326
|
if (property.type !== AST_NODE_TYPES.Identifier) return;
|
|
1328
1327
|
if (!MUTATING_ARRAY_METHODS.has(property.name)) return;
|
|
1329
|
-
const rootId =
|
|
1328
|
+
const rootId = Extract.rootIdentifier(object);
|
|
1330
1329
|
if (rootId == null) return;
|
|
1331
1330
|
if (rootId.name === "draft") return;
|
|
1332
|
-
const enclosingFn =
|
|
1331
|
+
const enclosingFn = Traverse.findParent(node, Check.isFunction);
|
|
1333
1332
|
if (enclosingFn == null) return;
|
|
1334
1333
|
const isState = isStateValue(rootId);
|
|
1335
1334
|
const propsDefiningFunc = !isState ? getPropsDefiningFunction(rootId) : null;
|
|
@@ -1347,10 +1346,10 @@ function create$46(context) {
|
|
|
1347
1346
|
},
|
|
1348
1347
|
AssignmentExpression(node) {
|
|
1349
1348
|
if (node.left.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
1350
|
-
const rootId =
|
|
1349
|
+
const rootId = Extract.rootIdentifier(node.left);
|
|
1351
1350
|
if (rootId == null) return;
|
|
1352
1351
|
if (rootId.name === "draft") return;
|
|
1353
|
-
const enclosingFn =
|
|
1352
|
+
const enclosingFn = Traverse.findParent(node, Check.isFunction);
|
|
1354
1353
|
if (enclosingFn == null) return;
|
|
1355
1354
|
const isState = isStateValue(rootId);
|
|
1356
1355
|
const propsDefiningFunc = !isState ? getPropsDefiningFunction(rootId) : null;
|
|
@@ -1375,7 +1374,7 @@ function create$46(context) {
|
|
|
1375
1374
|
insideComponentOrHook = true;
|
|
1376
1375
|
break;
|
|
1377
1376
|
}
|
|
1378
|
-
current =
|
|
1377
|
+
current = Traverse.findParent(current, Check.isFunction);
|
|
1379
1378
|
}
|
|
1380
1379
|
if (!insideComponentOrHook) continue;
|
|
1381
1380
|
if (propsDefiningFunc != null) {
|
|
@@ -1614,14 +1613,14 @@ function create$45(context) {
|
|
|
1614
1613
|
classStack.pop();
|
|
1615
1614
|
},
|
|
1616
1615
|
MemberExpression(node) {
|
|
1617
|
-
if (!
|
|
1616
|
+
if (!Check.thisExpression(node.object)) return;
|
|
1618
1617
|
const [currClass, isComponent = false] = classStack.at(-1) ?? [];
|
|
1619
1618
|
if (currClass == null || !isComponent) return;
|
|
1620
1619
|
const [currMethod, isStatic = false] = methodStack.at(-1) ?? [];
|
|
1621
1620
|
if (currMethod == null || isStatic) return;
|
|
1622
1621
|
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
1623
1622
|
if (setState == null || hasThisState) return;
|
|
1624
|
-
if (
|
|
1623
|
+
if (Extract.propertyName(node.property) !== "state") return;
|
|
1625
1624
|
context.report({
|
|
1626
1625
|
messageId: "default",
|
|
1627
1626
|
node
|
|
@@ -1646,8 +1645,8 @@ function create$45(context) {
|
|
|
1646
1645
|
if (currMethod == null || isStatic) return;
|
|
1647
1646
|
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
1648
1647
|
if (setState == null || hasThisState) return;
|
|
1649
|
-
if (node.init == null || !
|
|
1650
|
-
if (!node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.Property && isKeyLiteral$1(prop, prop.key) &&
|
|
1648
|
+
if (node.init == null || !Check.thisExpression(node.init) || node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
|
|
1649
|
+
if (!node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.Property && isKeyLiteral$1(prop, prop.key) && Extract.propertyName(prop.key) === "state")) return;
|
|
1651
1650
|
context.report({
|
|
1652
1651
|
messageId: "default",
|
|
1653
1652
|
node
|
|
@@ -1699,7 +1698,7 @@ function getMapIndexParamName(context, node) {
|
|
|
1699
1698
|
if (indexPosition === -1) return null;
|
|
1700
1699
|
const callbackArg = node.arguments[core.isChildrenMap(context, callee) || core.isChildrenForEach(context, callee) ? 1 : 0];
|
|
1701
1700
|
if (callbackArg == null) return null;
|
|
1702
|
-
if (!
|
|
1701
|
+
if (!isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(callbackArg)) return null;
|
|
1703
1702
|
const { params } = callbackArg;
|
|
1704
1703
|
if (params.length < indexPosition + 1) return null;
|
|
1705
1704
|
const param = params.at(indexPosition);
|
|
@@ -2114,7 +2113,7 @@ var no_create_ref_default = createRule({
|
|
|
2114
2113
|
});
|
|
2115
2114
|
function create$32(context) {
|
|
2116
2115
|
return merge({ CallExpression(node) {
|
|
2117
|
-
if (core.isCreateRefCall(context, node) &&
|
|
2116
|
+
if (core.isCreateRefCall(context, node) && Traverse.findParent(node, core.isClassComponent) == null) context.report({
|
|
2118
2117
|
messageId: "default",
|
|
2119
2118
|
node
|
|
2120
2119
|
});
|
|
@@ -2125,7 +2124,7 @@ function create$32(context) {
|
|
|
2125
2124
|
//#region src/rules/no-direct-mutation-state/no-direct-mutation-state.ts
|
|
2126
2125
|
const RULE_NAME$31 = "no-direct-mutation-state";
|
|
2127
2126
|
function isConstructorFunction(node) {
|
|
2128
|
-
return
|
|
2127
|
+
return isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && Check.isMethodOrProperty(node.parent) && node.parent.key.type === AST_NODE_TYPES.Identifier && node.parent.key.name === "constructor";
|
|
2129
2128
|
}
|
|
2130
2129
|
var no_direct_mutation_state_default = createRule({
|
|
2131
2130
|
meta: {
|
|
@@ -2141,9 +2140,9 @@ var no_direct_mutation_state_default = createRule({
|
|
|
2141
2140
|
function create$31(context) {
|
|
2142
2141
|
return merge({ AssignmentExpression(node) {
|
|
2143
2142
|
if (!core.isAssignmentToThisState(node)) return;
|
|
2144
|
-
const parentClass =
|
|
2143
|
+
const parentClass = Traverse.findParent(node, isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
|
|
2145
2144
|
if (parentClass == null) return;
|
|
2146
|
-
if (core.isClassComponent(parentClass) && context.sourceCode.getScope(node).block !==
|
|
2145
|
+
if (core.isClassComponent(parentClass) && context.sourceCode.getScope(node).block !== Traverse.findParent(node, isConstructorFunction)) context.report({
|
|
2147
2146
|
messageId: "default",
|
|
2148
2147
|
node
|
|
2149
2148
|
});
|
|
@@ -2171,7 +2170,7 @@ function create$30(context) {
|
|
|
2171
2170
|
const aValue = a.value;
|
|
2172
2171
|
const bValue = b.value;
|
|
2173
2172
|
if (aValue == null || bValue == null) return false;
|
|
2174
|
-
return
|
|
2173
|
+
return Compare.areEqual(aValue, bValue);
|
|
2175
2174
|
}
|
|
2176
2175
|
return merge({
|
|
2177
2176
|
"JSXAttribute[name.name='key']"(node) {
|
|
@@ -2190,12 +2189,12 @@ function create$30(context) {
|
|
|
2190
2189
|
break;
|
|
2191
2190
|
}
|
|
2192
2191
|
default: {
|
|
2193
|
-
const call =
|
|
2194
|
-
const iter =
|
|
2195
|
-
if (!
|
|
2192
|
+
const call = Traverse.findParent(jsxElement, (n) => n.type === AST_NODE_TYPES.CallExpression && n.callee.type === AST_NODE_TYPES.MemberExpression && n.callee.property.type === AST_NODE_TYPES.Identifier && n.callee.property.name === "map");
|
|
2193
|
+
const iter = Traverse.findParent(jsxElement, (n) => n === call || Check.isFunction(n));
|
|
2194
|
+
if (!Check.isFunction(iter)) return;
|
|
2196
2195
|
const arg0 = call?.arguments[0];
|
|
2197
2196
|
if (call == null || arg0 == null) return;
|
|
2198
|
-
if (
|
|
2197
|
+
if (Extract.unwrapped(arg0) !== iter) return;
|
|
2199
2198
|
keyedEntries.set(call, {
|
|
2200
2199
|
hasDuplicate: node.value?.type === AST_NODE_TYPES.Literal,
|
|
2201
2200
|
keys: [node],
|
|
@@ -2280,7 +2279,7 @@ function canFix(context, node) {
|
|
|
2280
2279
|
function getFix(context, node) {
|
|
2281
2280
|
return (fixer) => {
|
|
2282
2281
|
const [componentNode] = node.arguments;
|
|
2283
|
-
if (componentNode == null || !
|
|
2282
|
+
if (componentNode == null || !Check.isFunction(componentNode)) return [];
|
|
2284
2283
|
return [
|
|
2285
2284
|
fixer.removeRange([node.range[0], componentNode.range[0]]),
|
|
2286
2285
|
fixer.removeRange([componentNode.range[1], node.range[1]]),
|
|
@@ -2500,16 +2499,16 @@ function create$25(context) {
|
|
|
2500
2499
|
*/
|
|
2501
2500
|
function getReportDescriptor(node) {
|
|
2502
2501
|
if (node == null) return null;
|
|
2503
|
-
if (
|
|
2504
|
-
if (
|
|
2505
|
-
if (
|
|
2502
|
+
if (is(AST_NODE_TYPES.JSXExpressionContainer)(node)) return getReportDescriptor(node.expression);
|
|
2503
|
+
if (Check.isJSX(node)) return null;
|
|
2504
|
+
if (Check.isTypeExpression(node)) return getReportDescriptor(node.expression);
|
|
2506
2505
|
return match(node).with({
|
|
2507
2506
|
type: AST_NODE_TYPES.LogicalExpression,
|
|
2508
2507
|
operator: "&&"
|
|
2509
2508
|
}, ({ left, right }) => {
|
|
2510
2509
|
if (left.type === AST_NODE_TYPES.UnaryExpression && left.operator === "!") return getReportDescriptor(right);
|
|
2511
2510
|
const initialScope = context.sourceCode.getScope(left);
|
|
2512
|
-
if (
|
|
2511
|
+
if (Check.identifier(left, "NaN") || getStaticValue(left, initialScope)?.value === "NaN") return {
|
|
2513
2512
|
data: { value: context.sourceCode.getText(left) },
|
|
2514
2513
|
messageId: "default",
|
|
2515
2514
|
node: left
|
|
@@ -2586,9 +2585,6 @@ function create$23(context) {
|
|
|
2586
2585
|
const createCalls = [];
|
|
2587
2586
|
const displayNameAssignments = [];
|
|
2588
2587
|
return merge({
|
|
2589
|
-
[ast.SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION](node) {
|
|
2590
|
-
displayNameAssignments.push(node);
|
|
2591
|
-
},
|
|
2592
2588
|
CallExpression(node) {
|
|
2593
2589
|
if (!core.isCreateContextCall(context, node)) return;
|
|
2594
2590
|
createCalls.push(node);
|
|
@@ -2627,6 +2623,9 @@ function create$23(context) {
|
|
|
2627
2623
|
node: id
|
|
2628
2624
|
});
|
|
2629
2625
|
}
|
|
2626
|
+
},
|
|
2627
|
+
[Select.displayNameAssignment](node) {
|
|
2628
|
+
displayNameAssignments.push(node);
|
|
2630
2629
|
}
|
|
2631
2630
|
});
|
|
2632
2631
|
}
|
|
@@ -2651,10 +2650,10 @@ function report(context) {
|
|
|
2651
2650
|
*/
|
|
2652
2651
|
function getNestedReturnStatements(node) {
|
|
2653
2652
|
const statements = [];
|
|
2654
|
-
const boundaryNode = isFunction(node) ? node : findParent(node, isFunction);
|
|
2653
|
+
const boundaryNode = Check.isFunction(node) ? node : Traverse.findParent(node, Check.isFunction);
|
|
2655
2654
|
simpleTraverse(node, { enter(node) {
|
|
2656
2655
|
if (node.type !== AST_NODE_TYPES.ReturnStatement) return;
|
|
2657
|
-
if (findParent(node, isFunction) !== boundaryNode) return;
|
|
2656
|
+
if (Traverse.findParent(node, Check.isFunction) !== boundaryNode) return;
|
|
2658
2657
|
statements.push(node);
|
|
2659
2658
|
} });
|
|
2660
2659
|
return statements;
|
|
@@ -2712,7 +2711,7 @@ function create$22(context) {
|
|
|
2712
2711
|
return merge({
|
|
2713
2712
|
ArrayExpression(node) {
|
|
2714
2713
|
if (inChildrenToArray) return;
|
|
2715
|
-
const elements = node.elements.filter(
|
|
2714
|
+
const elements = node.elements.filter(is(AST_NODE_TYPES.JSXElement));
|
|
2716
2715
|
if (elements.length === 0) return;
|
|
2717
2716
|
for (const el of elements) if (!hasAttribute(context, el, "key")) context.report({
|
|
2718
2717
|
messageId: "default",
|
|
@@ -2728,7 +2727,7 @@ function create$22(context) {
|
|
|
2728
2727
|
const idx = name === "from" ? 1 : name === "map" ? 0 : -1;
|
|
2729
2728
|
if (idx < 0) return;
|
|
2730
2729
|
const cb = node.arguments[idx];
|
|
2731
|
-
if (!
|
|
2730
|
+
if (!Check.isFunction(cb)) return;
|
|
2732
2731
|
if (cb.body.type === AST_NODE_TYPES.BlockStatement) checkBlock(cb.body).forEach(report(context));
|
|
2733
2732
|
else report(context)(checkExpr(cb.body));
|
|
2734
2733
|
},
|
|
@@ -2766,8 +2765,8 @@ function isProcessEnvNodeEnvCompare(node, operator, value) {
|
|
|
2766
2765
|
if (node == null) return false;
|
|
2767
2766
|
if (node.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
2768
2767
|
if (node.operator !== operator) return false;
|
|
2769
|
-
if (isProcessEnvNodeEnv(node.left) &&
|
|
2770
|
-
if (
|
|
2768
|
+
if (isProcessEnvNodeEnv(node.left) && Check.literal(node.right, "string")) return node.right.value === value;
|
|
2769
|
+
if (Check.literal(node.left, "string") && isProcessEnvNodeEnv(node.right)) return node.left.value === value;
|
|
2771
2770
|
return false;
|
|
2772
2771
|
}
|
|
2773
2772
|
|
|
@@ -2794,7 +2793,7 @@ function create$21(context) {
|
|
|
2794
2793
|
return merge({
|
|
2795
2794
|
CallExpression(node) {
|
|
2796
2795
|
if (!core.isCaptureOwnerStackCall(context, node)) return;
|
|
2797
|
-
if (
|
|
2796
|
+
if (Traverse.findParent(node, isDevelopmentOnlyCheck) == null) context.report({
|
|
2798
2797
|
messageId: "missingDevelopmentOnlyCheck",
|
|
2799
2798
|
node
|
|
2800
2799
|
});
|
|
@@ -2839,9 +2838,9 @@ function create$20(context) {
|
|
|
2839
2838
|
const fComponents = [...fCollector.api.getAllComponents(program)];
|
|
2840
2839
|
const cComponents = [...cCollector.api.getAllComponents(program)];
|
|
2841
2840
|
function findEnclosingComponent(node) {
|
|
2842
|
-
return
|
|
2843
|
-
if (
|
|
2844
|
-
if (
|
|
2841
|
+
return Traverse.findParent(node, (n) => {
|
|
2842
|
+
if (Check.isFunction(n)) return fComponents.some((c) => c.node === n);
|
|
2843
|
+
if (Check.isClass(n)) return cComponents.some((c) => c.node === n);
|
|
2845
2844
|
return false;
|
|
2846
2845
|
});
|
|
2847
2846
|
}
|
|
@@ -2917,7 +2916,7 @@ function isInsideJSXAttributeValue(node) {
|
|
|
2917
2916
|
* @returns `true` if the node is inside a class component's render block
|
|
2918
2917
|
*/
|
|
2919
2918
|
function isInsideRenderMethod(node) {
|
|
2920
|
-
return
|
|
2919
|
+
return Traverse.findParent(node, (n) => core.isRenderMethodLike(n) && core.isClassComponent(n.parent.parent)) != null;
|
|
2921
2920
|
}
|
|
2922
2921
|
/**
|
|
2923
2922
|
* Determine whether the node is inside `createElement`'s props argument
|
|
@@ -2926,9 +2925,9 @@ function isInsideRenderMethod(node) {
|
|
|
2926
2925
|
* @returns `true` if the node is inside `createElement`'s props
|
|
2927
2926
|
*/
|
|
2928
2927
|
function isInsideCreateElementProps(context, node) {
|
|
2929
|
-
const call =
|
|
2928
|
+
const call = Traverse.findParent(node, core.isCreateElementCall(context));
|
|
2930
2929
|
if (call == null) return false;
|
|
2931
|
-
const prop =
|
|
2930
|
+
const prop = Traverse.findParent(node, is(AST_NODE_TYPES.ObjectExpression));
|
|
2932
2931
|
if (prop == null) return false;
|
|
2933
2932
|
return prop === call.arguments[1];
|
|
2934
2933
|
}
|
|
@@ -2954,7 +2953,7 @@ function create$19(context) {
|
|
|
2954
2953
|
const lazyCalls = /* @__PURE__ */ new Set();
|
|
2955
2954
|
return merge(fCollector.visitor, cCollector.visitor, hCollector.visitor, {
|
|
2956
2955
|
ImportExpression(node) {
|
|
2957
|
-
const lazyCall =
|
|
2956
|
+
const lazyCall = Traverse.findParent(node, (n) => core.isLazyCall(context, n));
|
|
2958
2957
|
if (lazyCall != null) lazyCalls.add(lazyCall);
|
|
2959
2958
|
},
|
|
2960
2959
|
"Program:exit"(program) {
|
|
@@ -2963,7 +2962,7 @@ function create$19(context) {
|
|
|
2963
2962
|
...hCollector.api.getAllHooks(program),
|
|
2964
2963
|
...cCollector.api.getAllComponents(program)
|
|
2965
2964
|
];
|
|
2966
|
-
for (const lazy of lazyCalls) if (
|
|
2965
|
+
for (const lazy of lazyCalls) if (Traverse.findParent(lazy, (n) => significantParents.some((p) => p.node === n))) context.report({
|
|
2967
2966
|
messageId: "default",
|
|
2968
2967
|
node: lazy
|
|
2969
2968
|
});
|
|
@@ -2989,8 +2988,8 @@ function create$18(context) {
|
|
|
2989
2988
|
if (!context.sourceCode.text.includes("componentDidMount")) return {};
|
|
2990
2989
|
return merge({ CallExpression(node) {
|
|
2991
2990
|
if (!core.isThisSetStateCall(node)) return;
|
|
2992
|
-
const enclosingClassNode =
|
|
2993
|
-
const enclosingMethodNode =
|
|
2991
|
+
const enclosingClassNode = Traverse.findParent(node, core.isClassComponent);
|
|
2992
|
+
const enclosingMethodNode = Traverse.findParent(node, (n) => n === enclosingClassNode || core.isComponentDidMount(n));
|
|
2994
2993
|
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
2995
2994
|
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
2996
2995
|
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
@@ -3019,8 +3018,8 @@ function create$17(context) {
|
|
|
3019
3018
|
if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
|
|
3020
3019
|
return merge({ CallExpression(node) {
|
|
3021
3020
|
if (!core.isThisSetStateCall(node)) return;
|
|
3022
|
-
const enclosingClassNode =
|
|
3023
|
-
const enclosingMethodNode =
|
|
3021
|
+
const enclosingClassNode = Traverse.findParent(node, core.isClassComponent);
|
|
3022
|
+
const enclosingMethodNode = Traverse.findParent(node, (n) => n === enclosingClassNode || core.isComponentDidUpdate(n));
|
|
3024
3023
|
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
3025
3024
|
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
3026
3025
|
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
@@ -3049,8 +3048,8 @@ function create$16(context) {
|
|
|
3049
3048
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
3050
3049
|
return merge({ CallExpression(node) {
|
|
3051
3050
|
if (!core.isThisSetStateCall(node)) return;
|
|
3052
|
-
const enclosingClassNode =
|
|
3053
|
-
const enclosingMethodNode =
|
|
3051
|
+
const enclosingClassNode = Traverse.findParent(node, core.isClassComponent);
|
|
3052
|
+
const enclosingMethodNode = Traverse.findParent(node, (n) => n === enclosingClassNode || core.isComponentWillUpdate(n));
|
|
3054
3053
|
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
3055
3054
|
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
3056
3055
|
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
@@ -3071,7 +3070,7 @@ function isTestMock(node) {
|
|
|
3071
3070
|
return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "mock";
|
|
3072
3071
|
}
|
|
3073
3072
|
function isTestMockCallback(node) {
|
|
3074
|
-
return node != null &&
|
|
3073
|
+
return node != null && Check.isFunction(node) && node.parent.type === AST_NODE_TYPES.CallExpression && isTestMock(node.parent.callee) && node.parent.arguments[1] === node;
|
|
3075
3074
|
}
|
|
3076
3075
|
|
|
3077
3076
|
//#endregion
|
|
@@ -3097,7 +3096,7 @@ function create$15(context) {
|
|
|
3097
3096
|
if (core.isFunctionEmpty(node)) continue;
|
|
3098
3097
|
if (WELL_KNOWN_HOOKS.includes(name)) continue;
|
|
3099
3098
|
if (containsUseComments(context, node)) continue;
|
|
3100
|
-
if (
|
|
3099
|
+
if (Traverse.findParent(node, isTestMockCallback) != null) continue;
|
|
3101
3100
|
context.report({
|
|
3102
3101
|
data: { name },
|
|
3103
3102
|
messageId: "default",
|
|
@@ -3208,7 +3207,7 @@ var no_unstable_context_value_default = createRule({
|
|
|
3208
3207
|
function create$11(context) {
|
|
3209
3208
|
const { compilationMode, version } = getSettingsFromContext(context);
|
|
3210
3209
|
if (compilationMode === "infer" || compilationMode === "all") return {};
|
|
3211
|
-
if (compilationMode === "annotation" &&
|
|
3210
|
+
if (compilationMode === "annotation" && context.sourceCode.ast.body.some((stmt) => Check.directive(stmt) && stmt.directive === "use memo")) return {};
|
|
3212
3211
|
const isReact18OrBelow = compare(version, "19.0.0", "<");
|
|
3213
3212
|
const { api, visitor } = core.getFunctionComponentCollector(context);
|
|
3214
3213
|
const constructions = /* @__PURE__ */ new WeakMap();
|
|
@@ -3217,7 +3216,7 @@ function create$11(context) {
|
|
|
3217
3216
|
const selfName = getElementFullType(node.parent).split(".").at(-1);
|
|
3218
3217
|
if (selfName == null) return;
|
|
3219
3218
|
if (!isContextName(selfName, isReact18OrBelow)) return;
|
|
3220
|
-
const enclosingFunction =
|
|
3219
|
+
const enclosingFunction = Traverse.findParent(node, Check.isFunction);
|
|
3221
3220
|
if (enclosingFunction == null) return;
|
|
3222
3221
|
if (compilationMode === "annotation" && core.isFunctionHasDirective(enclosingFunction, "use memo")) return;
|
|
3223
3222
|
const attribute = node.attributes.find((attribute) => attribute.type === AST_NODE_TYPES.JSXAttribute && attribute.name.name === "value");
|
|
@@ -3238,7 +3237,7 @@ function create$11(context) {
|
|
|
3238
3237
|
const suggestion = kind === "function" ? "Consider wrapping it in a useCallback hook." : "Consider wrapping it in a useMemo hook.";
|
|
3239
3238
|
context.report({
|
|
3240
3239
|
data: {
|
|
3241
|
-
kind:
|
|
3240
|
+
kind: Extract.humanReadableKind(constructionNode),
|
|
3242
3241
|
suggestion
|
|
3243
3242
|
},
|
|
3244
3243
|
messageId: "unstableContextValue",
|
|
@@ -3289,17 +3288,17 @@ function extractIdentifier(node) {
|
|
|
3289
3288
|
function create$10(context, [options]) {
|
|
3290
3289
|
const { compilationMode } = getSettingsFromContext(context);
|
|
3291
3290
|
if (compilationMode === "infer" || compilationMode === "all") return {};
|
|
3292
|
-
if (compilationMode === "annotation" &&
|
|
3291
|
+
if (compilationMode === "annotation" && context.sourceCode.ast.body.some((stmt) => Check.directive(stmt) && stmt.directive === "use memo")) return {};
|
|
3293
3292
|
const { api, visitor } = core.getFunctionComponentCollector(context);
|
|
3293
|
+
const SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR = [
|
|
3294
|
+
"VariableDeclarator",
|
|
3295
|
+
"[id.type='ObjectPattern']",
|
|
3296
|
+
"[init.type='Identifier']"
|
|
3297
|
+
].join("");
|
|
3294
3298
|
const declarators = /* @__PURE__ */ new WeakMap();
|
|
3295
3299
|
const { safeDefaultProps = [] } = options;
|
|
3296
3300
|
const safePatterns = safeDefaultProps.map((s) => toRegExp(s));
|
|
3297
3301
|
return merge(visitor, {
|
|
3298
|
-
[ast.SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR](node) {
|
|
3299
|
-
const enclosingFunction = ast.findParent(node, ast.isFunction);
|
|
3300
|
-
if (enclosingFunction == null) return;
|
|
3301
|
-
getOrInsertComputed(declarators, enclosingFunction, () => []).push(node);
|
|
3302
|
-
},
|
|
3303
3302
|
"Program:exit"(program) {
|
|
3304
3303
|
for (const { node: component } of api.getAllComponents(program)) {
|
|
3305
3304
|
const { params } = component;
|
|
@@ -3320,12 +3319,17 @@ function create$10(context, [options]) {
|
|
|
3320
3319
|
if (identifier != null && safePatterns.some((pattern) => pattern.test(identifier))) continue;
|
|
3321
3320
|
}
|
|
3322
3321
|
context.report({
|
|
3323
|
-
data: { kind:
|
|
3322
|
+
data: { kind: Extract.humanReadableKind(right) },
|
|
3324
3323
|
messageId: "default",
|
|
3325
3324
|
node: right
|
|
3326
3325
|
});
|
|
3327
3326
|
}
|
|
3328
3327
|
}
|
|
3328
|
+
},
|
|
3329
|
+
[SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR](node) {
|
|
3330
|
+
const enclosingFunction = Traverse.findParent(node, Check.isFunction);
|
|
3331
|
+
if (enclosingFunction == null) return;
|
|
3332
|
+
getOrInsertComputed(declarators, enclosingFunction, () => []).push(node);
|
|
3329
3333
|
}
|
|
3330
3334
|
});
|
|
3331
3335
|
}
|
|
@@ -3386,7 +3390,7 @@ function create$9(context) {
|
|
|
3386
3390
|
const usages = propertyUsages.get(currentClass);
|
|
3387
3391
|
if (defs == null) return;
|
|
3388
3392
|
for (const def of defs) {
|
|
3389
|
-
const methodName =
|
|
3393
|
+
const methodName = Extract.propertyName(def);
|
|
3390
3394
|
if (methodName == null) continue;
|
|
3391
3395
|
if ((usages?.has(methodName) ?? false) || LIFECYCLE_METHODS.has(methodName)) continue;
|
|
3392
3396
|
context.report({
|
|
@@ -3419,12 +3423,12 @@ function create$9(context) {
|
|
|
3419
3423
|
const currentMethod = methodStack.at(-1);
|
|
3420
3424
|
if (currentClass == null || currentMethod == null) return;
|
|
3421
3425
|
if (!core.isClassComponent(currentClass) || currentMethod.static) return;
|
|
3422
|
-
if (!
|
|
3426
|
+
if (!Check.thisExpression(node.object) || !isKeyLiteral(node, node.property)) return;
|
|
3423
3427
|
if (node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.left === node) {
|
|
3424
3428
|
propertyDefs.get(currentClass)?.add(node.property);
|
|
3425
3429
|
return;
|
|
3426
3430
|
}
|
|
3427
|
-
const propertyName =
|
|
3431
|
+
const propertyName = Extract.propertyName(node.property);
|
|
3428
3432
|
if (propertyName != null) propertyUsages.get(currentClass)?.add(propertyName);
|
|
3429
3433
|
},
|
|
3430
3434
|
MethodDefinition: methodEnter,
|
|
@@ -3436,9 +3440,9 @@ function create$9(context) {
|
|
|
3436
3440
|
const currentMethod = methodStack.at(-1);
|
|
3437
3441
|
if (currentClass == null || currentMethod == null) return;
|
|
3438
3442
|
if (!core.isClassComponent(currentClass) || currentMethod.static) return;
|
|
3439
|
-
if (node.init != null &&
|
|
3443
|
+
if (node.init != null && Check.thisExpression(node.init) && node.id.type === AST_NODE_TYPES.ObjectPattern) {
|
|
3440
3444
|
for (const prop of node.id.properties) if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral(prop, prop.key)) {
|
|
3441
|
-
const keyName =
|
|
3445
|
+
const keyName = Extract.propertyName(prop.key);
|
|
3442
3446
|
if (keyName != null) propertyUsages.get(currentClass)?.add(keyName);
|
|
3443
3447
|
}
|
|
3444
3448
|
}
|
|
@@ -3906,11 +3910,11 @@ function create$6(context) {
|
|
|
3906
3910
|
const nEntries = [];
|
|
3907
3911
|
return merge(hCollector.visitor, cCollector.visitor, {
|
|
3908
3912
|
CallExpression(node) {
|
|
3909
|
-
const expr =
|
|
3913
|
+
const expr = Extract.unwrapped(node.callee);
|
|
3910
3914
|
switch (true) {
|
|
3911
3915
|
case expr.type === AST_NODE_TYPES.Identifier: {
|
|
3912
3916
|
if (!IMPURE_FUNCS.get("globalThis")?.has(expr.name)) return;
|
|
3913
|
-
const func =
|
|
3917
|
+
const func = Traverse.findParent(node, Check.isFunction);
|
|
3914
3918
|
if (func == null) return;
|
|
3915
3919
|
cEntries.push({
|
|
3916
3920
|
func,
|
|
@@ -3922,7 +3926,7 @@ function create$6(context) {
|
|
|
3922
3926
|
const objectName = expr.object.name;
|
|
3923
3927
|
const propertyName = expr.property.name;
|
|
3924
3928
|
if (!IMPURE_FUNCS.get(objectName)?.has(propertyName)) return;
|
|
3925
|
-
const func =
|
|
3929
|
+
const func = Traverse.findParent(node, Check.isFunction);
|
|
3926
3930
|
if (func == null) return;
|
|
3927
3931
|
cEntries.push({
|
|
3928
3932
|
func,
|
|
@@ -3933,11 +3937,11 @@ function create$6(context) {
|
|
|
3933
3937
|
}
|
|
3934
3938
|
},
|
|
3935
3939
|
NewExpression(node) {
|
|
3936
|
-
const expr =
|
|
3940
|
+
const expr = Extract.unwrapped(node.callee);
|
|
3937
3941
|
if (expr.type !== AST_NODE_TYPES.Identifier) return;
|
|
3938
3942
|
if (!IMPURE_CTORS.has(expr.name)) return;
|
|
3939
3943
|
if (expr.name === "Date" && node.arguments.length > 0) return;
|
|
3940
|
-
const func =
|
|
3944
|
+
const func = Traverse.findParent(node, Check.isFunction);
|
|
3941
3945
|
if (func == null) return;
|
|
3942
3946
|
nEntries.push({
|
|
3943
3947
|
func,
|
|
@@ -3989,12 +3993,12 @@ function create$5(context) {
|
|
|
3989
3993
|
*/
|
|
3990
3994
|
function isInNullCheckTest(node) {
|
|
3991
3995
|
let parent = node.parent;
|
|
3992
|
-
while (
|
|
3996
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
3993
3997
|
if (!isMatching({
|
|
3994
3998
|
type: AST_NODE_TYPES.BinaryExpression,
|
|
3995
3999
|
operator: P.union("===", "==", "!==", "!=")
|
|
3996
4000
|
}, parent)) return false;
|
|
3997
|
-
const otherSide = parent.left === node ||
|
|
4001
|
+
const otherSide = parent.left === node || Extract.unwrapped(parent.left) === node ? parent.right : parent.left;
|
|
3998
4002
|
if (otherSide.type !== AST_NODE_TYPES.Literal || otherSide.value != null) return false;
|
|
3999
4003
|
return parent.parent.type === AST_NODE_TYPES.IfStatement && parent.parent.test === parent;
|
|
4000
4004
|
}
|
|
@@ -4010,8 +4014,8 @@ function create$5(context) {
|
|
|
4010
4014
|
if (op !== "===" && op !== "==" && op !== "!==" && op !== "!=") return false;
|
|
4011
4015
|
const { left, right } = test;
|
|
4012
4016
|
const checkSides = (a, b) => {
|
|
4013
|
-
a =
|
|
4014
|
-
return a.type === AST_NODE_TYPES.MemberExpression && a.object.type === AST_NODE_TYPES.Identifier && a.object.name === refName && b.type === AST_NODE_TYPES.Literal && b.value == null &&
|
|
4017
|
+
a = Check.isTypeExpression(a) ? Extract.unwrapped(a) : a;
|
|
4018
|
+
return a.type === AST_NODE_TYPES.MemberExpression && a.object.type === AST_NODE_TYPES.Identifier && a.object.name === refName && b.type === AST_NODE_TYPES.Literal && b.value == null && Extract.propertyName(a.property) === "current";
|
|
4015
4019
|
};
|
|
4016
4020
|
return checkSides(left, right) || checkSides(right, left);
|
|
4017
4021
|
}
|
|
@@ -4036,12 +4040,12 @@ function create$5(context) {
|
|
|
4036
4040
|
}
|
|
4037
4041
|
},
|
|
4038
4042
|
MemberExpression(node) {
|
|
4039
|
-
if (!
|
|
4043
|
+
if (!Check.identifier(node.property, "current")) return;
|
|
4040
4044
|
refAccesses.push({
|
|
4041
4045
|
isWrite: (() => {
|
|
4042
4046
|
let parent = node.parent;
|
|
4043
|
-
while (
|
|
4044
|
-
return match(parent).with({ type: AST_NODE_TYPES.AssignmentExpression }, (p) => p.left === node ||
|
|
4047
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
4048
|
+
return match(parent).with({ type: AST_NODE_TYPES.AssignmentExpression }, (p) => p.left === node || Extract.unwrapped(p.left) === node).with({ type: AST_NODE_TYPES.UpdateExpression }, (p) => p.argument === node || Extract.unwrapped(p.argument) === node).otherwise(() => false);
|
|
4045
4049
|
})(),
|
|
4046
4050
|
node
|
|
4047
4051
|
});
|
|
@@ -4050,7 +4054,7 @@ function create$5(context) {
|
|
|
4050
4054
|
const comps = cCollector.api.getAllComponents(program);
|
|
4051
4055
|
const hooks = hCollector.api.getAllHooks(program);
|
|
4052
4056
|
const funcs = new Set([...comps.map((c) => c.node), ...hooks.map((h) => h.node)]);
|
|
4053
|
-
const isCompOrHookFn = (n) =>
|
|
4057
|
+
const isCompOrHookFn = (n) => Check.isFunction(n) && funcs.has(n);
|
|
4054
4058
|
for (const { isWrite, node } of refAccesses) {
|
|
4055
4059
|
const obj = node.object;
|
|
4056
4060
|
if (obj.type !== AST_NODE_TYPES.Identifier) continue;
|
|
@@ -4060,9 +4064,9 @@ function create$5(context) {
|
|
|
4060
4064
|
case isInitializedFromRef(obj.name, context.sourceCode.getScope(node.object)): break;
|
|
4061
4065
|
default: continue;
|
|
4062
4066
|
}
|
|
4063
|
-
const boundary =
|
|
4067
|
+
const boundary = Traverse.findParent(node, isCompOrHookFn);
|
|
4064
4068
|
if (boundary == null) continue;
|
|
4065
|
-
if (
|
|
4069
|
+
if (Traverse.findParent(node, Check.isFunction) !== boundary) continue;
|
|
4066
4070
|
const refName = obj.name;
|
|
4067
4071
|
let isLazyInit = isInNullCheckTest(node);
|
|
4068
4072
|
if (!isLazyInit) {
|
|
@@ -6386,14 +6390,14 @@ function create$4(context) {
|
|
|
6386
6390
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
6387
6391
|
}
|
|
6388
6392
|
function getCallName(node) {
|
|
6389
|
-
if (node.type === AST_NODE_TYPES.CallExpression) return
|
|
6390
|
-
return
|
|
6393
|
+
if (node.type === AST_NODE_TYPES.CallExpression) return Extract.fullyQualifiedName(node.callee, getText);
|
|
6394
|
+
return Extract.fullyQualifiedName(node, getText);
|
|
6391
6395
|
}
|
|
6392
6396
|
function getCallKind(node) {
|
|
6393
6397
|
return match(node).when(isUseStateCall, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
6394
6398
|
}
|
|
6395
6399
|
function getFunctionKind(node) {
|
|
6396
|
-
const parent =
|
|
6400
|
+
const parent = Traverse.findParent(node, not(Check.isTypeExpression)) ?? node.parent;
|
|
6397
6401
|
switch (true) {
|
|
6398
6402
|
case node.async:
|
|
6399
6403
|
case parent.type === AST_NODE_TYPES.CallExpression && isThenCall(parent): return "deferred";
|
|
@@ -6477,7 +6481,7 @@ function create$4(context) {
|
|
|
6477
6481
|
case entry.kind === "deferred":
|
|
6478
6482
|
case entry.node.async: break;
|
|
6479
6483
|
case entry.node === setupFunction:
|
|
6480
|
-
case entry.kind === "immediate" &&
|
|
6484
|
+
case entry.kind === "immediate" && Traverse.findParent(entry.node, Check.isFunction) === setupFunction: {
|
|
6481
6485
|
const args0 = node.arguments.at(0);
|
|
6482
6486
|
if (args0 == null) return;
|
|
6483
6487
|
function isArgumentUsingRefValue(context, node) {
|
|
@@ -6490,7 +6494,7 @@ function create$4(context) {
|
|
|
6490
6494
|
}
|
|
6491
6495
|
};
|
|
6492
6496
|
if (isUsingRefValue(node)) return true;
|
|
6493
|
-
return
|
|
6497
|
+
return Check.isFunction(node) && context.sourceCode.getScope(node.body).references.some((r) => isUsingRefValue(r.identifier));
|
|
6494
6498
|
}
|
|
6495
6499
|
if (isArgumentUsingRefValue(context, args0)) return;
|
|
6496
6500
|
context.report({
|
|
@@ -6501,13 +6505,13 @@ function create$4(context) {
|
|
|
6501
6505
|
return;
|
|
6502
6506
|
}
|
|
6503
6507
|
default: {
|
|
6504
|
-
const init =
|
|
6508
|
+
const init = Traverse.findParent(node, isHookDecl)?.init;
|
|
6505
6509
|
if (init == null) getOrInsertComputed(setStateCallsByFn, entry.node, () => []).push(node);
|
|
6506
6510
|
else getOrInsertComputed(setStateInHookCallbacks, init, () => []).push(node);
|
|
6507
6511
|
}
|
|
6508
6512
|
}
|
|
6509
6513
|
}).with("useEffect", () => {
|
|
6510
|
-
if (
|
|
6514
|
+
if (Check.isFunction(node.arguments.at(0))) return;
|
|
6511
6515
|
setupFnIds.push(...getNestedIdentifiers(node));
|
|
6512
6516
|
}).with("other", () => {
|
|
6513
6517
|
if (entry.node !== setupFunction) return;
|
|
@@ -6522,14 +6526,14 @@ function create$4(context) {
|
|
|
6522
6526
|
const parent = node.parent.parent;
|
|
6523
6527
|
if (parent.type !== AST_NODE_TYPES.CallExpression) break;
|
|
6524
6528
|
if (!core.isUseMemoCall(context, parent)) break;
|
|
6525
|
-
const init =
|
|
6529
|
+
const init = Traverse.findParent(parent, isHookDecl)?.init;
|
|
6526
6530
|
if (init != null) getOrInsertComputed(setStateInEffectArg, init, () => []).push(node);
|
|
6527
6531
|
break;
|
|
6528
6532
|
}
|
|
6529
6533
|
case AST_NODE_TYPES.CallExpression:
|
|
6530
6534
|
if (node !== node.parent.arguments.at(0)) break;
|
|
6531
6535
|
if (core.isUseCallbackCall(context, node.parent)) {
|
|
6532
|
-
const init =
|
|
6536
|
+
const init = Traverse.findParent(node.parent, isHookDecl)?.init;
|
|
6533
6537
|
if (init != null) getOrInsertComputed(setStateInEffectArg, init, () => []).push(node);
|
|
6534
6538
|
break;
|
|
6535
6539
|
}
|
|
@@ -6642,7 +6646,7 @@ function create$3(context) {
|
|
|
6642
6646
|
function isInsideEventHandler(node, stopAt) {
|
|
6643
6647
|
let current = node.parent;
|
|
6644
6648
|
while (current != null && current !== stopAt) {
|
|
6645
|
-
if (
|
|
6649
|
+
if (Check.isFunction(current) && current !== stopAt) return true;
|
|
6646
6650
|
current = current.parent;
|
|
6647
6651
|
}
|
|
6648
6652
|
return false;
|
|
@@ -6656,7 +6660,7 @@ function create$3(context) {
|
|
|
6656
6660
|
}
|
|
6657
6661
|
function getFunctionKind(node) {
|
|
6658
6662
|
if (isComponentOrHookLikeFunction(node)) return "component";
|
|
6659
|
-
const parent =
|
|
6663
|
+
const parent = Traverse.findParent(node, not(Check.isTypeExpression)) ?? node.parent;
|
|
6660
6664
|
if (parent.type === AST_NODE_TYPES.CallExpression && parent.callee !== node) return "callback";
|
|
6661
6665
|
return "other";
|
|
6662
6666
|
}
|
|
@@ -6742,7 +6746,7 @@ function create$2(context) {
|
|
|
6742
6746
|
return merge(hCollector.visitor, cCollector.visitor, {
|
|
6743
6747
|
CallExpression(node) {
|
|
6744
6748
|
if (!isEvalCall(node)) return;
|
|
6745
|
-
const func =
|
|
6749
|
+
const func = Traverse.findParent(node, Check.isFunction);
|
|
6746
6750
|
if (func == null) return;
|
|
6747
6751
|
evalCalls.push({
|
|
6748
6752
|
func,
|
|
@@ -6781,7 +6785,7 @@ function create$2(context) {
|
|
|
6781
6785
|
}
|
|
6782
6786
|
},
|
|
6783
6787
|
WithStatement(node) {
|
|
6784
|
-
const func =
|
|
6788
|
+
const func = Traverse.findParent(node, Check.isFunction);
|
|
6785
6789
|
if (func == null) return;
|
|
6786
6790
|
withStmts.push({
|
|
6787
6791
|
func,
|
|
@@ -6813,7 +6817,7 @@ function create$1(context) {
|
|
|
6813
6817
|
return merge({ CallExpression(node) {
|
|
6814
6818
|
if (!core.isUseMemoCall(context, node)) return;
|
|
6815
6819
|
let parent = node.parent;
|
|
6816
|
-
while (
|
|
6820
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
6817
6821
|
if (!(parent.type === AST_NODE_TYPES.VariableDeclarator || parent.type === AST_NODE_TYPES.AssignmentExpression || parent.type === AST_NODE_TYPES.AssignmentPattern || parent.type === AST_NODE_TYPES.Property || parent.type === AST_NODE_TYPES.ReturnStatement || parent.type === AST_NODE_TYPES.JSXExpressionContainer || parent.type === AST_NODE_TYPES.CallExpression || parent.type === AST_NODE_TYPES.NewExpression || parent.type === AST_NODE_TYPES.ArrayExpression || parent.type === AST_NODE_TYPES.ConditionalExpression || parent.type === AST_NODE_TYPES.LogicalExpression || parent.type === AST_NODE_TYPES.SequenceExpression || parent.type === AST_NODE_TYPES.SpreadElement || parent.type === AST_NODE_TYPES.TemplateLiteral || parent.type === AST_NODE_TYPES.BinaryExpression || parent.type === AST_NODE_TYPES.UnaryExpression || parent.type === AST_NODE_TYPES.MemberExpression || parent.type === AST_NODE_TYPES.TaggedTemplateExpression || parent.type === AST_NODE_TYPES.ChainExpression || parent.type === AST_NODE_TYPES.ArrowFunctionExpression)) {
|
|
6818
6822
|
context.report({
|
|
6819
6823
|
messageId: "notAssignedToVariable",
|
|
@@ -6823,7 +6827,7 @@ function create$1(context) {
|
|
|
6823
6827
|
}
|
|
6824
6828
|
const [callbackArg] = node.arguments;
|
|
6825
6829
|
if (callbackArg == null) return;
|
|
6826
|
-
if (!
|
|
6830
|
+
if (!Check.isFunction(callbackArg)) return;
|
|
6827
6831
|
if (callbackArg.type === AST_NODE_TYPES.ArrowFunctionExpression && callbackArg.body.type !== AST_NODE_TYPES.BlockStatement) return;
|
|
6828
6832
|
if (callbackArg.body.type !== AST_NODE_TYPES.BlockStatement) return;
|
|
6829
6833
|
const returnStatements = getNestedReturnStatements(callbackArg);
|
|
@@ -6993,7 +6997,7 @@ function create(context) {
|
|
|
6993
6997
|
for (const expr of getNestedNewExpressions(useStateInput)) {
|
|
6994
6998
|
if (!("name" in expr.callee)) continue;
|
|
6995
6999
|
if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
6996
|
-
if (
|
|
7000
|
+
if (Traverse.findParent(expr, (n) => core.isUseCall(context, n)) != null) continue;
|
|
6997
7001
|
context.report({
|
|
6998
7002
|
messageId: "invalidInitialization",
|
|
6999
7003
|
node: expr
|
|
@@ -7003,7 +7007,7 @@ function create(context) {
|
|
|
7003
7007
|
if (!("name" in expr.callee)) continue;
|
|
7004
7008
|
if (core.isHookName(expr.callee.name)) continue;
|
|
7005
7009
|
if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
7006
|
-
if (
|
|
7010
|
+
if (Traverse.findParent(expr, (n) => core.isUseCall(context, n)) != null) continue;
|
|
7007
7011
|
context.report({
|
|
7008
7012
|
messageId: "invalidInitialization",
|
|
7009
7013
|
node: expr
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.2-beta.0",
|
|
4
4
|
"description": "A set of composable ESLint rules for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"string-ts": "^2.3.1",
|
|
47
47
|
"ts-api-utils": "^2.5.0",
|
|
48
48
|
"ts-pattern": "^5.9.0",
|
|
49
|
-
"@eslint-react/ast": "5.2.
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/jsx": "5.2.
|
|
53
|
-
"@eslint-react/var": "5.2.
|
|
54
|
-
"@eslint-react/
|
|
49
|
+
"@eslint-react/ast": "5.2.2-beta.0",
|
|
50
|
+
"@eslint-react/core": "5.2.2-beta.0",
|
|
51
|
+
"@eslint-react/eslint": "5.2.2-beta.0",
|
|
52
|
+
"@eslint-react/jsx": "5.2.2-beta.0",
|
|
53
|
+
"@eslint-react/var": "5.2.2-beta.0",
|
|
54
|
+
"@eslint-react/shared": "5.2.2-beta.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/react": "^19.2.14",
|