eslint-plugin-react-x 5.2.5-next.0 → 5.3.0-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 +264 -240
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -142,7 +142,7 @@ const rules$7 = {
|
|
|
142
142
|
//#endregion
|
|
143
143
|
//#region package.json
|
|
144
144
|
var name$6 = "eslint-plugin-react-x";
|
|
145
|
-
var version = "5.
|
|
145
|
+
var version = "5.3.0-beta.0";
|
|
146
146
|
|
|
147
147
|
//#endregion
|
|
148
148
|
//#region src/rules/component-hook-factories/lib.ts
|
|
@@ -215,14 +215,14 @@ var component_hook_factories_default = createRule({
|
|
|
215
215
|
});
|
|
216
216
|
function create$48(context) {
|
|
217
217
|
const hint = core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.FunctionComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.FunctionComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayPatternElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayExpressionElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
const
|
|
218
|
+
const fc = core.getFunctionComponentCollector(context, { hint });
|
|
219
|
+
const cc = core.getClassComponentCollector(context);
|
|
220
|
+
const hc = core.getHookCollector(context);
|
|
221
221
|
const reported = /* @__PURE__ */ new Set();
|
|
222
|
-
return merge(
|
|
223
|
-
const fComponents = [...
|
|
224
|
-
const cComponents = [...
|
|
225
|
-
const hooks = [...
|
|
222
|
+
return merge(fc.visitor, cc.visitor, hc.visitor, { "Program:exit"(program) {
|
|
223
|
+
const fComponents = [...fc.api.getAllComponents(program)];
|
|
224
|
+
const cComponents = [...cc.api.getAllComponents(program)];
|
|
225
|
+
const hooks = [...hc.api.getAllHooks(program)];
|
|
226
226
|
for (const { name, node } of fComponents) {
|
|
227
227
|
if (name == null) continue;
|
|
228
228
|
const parentFn = Traverse.findParent(node, Check.isFunction);
|
|
@@ -282,18 +282,18 @@ var error_boundaries_default = createRule({
|
|
|
282
282
|
function create$47(context) {
|
|
283
283
|
if (!context.sourceCode.text.includes("try")) return {};
|
|
284
284
|
const hint = JsxDetectionHint.DoNotIncludeJsxWithNullValue | JsxDetectionHint.DoNotIncludeJsxWithNumberValue | JsxDetectionHint.DoNotIncludeJsxWithBigIntValue | JsxDetectionHint.DoNotIncludeJsxWithStringValue | JsxDetectionHint.DoNotIncludeJsxWithBooleanValue | JsxDetectionHint.DoNotIncludeJsxWithUndefinedValue | JsxDetectionHint.DoNotIncludeJsxWithEmptyArrayValue;
|
|
285
|
-
const
|
|
286
|
-
const
|
|
285
|
+
const fc = core.getFunctionComponentCollector(context);
|
|
286
|
+
const hc = core.getHookCollector(context);
|
|
287
287
|
const reported = /* @__PURE__ */ new Set();
|
|
288
288
|
const useCalls = /* @__PURE__ */ new Set();
|
|
289
|
-
return merge(
|
|
289
|
+
return merge(fc.visitor, hc.visitor, {
|
|
290
290
|
CallExpression(node) {
|
|
291
291
|
if (!core.isUseCall(context, node)) return;
|
|
292
292
|
useCalls.add(node);
|
|
293
293
|
},
|
|
294
294
|
"Program:exit"(node) {
|
|
295
|
-
const comps =
|
|
296
|
-
const hooks =
|
|
295
|
+
const comps = fc.api.getAllComponents(node);
|
|
296
|
+
const hooks = hc.api.getAllHooks(node);
|
|
297
297
|
const funcs = [...comps, ...hooks];
|
|
298
298
|
for (const call of useCalls) {
|
|
299
299
|
const stmt = Traverse.findParent(call, is(AST_NODE_TYPES.TryStatement));
|
|
@@ -1229,8 +1229,7 @@ function getUnknownDependenciesMessage(reactiveHookName) {
|
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
1231
|
//#endregion
|
|
1232
|
-
//#region src/rules/immutability/
|
|
1233
|
-
const RULE_NAME$46 = "immutability";
|
|
1232
|
+
//#region src/rules/immutability/lib.ts
|
|
1234
1233
|
/**
|
|
1235
1234
|
* Array methods that mutate the array in place.
|
|
1236
1235
|
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
@@ -1246,6 +1245,10 @@ const MUTATING_ARRAY_METHODS = new Set([
|
|
|
1246
1245
|
"splice",
|
|
1247
1246
|
"unshift"
|
|
1248
1247
|
]);
|
|
1248
|
+
|
|
1249
|
+
//#endregion
|
|
1250
|
+
//#region src/rules/immutability/immutability.ts
|
|
1251
|
+
const RULE_NAME$46 = "immutability";
|
|
1249
1252
|
var immutability_default = createRule({
|
|
1250
1253
|
meta: {
|
|
1251
1254
|
type: "problem",
|
|
@@ -1262,8 +1265,8 @@ var immutability_default = createRule({
|
|
|
1262
1265
|
});
|
|
1263
1266
|
function create$46(context) {
|
|
1264
1267
|
const { additionalStateHooks } = getSettingsFromContext(context);
|
|
1265
|
-
const
|
|
1266
|
-
const
|
|
1268
|
+
const hc = core.getHookCollector(context);
|
|
1269
|
+
const fc = core.getFunctionComponentCollector(context);
|
|
1267
1270
|
/**
|
|
1268
1271
|
* Violations accumulated while traversing. Each entry records the node to
|
|
1269
1272
|
* report and the enclosing function so we can filter at Program:exit.
|
|
@@ -1318,7 +1321,7 @@ function create$46(context) {
|
|
|
1318
1321
|
}
|
|
1319
1322
|
return null;
|
|
1320
1323
|
}
|
|
1321
|
-
return merge(
|
|
1324
|
+
return merge(hc.visitor, fc.visitor, {
|
|
1322
1325
|
CallExpression(node) {
|
|
1323
1326
|
if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
1324
1327
|
const { object, property } = node.callee;
|
|
@@ -1362,8 +1365,8 @@ function create$46(context) {
|
|
|
1362
1365
|
});
|
|
1363
1366
|
},
|
|
1364
1367
|
"Program:exit"(node) {
|
|
1365
|
-
const comps =
|
|
1366
|
-
const hooks =
|
|
1368
|
+
const comps = fc.api.getAllComponents(node);
|
|
1369
|
+
const hooks = hc.api.getAllHooks(node);
|
|
1367
1370
|
const funcs = [...comps, ...hooks];
|
|
1368
1371
|
for (const { data, func, messageId, node, propsDefiningFunc } of violations) {
|
|
1369
1372
|
let current = func;
|
|
@@ -1667,10 +1670,6 @@ function report$2(context) {
|
|
|
1667
1670
|
return context.report(descriptor);
|
|
1668
1671
|
};
|
|
1669
1672
|
}
|
|
1670
|
-
|
|
1671
|
-
//#endregion
|
|
1672
|
-
//#region src/rules/no-array-index-key/no-array-index-key.ts
|
|
1673
|
-
const RULE_NAME$44 = "no-array-index-key";
|
|
1674
1673
|
function getIndexParamPosition(methodName) {
|
|
1675
1674
|
switch (methodName) {
|
|
1676
1675
|
case "every":
|
|
@@ -1708,6 +1707,10 @@ function getIdentifiersFromBinaryExpression(side) {
|
|
|
1708
1707
|
if (side.type === AST_NODE_TYPES.BinaryExpression) return [...getIdentifiersFromBinaryExpression(side.left), ...getIdentifiersFromBinaryExpression(side.right)];
|
|
1709
1708
|
return [];
|
|
1710
1709
|
}
|
|
1710
|
+
|
|
1711
|
+
//#endregion
|
|
1712
|
+
//#region src/rules/no-array-index-key/no-array-index-key.ts
|
|
1713
|
+
const RULE_NAME$44 = "no-array-index-key";
|
|
1711
1714
|
var no_array_index_key_default = createRule({
|
|
1712
1715
|
meta: {
|
|
1713
1716
|
type: "suggestion",
|
|
@@ -2123,7 +2126,7 @@ function create$32(context) {
|
|
|
2123
2126
|
//#region src/rules/no-direct-mutation-state/no-direct-mutation-state.ts
|
|
2124
2127
|
const RULE_NAME$31 = "no-direct-mutation-state";
|
|
2125
2128
|
function isConstructorFunction(node) {
|
|
2126
|
-
return isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && Check.
|
|
2129
|
+
return isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && Check.isPropertyOrMethod(node.parent) && node.parent.key.type === AST_NODE_TYPES.Identifier && node.parent.key.name === "constructor";
|
|
2127
2130
|
}
|
|
2128
2131
|
var no_direct_mutation_state_default = createRule({
|
|
2129
2132
|
meta: {
|
|
@@ -2768,6 +2771,10 @@ function isProcessEnvNodeEnvCompare(node, operator, value) {
|
|
|
2768
2771
|
if (Check.isLiteral("string")(node.left) && isProcessEnvNodeEnv(node.right)) return node.left.value === value;
|
|
2769
2772
|
return false;
|
|
2770
2773
|
}
|
|
2774
|
+
function isDevelopmentOnlyCheck(node) {
|
|
2775
|
+
if (node.type !== AST_NODE_TYPES.IfStatement) return false;
|
|
2776
|
+
return isProcessEnvNodeEnvCompare(node.test, "!==", "production");
|
|
2777
|
+
}
|
|
2771
2778
|
|
|
2772
2779
|
//#endregion
|
|
2773
2780
|
//#region src/rules/no-misused-capture-owner-stack/no-misused-capture-owner-stack.ts
|
|
@@ -2810,9 +2817,38 @@ function create$21(context) {
|
|
|
2810
2817
|
}
|
|
2811
2818
|
});
|
|
2812
2819
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2820
|
+
|
|
2821
|
+
//#endregion
|
|
2822
|
+
//#region src/rules/no-nested-component-definitions/lib.ts
|
|
2823
|
+
/**
|
|
2824
|
+
* Determine whether the node is inside JSX attribute value
|
|
2825
|
+
* @param node The AST node to check
|
|
2826
|
+
* @returns `true` if the node is inside JSX attribute value
|
|
2827
|
+
*/
|
|
2828
|
+
function isInsideJSXAttributeValue(node) {
|
|
2829
|
+
return node.parent.type === AST_NODE_TYPES.JSXAttribute || findParentAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
|
|
2830
|
+
}
|
|
2831
|
+
/**
|
|
2832
|
+
* Check whether a given node is declared inside a class component's render block
|
|
2833
|
+
* Ex: class C extends React.Component { render() { const Nested = () => <div />; } }
|
|
2834
|
+
* @param node The AST node being checked
|
|
2835
|
+
* @returns `true` if the node is inside a class component's render block
|
|
2836
|
+
*/
|
|
2837
|
+
function isInsideRenderMethod(node) {
|
|
2838
|
+
return Traverse.findParent(node, (n) => core.isRenderMethodLike(n) && core.isClassComponent(n.parent.parent)) != null;
|
|
2839
|
+
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Determine whether the node is inside `createElement`'s props argument
|
|
2842
|
+
* @param context The rule context
|
|
2843
|
+
* @param node The AST node to check
|
|
2844
|
+
* @returns `true` if the node is inside `createElement`'s props
|
|
2845
|
+
*/
|
|
2846
|
+
function isInsideCreateElementProps(context, node) {
|
|
2847
|
+
const call = Traverse.findParent(node, core.isCreateElementCall(context));
|
|
2848
|
+
if (call == null) return false;
|
|
2849
|
+
const prop = Traverse.findParent(node, is(AST_NODE_TYPES.ObjectExpression));
|
|
2850
|
+
if (prop == null) return false;
|
|
2851
|
+
return prop === call.arguments[1];
|
|
2816
2852
|
}
|
|
2817
2853
|
|
|
2818
2854
|
//#endregion
|
|
@@ -2831,11 +2867,11 @@ var no_nested_component_definitions_default = createRule({
|
|
|
2831
2867
|
});
|
|
2832
2868
|
function create$20(context) {
|
|
2833
2869
|
const hint = core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.FunctionComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.FunctionComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayPatternElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayExpressionElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
|
|
2834
|
-
const
|
|
2835
|
-
const
|
|
2836
|
-
return merge(
|
|
2837
|
-
const fComponents = [...
|
|
2838
|
-
const cComponents = [...
|
|
2870
|
+
const fc = core.getFunctionComponentCollector(context, { hint });
|
|
2871
|
+
const cc = core.getClassComponentCollector(context);
|
|
2872
|
+
return merge(fc.visitor, cc.visitor, { "Program:exit"(program) {
|
|
2873
|
+
const fComponents = [...fc.api.getAllComponents(program)];
|
|
2874
|
+
const cComponents = [...cc.api.getAllComponents(program)];
|
|
2839
2875
|
function findEnclosingComponent(node) {
|
|
2840
2876
|
return Traverse.findParent(node, (n) => {
|
|
2841
2877
|
if (Check.isFunction(n)) return fComponents.some((c) => c.node === n);
|
|
@@ -2900,36 +2936,6 @@ function create$20(context) {
|
|
|
2900
2936
|
}
|
|
2901
2937
|
} });
|
|
2902
2938
|
}
|
|
2903
|
-
/**
|
|
2904
|
-
* Determine whether the node is inside JSX attribute value
|
|
2905
|
-
* @param node The AST node to check
|
|
2906
|
-
* @returns `true` if the node is inside JSX attribute value
|
|
2907
|
-
*/
|
|
2908
|
-
function isInsideJSXAttributeValue(node) {
|
|
2909
|
-
return node.parent.type === AST_NODE_TYPES.JSXAttribute || findParentAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
|
|
2910
|
-
}
|
|
2911
|
-
/**
|
|
2912
|
-
* Check whether a given node is declared inside a class component's render block
|
|
2913
|
-
* Ex: class C extends React.Component { render() { const Nested = () => <div />; } }
|
|
2914
|
-
* @param node The AST node being checked
|
|
2915
|
-
* @returns `true` if the node is inside a class component's render block
|
|
2916
|
-
*/
|
|
2917
|
-
function isInsideRenderMethod(node) {
|
|
2918
|
-
return Traverse.findParent(node, (n) => core.isRenderMethodLike(n) && core.isClassComponent(n.parent.parent)) != null;
|
|
2919
|
-
}
|
|
2920
|
-
/**
|
|
2921
|
-
* Determine whether the node is inside `createElement`'s props argument
|
|
2922
|
-
* @param context The rule context
|
|
2923
|
-
* @param node The AST node to check
|
|
2924
|
-
* @returns `true` if the node is inside `createElement`'s props
|
|
2925
|
-
*/
|
|
2926
|
-
function isInsideCreateElementProps(context, node) {
|
|
2927
|
-
const call = Traverse.findParent(node, core.isCreateElementCall(context));
|
|
2928
|
-
if (call == null) return false;
|
|
2929
|
-
const prop = Traverse.findParent(node, is(AST_NODE_TYPES.ObjectExpression));
|
|
2930
|
-
if (prop == null) return false;
|
|
2931
|
-
return prop === call.arguments[1];
|
|
2932
|
-
}
|
|
2933
2939
|
|
|
2934
2940
|
//#endregion
|
|
2935
2941
|
//#region src/rules/no-nested-lazy-component-declarations/no-nested-lazy-component-declarations.ts
|
|
@@ -2946,20 +2952,20 @@ var no_nested_lazy_component_declarations_default = createRule({
|
|
|
2946
2952
|
defaultOptions: []
|
|
2947
2953
|
});
|
|
2948
2954
|
function create$19(context) {
|
|
2949
|
-
const
|
|
2950
|
-
const
|
|
2951
|
-
const
|
|
2955
|
+
const fc = core.getFunctionComponentCollector(context);
|
|
2956
|
+
const cc = core.getClassComponentCollector(context);
|
|
2957
|
+
const hc = core.getHookCollector(context);
|
|
2952
2958
|
const lazyCalls = /* @__PURE__ */ new Set();
|
|
2953
|
-
return merge(
|
|
2959
|
+
return merge(fc.visitor, cc.visitor, hc.visitor, {
|
|
2954
2960
|
ImportExpression(node) {
|
|
2955
2961
|
const lazyCall = Traverse.findParent(node, (n) => core.isLazyCall(context, n));
|
|
2956
2962
|
if (lazyCall != null) lazyCalls.add(lazyCall);
|
|
2957
2963
|
},
|
|
2958
2964
|
"Program:exit"(program) {
|
|
2959
2965
|
const significantParents = [
|
|
2960
|
-
...
|
|
2961
|
-
...
|
|
2962
|
-
...
|
|
2966
|
+
...fc.api.getAllComponents(program),
|
|
2967
|
+
...hc.api.getAllHooks(program),
|
|
2968
|
+
...cc.api.getAllComponents(program)
|
|
2963
2969
|
];
|
|
2964
2970
|
for (const lazy of lazyCalls) if (Traverse.findParent(lazy, (n) => significantParents.some((p) => p.node === n))) context.report({
|
|
2965
2971
|
messageId: "default",
|
|
@@ -3189,6 +3195,14 @@ function create$12(context) {
|
|
|
3189
3195
|
} });
|
|
3190
3196
|
}
|
|
3191
3197
|
|
|
3198
|
+
//#endregion
|
|
3199
|
+
//#region src/rules/no-unstable-context-value/lib.ts
|
|
3200
|
+
function isContextName(name, isReact18OrBelow) {
|
|
3201
|
+
if (name === "Provider") return true;
|
|
3202
|
+
if (!isReact18OrBelow) return name.endsWith("Context") || name.endsWith("CONTEXT");
|
|
3203
|
+
return false;
|
|
3204
|
+
}
|
|
3205
|
+
|
|
3192
3206
|
//#endregion
|
|
3193
3207
|
//#region src/rules/no-unstable-context-value/no-unstable-context-value.ts
|
|
3194
3208
|
const RULE_NAME$11 = "no-unstable-context-value";
|
|
@@ -3247,11 +3261,6 @@ function create$11(context) {
|
|
|
3247
3261
|
}
|
|
3248
3262
|
});
|
|
3249
3263
|
}
|
|
3250
|
-
function isContextName(name, isReact18OrBelow) {
|
|
3251
|
-
if (name === "Provider") return true;
|
|
3252
|
-
if (!isReact18OrBelow) return name.endsWith("Context") || name.endsWith("CONTEXT");
|
|
3253
|
-
return false;
|
|
3254
|
-
}
|
|
3255
3264
|
|
|
3256
3265
|
//#endregion
|
|
3257
3266
|
//#region src/rules/no-unstable-default-props/lib.ts
|
|
@@ -3337,8 +3346,7 @@ function create$10(context, [options]) {
|
|
|
3337
3346
|
}
|
|
3338
3347
|
|
|
3339
3348
|
//#endregion
|
|
3340
|
-
//#region src/rules/no-unused-class-component-members/
|
|
3341
|
-
const RULE_NAME$9 = "no-unused-class-component-members";
|
|
3349
|
+
//#region src/rules/no-unused-class-component-members/lib.ts
|
|
3342
3350
|
const LIFECYCLE_METHODS = new Set([
|
|
3343
3351
|
"componentDidCatch",
|
|
3344
3352
|
"componentDidMount",
|
|
@@ -3362,6 +3370,10 @@ function isKeyLiteral(node, key) {
|
|
|
3362
3370
|
expressions: []
|
|
3363
3371
|
}, constTrue).with({ type: AST_NODE_TYPES.Identifier }, () => !node.computed).otherwise(constFalse);
|
|
3364
3372
|
}
|
|
3373
|
+
|
|
3374
|
+
//#endregion
|
|
3375
|
+
//#region src/rules/no-unused-class-component-members/no-unused-class-component-members.ts
|
|
3376
|
+
const RULE_NAME$9 = "no-unused-class-component-members";
|
|
3365
3377
|
var no_unused_class_component_members_default = createRule({
|
|
3366
3378
|
meta: {
|
|
3367
3379
|
type: "suggestion",
|
|
@@ -3453,43 +3465,7 @@ function create$9(context) {
|
|
|
3453
3465
|
}
|
|
3454
3466
|
|
|
3455
3467
|
//#endregion
|
|
3456
|
-
//#region src/rules/no-unused-props/
|
|
3457
|
-
const RULE_NAME$8 = "no-unused-props";
|
|
3458
|
-
var no_unused_props_default = createRule({
|
|
3459
|
-
meta: {
|
|
3460
|
-
type: "suggestion",
|
|
3461
|
-
docs: { description: "Warns about component props that are defined but never used." },
|
|
3462
|
-
messages: { default: "Prop `{{name}}` is declared but never used" },
|
|
3463
|
-
schema: []
|
|
3464
|
-
},
|
|
3465
|
-
name: RULE_NAME$8,
|
|
3466
|
-
create: create$8,
|
|
3467
|
-
defaultOptions: []
|
|
3468
|
-
});
|
|
3469
|
-
function create$8(context) {
|
|
3470
|
-
const services = ESLintUtils.getParserServices(context, false);
|
|
3471
|
-
const checker = services.program.getTypeChecker();
|
|
3472
|
-
const { api, visitor } = core.getFunctionComponentCollector(context);
|
|
3473
|
-
return merge(visitor, { "Program:exit"(program) {
|
|
3474
|
-
const totalDeclaredProps = /* @__PURE__ */ new Map();
|
|
3475
|
-
const totalUsedDeclarations = /* @__PURE__ */ new Set();
|
|
3476
|
-
for (const component of api.getAllComponents(program)) {
|
|
3477
|
-
const [props] = component.node.params;
|
|
3478
|
-
if (props == null) continue;
|
|
3479
|
-
const usedPropKeys = /* @__PURE__ */ new Set();
|
|
3480
|
-
if (!collectUsedPropKeysOfParameter(context, usedPropKeys, props)) continue;
|
|
3481
|
-
const tsNode = services.esTreeNodeToTSNodeMap.get(props);
|
|
3482
|
-
const declaredProps = checker.getTypeAtLocation(tsNode).getProperties();
|
|
3483
|
-
for (const declaredProp of declaredProps) {
|
|
3484
|
-
const declaration = declaredProp.getDeclarations()?.[0];
|
|
3485
|
-
if (declaration == null) continue;
|
|
3486
|
-
if (!totalDeclaredProps.has(declaration)) totalDeclaredProps.set(declaration, declaredProp);
|
|
3487
|
-
if (usedPropKeys.has(declaredProp.name)) totalUsedDeclarations.add(declaration);
|
|
3488
|
-
}
|
|
3489
|
-
}
|
|
3490
|
-
for (const [declaration, symbol] of totalDeclaredProps.entries()) if (!totalUsedDeclarations.has(declaration)) reportUnusedProp(context, services, symbol);
|
|
3491
|
-
} });
|
|
3492
|
-
}
|
|
3468
|
+
//#region src/rules/no-unused-props/lib.ts
|
|
3493
3469
|
function collectUsedPropKeysOfParameter(context, usedPropKeys, parameter) {
|
|
3494
3470
|
switch (parameter.type) {
|
|
3495
3471
|
case AST_NODE_TYPES.Identifier: return collectUsedPropKeysOfIdentifier(context, usedPropKeys, parameter);
|
|
@@ -3552,6 +3528,45 @@ function getKeyOfExpression(expr) {
|
|
|
3552
3528
|
}
|
|
3553
3529
|
return null;
|
|
3554
3530
|
}
|
|
3531
|
+
|
|
3532
|
+
//#endregion
|
|
3533
|
+
//#region src/rules/no-unused-props/no-unused-props.ts
|
|
3534
|
+
const RULE_NAME$8 = "no-unused-props";
|
|
3535
|
+
var no_unused_props_default = createRule({
|
|
3536
|
+
meta: {
|
|
3537
|
+
type: "suggestion",
|
|
3538
|
+
docs: { description: "Warns about component props that are defined but never used." },
|
|
3539
|
+
messages: { default: "Prop `{{name}}` is declared but never used" },
|
|
3540
|
+
schema: []
|
|
3541
|
+
},
|
|
3542
|
+
name: RULE_NAME$8,
|
|
3543
|
+
create: create$8,
|
|
3544
|
+
defaultOptions: []
|
|
3545
|
+
});
|
|
3546
|
+
function create$8(context) {
|
|
3547
|
+
const services = ESLintUtils.getParserServices(context, false);
|
|
3548
|
+
const checker = services.program.getTypeChecker();
|
|
3549
|
+
const { api, visitor } = core.getFunctionComponentCollector(context);
|
|
3550
|
+
return merge(visitor, { "Program:exit"(program) {
|
|
3551
|
+
const totalDeclaredProps = /* @__PURE__ */ new Map();
|
|
3552
|
+
const totalUsedDeclarations = /* @__PURE__ */ new Set();
|
|
3553
|
+
for (const component of api.getAllComponents(program)) {
|
|
3554
|
+
const [props] = component.node.params;
|
|
3555
|
+
if (props == null) continue;
|
|
3556
|
+
const usedPropKeys = /* @__PURE__ */ new Set();
|
|
3557
|
+
if (!collectUsedPropKeysOfParameter(context, usedPropKeys, props)) continue;
|
|
3558
|
+
const tsNode = services.esTreeNodeToTSNodeMap.get(props);
|
|
3559
|
+
const declaredProps = checker.getTypeAtLocation(tsNode).getProperties();
|
|
3560
|
+
for (const declaredProp of declaredProps) {
|
|
3561
|
+
const declaration = declaredProp.getDeclarations()?.[0];
|
|
3562
|
+
if (declaration == null) continue;
|
|
3563
|
+
if (!totalDeclaredProps.has(declaration)) totalDeclaredProps.set(declaration, declaredProp);
|
|
3564
|
+
if (usedPropKeys.has(declaredProp.name)) totalUsedDeclarations.add(declaration);
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
for (const [declaration, symbol] of totalDeclaredProps.entries()) if (!totalUsedDeclarations.has(declaration)) reportUnusedProp(context, services, symbol);
|
|
3568
|
+
} });
|
|
3569
|
+
}
|
|
3555
3570
|
function reportUnusedProp(context, services, prop) {
|
|
3556
3571
|
const declaration = prop.getDeclarations()?.[0];
|
|
3557
3572
|
if (declaration == null) return;
|
|
@@ -3906,11 +3921,11 @@ var purity_default = createRule({
|
|
|
3906
3921
|
defaultOptions: []
|
|
3907
3922
|
});
|
|
3908
3923
|
function create$6(context) {
|
|
3909
|
-
const
|
|
3910
|
-
const
|
|
3924
|
+
const hc = core.getHookCollector(context);
|
|
3925
|
+
const fc = core.getFunctionComponentCollector(context);
|
|
3911
3926
|
const cEntries = [];
|
|
3912
3927
|
const nEntries = [];
|
|
3913
|
-
return merge(
|
|
3928
|
+
return merge(hc.visitor, fc.visitor, {
|
|
3914
3929
|
CallExpression(node) {
|
|
3915
3930
|
const expr = Extract.unwrap(node.callee);
|
|
3916
3931
|
switch (true) {
|
|
@@ -3951,8 +3966,8 @@ function create$6(context) {
|
|
|
3951
3966
|
});
|
|
3952
3967
|
},
|
|
3953
3968
|
"Program:exit"(node) {
|
|
3954
|
-
const comps =
|
|
3955
|
-
const hooks =
|
|
3969
|
+
const comps = fc.api.getAllComponents(node);
|
|
3970
|
+
const hooks = hc.api.getAllHooks(node);
|
|
3956
3971
|
const funcs = [...comps, ...hooks];
|
|
3957
3972
|
for (const { func, node } of [...cEntries, ...nEntries]) {
|
|
3958
3973
|
if (!funcs.some((f) => f.node === func)) continue;
|
|
@@ -3966,6 +3981,54 @@ function create$6(context) {
|
|
|
3966
3981
|
});
|
|
3967
3982
|
}
|
|
3968
3983
|
|
|
3984
|
+
//#endregion
|
|
3985
|
+
//#region src/rules/refs/lib.ts
|
|
3986
|
+
/**
|
|
3987
|
+
* Check if the node is the operand of a `ref.current === null` test inside an IfStatement.
|
|
3988
|
+
* @param node The MemberExpression node for ref.current
|
|
3989
|
+
* @returns true if the node is part of a null check test in an if statement
|
|
3990
|
+
*/
|
|
3991
|
+
function isInNullCheckTest(node) {
|
|
3992
|
+
let parent = node.parent;
|
|
3993
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
3994
|
+
if (!isMatching({
|
|
3995
|
+
type: AST_NODE_TYPES.BinaryExpression,
|
|
3996
|
+
operator: P.union("===", "==", "!==", "!=")
|
|
3997
|
+
}, parent)) return false;
|
|
3998
|
+
const otherSide = parent.left === node || Extract.unwrap(parent.left) === node ? parent.right : parent.left;
|
|
3999
|
+
if (otherSide.type !== AST_NODE_TYPES.Literal || otherSide.value != null) return false;
|
|
4000
|
+
return parent.parent.type === AST_NODE_TYPES.IfStatement && parent.parent.test === parent;
|
|
4001
|
+
}
|
|
4002
|
+
/**
|
|
4003
|
+
* Check if a test expression is a null check on `ref.current` for a given ref name.
|
|
4004
|
+
* Matches forms like `ref.current === null`, `null === ref.current`, and their != variants.
|
|
4005
|
+
* @param test The test expression to check.
|
|
4006
|
+
* @param refName The name of the ref variable.
|
|
4007
|
+
*/
|
|
4008
|
+
function isRefCurrentNullCheck(test, refName) {
|
|
4009
|
+
if (test.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
4010
|
+
const op = test.operator;
|
|
4011
|
+
if (op !== "===" && op !== "==" && op !== "!==" && op !== "!=") return false;
|
|
4012
|
+
const { left, right } = test;
|
|
4013
|
+
const checkSides = (a, b) => {
|
|
4014
|
+
a = Check.isTypeExpression(a) ? Extract.unwrap(a) : a;
|
|
4015
|
+
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.getPropertyName(a.property) === "current";
|
|
4016
|
+
};
|
|
4017
|
+
return checkSides(left, right) || checkSides(right, left);
|
|
4018
|
+
}
|
|
4019
|
+
function isInitializedFromRef$1(context, name, initialScope) {
|
|
4020
|
+
for (const { node } of findVariable(initialScope, name)?.defs ?? []) {
|
|
4021
|
+
if (node.type !== AST_NODE_TYPES.VariableDeclarator) continue;
|
|
4022
|
+
const init = node.init;
|
|
4023
|
+
if (init == null) continue;
|
|
4024
|
+
switch (true) {
|
|
4025
|
+
case init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier && (init.object.name === "ref" || init.object.name.endsWith("Ref")): return true;
|
|
4026
|
+
case init.type === AST_NODE_TYPES.CallExpression && core.isUseRefCall(context, init): return true;
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
return false;
|
|
4030
|
+
}
|
|
4031
|
+
|
|
3969
4032
|
//#endregion
|
|
3970
4033
|
//#region src/rules/refs/refs.ts
|
|
3971
4034
|
const RULE_NAME$5 = "refs";
|
|
@@ -3984,56 +4047,11 @@ var refs_default = createRule({
|
|
|
3984
4047
|
defaultOptions: []
|
|
3985
4048
|
});
|
|
3986
4049
|
function create$5(context) {
|
|
3987
|
-
const
|
|
3988
|
-
const
|
|
4050
|
+
const hc = core.getHookCollector(context);
|
|
4051
|
+
const fc = core.getFunctionComponentCollector(context);
|
|
3989
4052
|
const refAccesses = [];
|
|
3990
4053
|
const jsxRefIdentifiers = /* @__PURE__ */ new Set();
|
|
3991
|
-
|
|
3992
|
-
* Check if the node is the operand of a `ref.current === null` test inside an IfStatement.
|
|
3993
|
-
* @param node The MemberExpression node for ref.current
|
|
3994
|
-
* @returns true if the node is part of a null check test in an if statement
|
|
3995
|
-
*/
|
|
3996
|
-
function isInNullCheckTest(node) {
|
|
3997
|
-
let parent = node.parent;
|
|
3998
|
-
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
3999
|
-
if (!isMatching({
|
|
4000
|
-
type: AST_NODE_TYPES.BinaryExpression,
|
|
4001
|
-
operator: P.union("===", "==", "!==", "!=")
|
|
4002
|
-
}, parent)) return false;
|
|
4003
|
-
const otherSide = parent.left === node || Extract.unwrap(parent.left) === node ? parent.right : parent.left;
|
|
4004
|
-
if (otherSide.type !== AST_NODE_TYPES.Literal || otherSide.value != null) return false;
|
|
4005
|
-
return parent.parent.type === AST_NODE_TYPES.IfStatement && parent.parent.test === parent;
|
|
4006
|
-
}
|
|
4007
|
-
/**
|
|
4008
|
-
* Check if a test expression is a null check on `ref.current` for a given ref name.
|
|
4009
|
-
* Matches forms like `ref.current === null`, `null === ref.current`, and their != variants.
|
|
4010
|
-
* @param test The test expression to check.
|
|
4011
|
-
* @param refName The name of the ref variable.
|
|
4012
|
-
*/
|
|
4013
|
-
function isRefCurrentNullCheck(test, refName) {
|
|
4014
|
-
if (test.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
4015
|
-
const op = test.operator;
|
|
4016
|
-
if (op !== "===" && op !== "==" && op !== "!==" && op !== "!=") return false;
|
|
4017
|
-
const { left, right } = test;
|
|
4018
|
-
const checkSides = (a, b) => {
|
|
4019
|
-
a = Check.isTypeExpression(a) ? Extract.unwrap(a) : a;
|
|
4020
|
-
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.getPropertyName(a.property) === "current";
|
|
4021
|
-
};
|
|
4022
|
-
return checkSides(left, right) || checkSides(right, left);
|
|
4023
|
-
}
|
|
4024
|
-
function isInitializedFromRef(name, initialScope) {
|
|
4025
|
-
for (const { node } of findVariable(initialScope, name)?.defs ?? []) {
|
|
4026
|
-
if (node.type !== AST_NODE_TYPES.VariableDeclarator) continue;
|
|
4027
|
-
const init = node.init;
|
|
4028
|
-
if (init == null) continue;
|
|
4029
|
-
switch (true) {
|
|
4030
|
-
case init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier && (init.object.name === "ref" || init.object.name.endsWith("Ref")): return true;
|
|
4031
|
-
case init.type === AST_NODE_TYPES.CallExpression && core.isUseRefCall(context, init): return true;
|
|
4032
|
-
}
|
|
4033
|
-
}
|
|
4034
|
-
return false;
|
|
4035
|
-
}
|
|
4036
|
-
return merge(hCollector.visitor, cCollector.visitor, {
|
|
4054
|
+
return merge(hc.visitor, fc.visitor, {
|
|
4037
4055
|
JSXAttribute(node) {
|
|
4038
4056
|
switch (true) {
|
|
4039
4057
|
case node.name.type === AST_NODE_TYPES.JSXIdentifier && node.name.name === "ref" && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === AST_NODE_TYPES.Identifier:
|
|
@@ -4053,8 +4071,8 @@ function create$5(context) {
|
|
|
4053
4071
|
});
|
|
4054
4072
|
},
|
|
4055
4073
|
"Program:exit"(program) {
|
|
4056
|
-
const comps =
|
|
4057
|
-
const hooks =
|
|
4074
|
+
const comps = fc.api.getAllComponents(program);
|
|
4075
|
+
const hooks = hc.api.getAllHooks(program);
|
|
4058
4076
|
const funcs = new Set([...comps.map((c) => c.node), ...hooks.map((h) => h.node)]);
|
|
4059
4077
|
const isCompOrHookFn = (n) => Check.isFunction(n) && funcs.has(n);
|
|
4060
4078
|
for (const { isWrite, node } of refAccesses) {
|
|
@@ -4063,7 +4081,7 @@ function create$5(context) {
|
|
|
4063
4081
|
switch (true) {
|
|
4064
4082
|
case obj.name === "ref" || obj.name.endsWith("Ref"):
|
|
4065
4083
|
case jsxRefIdentifiers.has(obj.name):
|
|
4066
|
-
case isInitializedFromRef(obj.name, context.sourceCode.getScope(node.object)): break;
|
|
4084
|
+
case isInitializedFromRef$1(context, obj.name, context.sourceCode.getScope(node.object)): break;
|
|
4067
4085
|
default: continue;
|
|
4068
4086
|
}
|
|
4069
4087
|
const boundary = Traverse.findParent(node, isCompOrHookFn);
|
|
@@ -6346,6 +6364,29 @@ function getNestedIdentifiers(node) {
|
|
|
6346
6364
|
if (node.type === AST_NODE_TYPES.TSInstantiationExpression) identifiers.push(...getNestedIdentifiers(node.expression));
|
|
6347
6365
|
return identifiers;
|
|
6348
6366
|
}
|
|
6367
|
+
function isHookDecl(node) {
|
|
6368
|
+
if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
|
|
6369
|
+
if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
|
|
6370
|
+
const init = node.init;
|
|
6371
|
+
if (init == null || init.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
6372
|
+
switch (init.callee.type) {
|
|
6373
|
+
case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
|
|
6374
|
+
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
|
|
6375
|
+
default: return false;
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6378
|
+
function isInitializedFromRef(context, name, initialScope) {
|
|
6379
|
+
for (const { node } of findVariable(initialScope, name)?.defs ?? []) {
|
|
6380
|
+
if (node.type !== AST_NODE_TYPES.VariableDeclarator) continue;
|
|
6381
|
+
const init = node.init;
|
|
6382
|
+
if (init == null) continue;
|
|
6383
|
+
switch (true) {
|
|
6384
|
+
case init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier && (init.object.name === "ref" || init.object.name.endsWith("Ref")): return true;
|
|
6385
|
+
case init.type === AST_NODE_TYPES.CallExpression && core.isUseRefCall(context, init): return true;
|
|
6386
|
+
}
|
|
6387
|
+
}
|
|
6388
|
+
return false;
|
|
6389
|
+
}
|
|
6349
6390
|
|
|
6350
6391
|
//#endregion
|
|
6351
6392
|
//#region src/rules/set-state-in-effect/set-state-in-effect.ts
|
|
@@ -6437,29 +6478,6 @@ function create$4(context) {
|
|
|
6437
6478
|
default: return false;
|
|
6438
6479
|
}
|
|
6439
6480
|
}
|
|
6440
|
-
function isHookDecl(node) {
|
|
6441
|
-
if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
|
|
6442
|
-
if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
|
|
6443
|
-
const init = node.init;
|
|
6444
|
-
if (init == null || init.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
6445
|
-
switch (init.callee.type) {
|
|
6446
|
-
case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
|
|
6447
|
-
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
|
|
6448
|
-
default: return false;
|
|
6449
|
-
}
|
|
6450
|
-
}
|
|
6451
|
-
function isInitializedFromRef(name, initialScope) {
|
|
6452
|
-
for (const { node } of findVariable(initialScope, name)?.defs ?? []) {
|
|
6453
|
-
if (node.type !== AST_NODE_TYPES.VariableDeclarator) continue;
|
|
6454
|
-
const init = node.init;
|
|
6455
|
-
if (init == null) continue;
|
|
6456
|
-
switch (true) {
|
|
6457
|
-
case init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier && (init.object.name === "ref" || init.object.name.endsWith("Ref")): return true;
|
|
6458
|
-
case init.type === AST_NODE_TYPES.CallExpression && core.isUseRefCall(context, init): return true;
|
|
6459
|
-
}
|
|
6460
|
-
}
|
|
6461
|
-
return false;
|
|
6462
|
-
}
|
|
6463
6481
|
return merge({
|
|
6464
6482
|
":function"(node) {
|
|
6465
6483
|
const kind = getFunctionKind(node);
|
|
@@ -6489,7 +6507,7 @@ function create$4(context) {
|
|
|
6489
6507
|
function isArgumentUsingRefValue(context, node) {
|
|
6490
6508
|
const isUsingRefValue = (n) => {
|
|
6491
6509
|
switch (n.type) {
|
|
6492
|
-
case AST_NODE_TYPES.Identifier: return isInitializedFromRef(n.name, context.sourceCode.getScope(n));
|
|
6510
|
+
case AST_NODE_TYPES.Identifier: return isInitializedFromRef(context, n.name, context.sourceCode.getScope(n));
|
|
6493
6511
|
case AST_NODE_TYPES.MemberExpression: return isUsingRefValue(n.object);
|
|
6494
6512
|
case AST_NODE_TYPES.CallExpression: return isUsingRefValue(n.callee) || getNestedIdentifiers(n).some(isUsingRefValue);
|
|
6495
6513
|
default: return false;
|
|
@@ -6579,6 +6597,39 @@ function create$4(context) {
|
|
|
6579
6597
|
});
|
|
6580
6598
|
}
|
|
6581
6599
|
|
|
6600
|
+
//#endregion
|
|
6601
|
+
//#region src/rules/set-state-in-render/lib.ts
|
|
6602
|
+
function isInsideConditional(node, stopAt) {
|
|
6603
|
+
let current = node.parent;
|
|
6604
|
+
while (current != null && current !== stopAt) {
|
|
6605
|
+
switch (current.type) {
|
|
6606
|
+
case AST_NODE_TYPES.IfStatement:
|
|
6607
|
+
case AST_NODE_TYPES.ConditionalExpression:
|
|
6608
|
+
case AST_NODE_TYPES.LogicalExpression:
|
|
6609
|
+
case AST_NODE_TYPES.SwitchStatement:
|
|
6610
|
+
case AST_NODE_TYPES.SwitchCase: return true;
|
|
6611
|
+
default: break;
|
|
6612
|
+
}
|
|
6613
|
+
current = current.parent;
|
|
6614
|
+
}
|
|
6615
|
+
return false;
|
|
6616
|
+
}
|
|
6617
|
+
function isInsideEventHandler(node, stopAt) {
|
|
6618
|
+
let current = node.parent;
|
|
6619
|
+
while (current != null && current !== stopAt) {
|
|
6620
|
+
if (Check.isFunction(current) && current !== stopAt) return true;
|
|
6621
|
+
current = current.parent;
|
|
6622
|
+
}
|
|
6623
|
+
return false;
|
|
6624
|
+
}
|
|
6625
|
+
function isComponentOrHookLikeFunction(node) {
|
|
6626
|
+
const id = core.getFunctionId(node);
|
|
6627
|
+
if (id == null) return false;
|
|
6628
|
+
if (id.type === AST_NODE_TYPES.Identifier) return core.isFunctionComponentName(id.name) || core.isHookName(id.name);
|
|
6629
|
+
if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isFunctionComponentName(id.property.name) || core.isHookName(id.property.name);
|
|
6630
|
+
return false;
|
|
6631
|
+
}
|
|
6632
|
+
|
|
6582
6633
|
//#endregion
|
|
6583
6634
|
//#region src/rules/set-state-in-render/set-state-in-render.ts
|
|
6584
6635
|
const RULE_NAME$3 = "set-state-in-render";
|
|
@@ -6630,36 +6681,6 @@ function create$3(context) {
|
|
|
6630
6681
|
default: return false;
|
|
6631
6682
|
}
|
|
6632
6683
|
}
|
|
6633
|
-
function isInsideConditional(node, stopAt) {
|
|
6634
|
-
let current = node.parent;
|
|
6635
|
-
while (current != null && current !== stopAt) {
|
|
6636
|
-
switch (current.type) {
|
|
6637
|
-
case AST_NODE_TYPES.IfStatement:
|
|
6638
|
-
case AST_NODE_TYPES.ConditionalExpression:
|
|
6639
|
-
case AST_NODE_TYPES.LogicalExpression:
|
|
6640
|
-
case AST_NODE_TYPES.SwitchStatement:
|
|
6641
|
-
case AST_NODE_TYPES.SwitchCase: return true;
|
|
6642
|
-
default: break;
|
|
6643
|
-
}
|
|
6644
|
-
current = current.parent;
|
|
6645
|
-
}
|
|
6646
|
-
return false;
|
|
6647
|
-
}
|
|
6648
|
-
function isInsideEventHandler(node, stopAt) {
|
|
6649
|
-
let current = node.parent;
|
|
6650
|
-
while (current != null && current !== stopAt) {
|
|
6651
|
-
if (Check.isFunction(current) && current !== stopAt) return true;
|
|
6652
|
-
current = current.parent;
|
|
6653
|
-
}
|
|
6654
|
-
return false;
|
|
6655
|
-
}
|
|
6656
|
-
function isComponentOrHookLikeFunction(node) {
|
|
6657
|
-
const id = core.getFunctionId(node);
|
|
6658
|
-
if (id == null) return false;
|
|
6659
|
-
if (id.type === AST_NODE_TYPES.Identifier) return core.isFunctionComponentName(id.name) || core.isHookName(id.name);
|
|
6660
|
-
if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isFunctionComponentName(id.property.name) || core.isHookName(id.property.name);
|
|
6661
|
-
return false;
|
|
6662
|
-
}
|
|
6663
6684
|
function getFunctionKind(node) {
|
|
6664
6685
|
if (isComponentOrHookLikeFunction(node)) return "component";
|
|
6665
6686
|
const parent = Traverse.findParent(node, not(Check.isTypeExpression)) ?? node.parent;
|
|
@@ -6716,6 +6737,15 @@ function create$3(context) {
|
|
|
6716
6737
|
});
|
|
6717
6738
|
}
|
|
6718
6739
|
|
|
6740
|
+
//#endregion
|
|
6741
|
+
//#region src/rules/unsupported-syntax/lib.ts
|
|
6742
|
+
function isEvalCall(node) {
|
|
6743
|
+
return node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === "eval";
|
|
6744
|
+
}
|
|
6745
|
+
function isIifeCall(node) {
|
|
6746
|
+
return node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
|
|
6747
|
+
}
|
|
6748
|
+
|
|
6719
6749
|
//#endregion
|
|
6720
6750
|
//#region src/rules/unsupported-syntax/unsupported-syntax.ts
|
|
6721
6751
|
const RULE_NAME$2 = "unsupported-syntax";
|
|
@@ -6734,18 +6764,12 @@ var unsupported_syntax_default = createRule({
|
|
|
6734
6764
|
create: create$2,
|
|
6735
6765
|
defaultOptions: []
|
|
6736
6766
|
});
|
|
6737
|
-
function isEvalCall(node) {
|
|
6738
|
-
return node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === "eval";
|
|
6739
|
-
}
|
|
6740
|
-
function isIifeCall(node) {
|
|
6741
|
-
return node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
|
|
6742
|
-
}
|
|
6743
6767
|
function create$2(context) {
|
|
6744
|
-
const
|
|
6745
|
-
const
|
|
6768
|
+
const hc = core.getHookCollector(context);
|
|
6769
|
+
const fc = core.getFunctionComponentCollector(context);
|
|
6746
6770
|
const evalCalls = [];
|
|
6747
6771
|
const withStmts = [];
|
|
6748
|
-
return merge(
|
|
6772
|
+
return merge(hc.visitor, fc.visitor, {
|
|
6749
6773
|
CallExpression(node) {
|
|
6750
6774
|
if (!isEvalCall(node)) return;
|
|
6751
6775
|
const func = Traverse.findParent(node, Check.isFunction);
|
|
@@ -6768,8 +6792,8 @@ function create$2(context) {
|
|
|
6768
6792
|
});
|
|
6769
6793
|
},
|
|
6770
6794
|
"Program:exit"(node) {
|
|
6771
|
-
const components =
|
|
6772
|
-
const hooks =
|
|
6795
|
+
const components = fc.api.getAllComponents(node);
|
|
6796
|
+
const hooks = hc.api.getAllHooks(node);
|
|
6773
6797
|
const funcs = [...components, ...hooks];
|
|
6774
6798
|
for (const { func, node } of evalCalls) {
|
|
6775
6799
|
if (!funcs.some((f) => f.node === func)) continue;
|
|
@@ -6849,6 +6873,11 @@ function create$1(context) {
|
|
|
6849
6873
|
|
|
6850
6874
|
//#endregion
|
|
6851
6875
|
//#region src/rules/use-state/lib.ts
|
|
6876
|
+
const LAZY_INIT_ALLOW_LIST = [
|
|
6877
|
+
"Boolean",
|
|
6878
|
+
"String",
|
|
6879
|
+
"Number"
|
|
6880
|
+
];
|
|
6852
6881
|
/**
|
|
6853
6882
|
* Get all nested expressions of type T in an expression like node
|
|
6854
6883
|
* @param type The type of the expression to retrieve within the node
|
|
@@ -6968,11 +6997,6 @@ const schema = [{
|
|
|
6968
6997
|
}
|
|
6969
6998
|
}
|
|
6970
6999
|
}];
|
|
6971
|
-
const LAZY_INIT_ALLOW_LIST = [
|
|
6972
|
-
"Boolean",
|
|
6973
|
-
"String",
|
|
6974
|
-
"Number"
|
|
6975
|
-
];
|
|
6976
7000
|
var use_state_default = createRule({
|
|
6977
7001
|
meta: {
|
|
6978
7002
|
type: "suggestion",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0-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,24 +46,24 @@
|
|
|
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.
|
|
50
|
-
"@eslint-react/eslint": "5.
|
|
51
|
-
"@eslint-react/core": "5.
|
|
52
|
-
"@eslint-react/jsx": "5.
|
|
53
|
-
"@eslint-react/shared": "5.
|
|
54
|
-
"@eslint-react/var": "5.
|
|
49
|
+
"@eslint-react/ast": "5.3.0-beta.0",
|
|
50
|
+
"@eslint-react/eslint": "5.3.0-beta.0",
|
|
51
|
+
"@eslint-react/core": "5.3.0-beta.0",
|
|
52
|
+
"@eslint-react/jsx": "5.3.0-beta.0",
|
|
53
|
+
"@eslint-react/shared": "5.3.0-beta.0",
|
|
54
|
+
"@eslint-react/var": "5.3.0-beta.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/react": "^19.2.14",
|
|
58
58
|
"@types/react-dom": "^19.2.3",
|
|
59
|
-
"eslint": "^10.2.
|
|
59
|
+
"eslint": "^10.2.1",
|
|
60
60
|
"tsdown": "^0.21.9",
|
|
61
|
-
"tsl-dx": "^0.
|
|
61
|
+
"tsl-dx": "^0.11.0",
|
|
62
62
|
"@local/configs": "0.0.0",
|
|
63
63
|
"@local/eff": "3.0.0-beta.72"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"eslint": "^10.2.
|
|
66
|
+
"eslint": "^10.2.1",
|
|
67
67
|
"typescript": "*"
|
|
68
68
|
},
|
|
69
69
|
"engines": {
|