eslint-plugin-react-x 3.0.0-next.2 → 3.0.0-next.23
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 +935 -498
- package/package.json +12 -11
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { ESLintUtils } from "@typescript-eslint/utils";
|
|
|
5
5
|
import { P, isMatching, match } from "ts-pattern";
|
|
6
6
|
import ts from "typescript";
|
|
7
7
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
8
|
-
import { findEnclosingAssignmentTarget, findVariable, getChildScopes, getObjectType,
|
|
8
|
+
import { findEnclosingAssignmentTarget, findVariable, getChildScopes, getObjectType, getVariableInitializer, isAssignmentTargetEqual } from "@eslint-react/var";
|
|
9
9
|
import { DefinitionType } from "@typescript-eslint/scope-manager";
|
|
10
10
|
import { constFalse, constTrue, constVoid, flow, getOrElseUpdate, identity, not, unit } from "@eslint-react/eff";
|
|
11
11
|
import { compare } from "compare-versions";
|
|
@@ -13,6 +13,7 @@ import { getConstrainedTypeAtLocation, isTypeReadonly } from "@typescript-eslint
|
|
|
13
13
|
import { isPropertyReadonlyInType, unionConstituents } from "ts-api-utils";
|
|
14
14
|
import { getStaticValue, isIdentifier, isVariableDeclarator } from "@typescript-eslint/utils/ast-utils";
|
|
15
15
|
import { getTypeImmutability, isImmutable, isReadonlyDeep, isReadonlyShallow, isUnknown } from "is-immutable-type";
|
|
16
|
+
import { snakeCase } from "string-ts";
|
|
16
17
|
|
|
17
18
|
//#region \0rolldown/runtime.js
|
|
18
19
|
var __defProp = Object.defineProperty;
|
|
@@ -38,15 +39,18 @@ var disable_experimental_exports = /* @__PURE__ */ __exportAll({
|
|
|
38
39
|
});
|
|
39
40
|
const name$8 = "react-x/disable-experimental";
|
|
40
41
|
const rules$8 = {
|
|
42
|
+
"react-x/exhaustive-deps": "off",
|
|
41
43
|
"react-x/jsx-key-before-spread": "off",
|
|
42
|
-
"react-x/jsx-no-iife": "off",
|
|
43
44
|
"react-x/no-duplicate-key": "off",
|
|
44
45
|
"react-x/no-implicit-key": "off",
|
|
45
46
|
"react-x/no-misused-capture-owner-stack": "off",
|
|
46
47
|
"react-x/no-unnecessary-use-callback": "off",
|
|
47
48
|
"react-x/no-unnecessary-use-memo": "off",
|
|
48
49
|
"react-x/no-unused-props": "off",
|
|
49
|
-
"react-x/prefer-read-only-props": "off"
|
|
50
|
+
"react-x/prefer-read-only-props": "off",
|
|
51
|
+
"react-x/refs": "off",
|
|
52
|
+
"react-x/rules-of-hooks": "off",
|
|
53
|
+
"react-x/set-state-in-render": "off"
|
|
50
54
|
};
|
|
51
55
|
|
|
52
56
|
//#endregion
|
|
@@ -66,7 +70,7 @@ const rules$7 = {
|
|
|
66
70
|
//#endregion
|
|
67
71
|
//#region package.json
|
|
68
72
|
var name$6 = "eslint-plugin-react-x";
|
|
69
|
-
var version = "3.0.0-next.
|
|
73
|
+
var version = "3.0.0-next.23";
|
|
70
74
|
|
|
71
75
|
//#endregion
|
|
72
76
|
//#region src/utils/create-rule.ts
|
|
@@ -136,7 +140,6 @@ function getFullyQualifiedNameEx(checker, symbol) {
|
|
|
136
140
|
let name = symbol.name;
|
|
137
141
|
let parent = symbol.declarations?.at(0)?.parent;
|
|
138
142
|
if (parent == null) return checker.getFullyQualifiedName(symbol);
|
|
139
|
-
const namespace = parent.getSourceFile().statements.find((n) => ts.isNamespaceExportDeclaration(n));
|
|
140
143
|
while (parent.kind !== ts.SyntaxKind.SourceFile) {
|
|
141
144
|
switch (true) {
|
|
142
145
|
case ts.isInterfaceDeclaration(parent):
|
|
@@ -168,11 +171,14 @@ function getFullyQualifiedNameEx(checker, symbol) {
|
|
|
168
171
|
case ts.isObjectLiteralExpression(parent):
|
|
169
172
|
case ts.isIntersectionTypeNode(parent):
|
|
170
173
|
case ts.isUnionTypeNode(parent): break;
|
|
174
|
+
default: break;
|
|
171
175
|
}
|
|
172
176
|
parent = parent.parent;
|
|
173
177
|
}
|
|
174
|
-
|
|
175
|
-
return name;
|
|
178
|
+
const namespace = parent.getSourceFile().statements.find((n) => ts.isNamespaceExportDeclaration(n))?.name.text;
|
|
179
|
+
if (namespace == null) return name;
|
|
180
|
+
if (name.startsWith(`${namespace}.`)) return name;
|
|
181
|
+
return `${namespace}.${name}`;
|
|
176
182
|
}
|
|
177
183
|
|
|
178
184
|
//#endregion
|
|
@@ -221,7 +227,7 @@ function getTypeVariants(types) {
|
|
|
221
227
|
|
|
222
228
|
//#endregion
|
|
223
229
|
//#region src/rules/component-hook-factories.ts
|
|
224
|
-
const RULE_NAME$
|
|
230
|
+
const RULE_NAME$66 = "component-hook-factories";
|
|
225
231
|
var component_hook_factories_default = createRule({
|
|
226
232
|
meta: {
|
|
227
233
|
type: "problem",
|
|
@@ -232,11 +238,11 @@ var component_hook_factories_default = createRule({
|
|
|
232
238
|
},
|
|
233
239
|
schema: []
|
|
234
240
|
},
|
|
235
|
-
name: RULE_NAME$
|
|
236
|
-
create: create$
|
|
241
|
+
name: RULE_NAME$66,
|
|
242
|
+
create: create$66,
|
|
237
243
|
defaultOptions: []
|
|
238
244
|
});
|
|
239
|
-
function create$
|
|
245
|
+
function create$66(context) {
|
|
240
246
|
const hint = core.ComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.ComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.ComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.ComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.ComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.ComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.ComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
|
|
241
247
|
const fCollector = core.useComponentCollector(context, { hint });
|
|
242
248
|
const cCollector = core.useComponentCollectorLegacy(context);
|
|
@@ -280,7 +286,7 @@ function create$64(context) {
|
|
|
280
286
|
|
|
281
287
|
//#endregion
|
|
282
288
|
//#region src/rules/error-boundaries.ts
|
|
283
|
-
const RULE_NAME$
|
|
289
|
+
const RULE_NAME$65 = "error-boundaries";
|
|
284
290
|
var error_boundaries_default = createRule({
|
|
285
291
|
meta: {
|
|
286
292
|
type: "problem",
|
|
@@ -291,11 +297,11 @@ var error_boundaries_default = createRule({
|
|
|
291
297
|
},
|
|
292
298
|
schema: []
|
|
293
299
|
},
|
|
294
|
-
name: RULE_NAME$
|
|
295
|
-
create: create$
|
|
300
|
+
name: RULE_NAME$65,
|
|
301
|
+
create: create$65,
|
|
296
302
|
defaultOptions: []
|
|
297
303
|
});
|
|
298
|
-
function create$
|
|
304
|
+
function create$65(context) {
|
|
299
305
|
if (!context.sourceCode.text.includes("try")) return {};
|
|
300
306
|
const { ctx, visitor } = core.useComponentCollector(context);
|
|
301
307
|
const reported = /* @__PURE__ */ new Set();
|
|
@@ -329,7 +335,7 @@ function create$63(context) {
|
|
|
329
335
|
|
|
330
336
|
//#endregion
|
|
331
337
|
//#region src/rules/exhaustive-deps.ts
|
|
332
|
-
const RULE_NAME$
|
|
338
|
+
const RULE_NAME$64 = "exhaustive-deps";
|
|
333
339
|
/**
|
|
334
340
|
* Built-in hooks that accept dependency arrays.
|
|
335
341
|
* Maps hook name to the index of the callback argument.
|
|
@@ -469,6 +475,23 @@ function findComponentOrHookScope(node) {
|
|
|
469
475
|
return null;
|
|
470
476
|
}
|
|
471
477
|
/**
|
|
478
|
+
* Check if a variable's definition is contained within a given AST node.
|
|
479
|
+
* Used to exclude callback-local variables from the reactive deps list —
|
|
480
|
+
* a variable declared inside the effect/memo callback is a local, not a dep.
|
|
481
|
+
* @param variable - the variable to check
|
|
482
|
+
* @param node - the node that must NOT contain the variable's definition
|
|
483
|
+
*/
|
|
484
|
+
function isDefinedInsideNode(variable, node) {
|
|
485
|
+
for (const def of variable.defs) {
|
|
486
|
+
let current = def.name;
|
|
487
|
+
while (current.parent != null) {
|
|
488
|
+
current = current.parent;
|
|
489
|
+
if (current === node) return true;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
472
495
|
* Check if a variable is defined within the given function scope (reactive).
|
|
473
496
|
* @param variable - the variable to check
|
|
474
497
|
* @param scopeNode - the function scope to check against
|
|
@@ -508,11 +531,11 @@ var exhaustive_deps_default = createRule({
|
|
|
508
531
|
properties: { additionalHooks: { type: "string" } }
|
|
509
532
|
}]
|
|
510
533
|
},
|
|
511
|
-
name: RULE_NAME$
|
|
512
|
-
create: create$
|
|
534
|
+
name: RULE_NAME$64,
|
|
535
|
+
create: create$64,
|
|
513
536
|
defaultOptions: [{}]
|
|
514
537
|
});
|
|
515
|
-
function create$
|
|
538
|
+
function create$64(context) {
|
|
516
539
|
const additionalHooks = context.options[0]?.additionalHooks;
|
|
517
540
|
const additionalHooksRegex = additionalHooks != null && additionalHooks.length > 0 ? new RegExp(additionalHooks) : null;
|
|
518
541
|
/** Collected hook calls for later analysis. */
|
|
@@ -580,6 +603,7 @@ function create$62(context) {
|
|
|
580
603
|
if (variable == null) continue;
|
|
581
604
|
if (isStableVariable(variable)) continue;
|
|
582
605
|
if (!isDefinedInScope(variable, componentScope)) continue;
|
|
606
|
+
if (isDefinedInsideNode(variable, callbackNode)) continue;
|
|
583
607
|
reactiveDeps.add(memberExprText);
|
|
584
608
|
continue;
|
|
585
609
|
}
|
|
@@ -587,6 +611,7 @@ function create$62(context) {
|
|
|
587
611
|
if (variable == null) continue;
|
|
588
612
|
if (isStableVariable(variable)) continue;
|
|
589
613
|
if (!isDefinedInScope(variable, componentScope)) continue;
|
|
614
|
+
if (isDefinedInsideNode(variable, callbackNode)) continue;
|
|
590
615
|
reactiveDeps.add(identifier.name);
|
|
591
616
|
}
|
|
592
617
|
return reactiveDeps;
|
|
@@ -636,6 +661,32 @@ function create$62(context) {
|
|
|
636
661
|
return deps;
|
|
637
662
|
}
|
|
638
663
|
/**
|
|
664
|
+
* Check if a reactive dependency is covered by a declared dependency.
|
|
665
|
+
* A declared dep covers a reactive dep if they are equal, or if the
|
|
666
|
+
* declared dep is a prefix ancestor (e.g. `array` covers `array.map`,
|
|
667
|
+
* `obj` covers `obj.a?.toString`).
|
|
668
|
+
* @param reactiveDep
|
|
669
|
+
* @param declaredDeps
|
|
670
|
+
*/
|
|
671
|
+
function isCoveredByDeclaredDep(reactiveDep, declaredDeps) {
|
|
672
|
+
if (declaredDeps.has(reactiveDep)) return true;
|
|
673
|
+
for (const declared of declaredDeps) if (reactiveDep.startsWith(`${declared}.`) || reactiveDep.startsWith(`${declared}?.`)) return true;
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Check if a declared dependency covers at least one reactive dependency.
|
|
678
|
+
* A declared dep is considered necessary if it equals a reactive dep, or if
|
|
679
|
+
* it is a prefix ancestor of any reactive dep (e.g. `array` is necessary
|
|
680
|
+
* when `array.map` is reactive).
|
|
681
|
+
* @param declaredDep
|
|
682
|
+
* @param reactiveDeps
|
|
683
|
+
*/
|
|
684
|
+
function declaredDepCoversAny(declaredDep, reactiveDeps) {
|
|
685
|
+
if (reactiveDeps.has(declaredDep)) return true;
|
|
686
|
+
for (const reactive of reactiveDeps) if (reactive.startsWith(`${declaredDep}.`) || reactive.startsWith(`${declaredDep}?.`)) return true;
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
639
690
|
* Generate a fix that produces a corrected dependency array.
|
|
640
691
|
* Removes unnecessary deps, adds missing deps, and sorts all alphabetically.
|
|
641
692
|
* @param depsNode - the dependency array node
|
|
@@ -660,9 +711,9 @@ function create$62(context) {
|
|
|
660
711
|
const reactiveDeps = collectReactiveDeps(callback, componentScope);
|
|
661
712
|
const declaredDeps = getDeclaredDeps(depsNode);
|
|
662
713
|
const missingDeps = /* @__PURE__ */ new Set();
|
|
663
|
-
for (const dep of reactiveDeps) if (!
|
|
714
|
+
for (const dep of reactiveDeps) if (!isCoveredByDeclaredDep(dep, declaredDeps)) missingDeps.add(dep);
|
|
664
715
|
const unnecessaryDeps = /* @__PURE__ */ new Set();
|
|
665
|
-
for (const dep of declaredDeps) if (!
|
|
716
|
+
for (const dep of declaredDeps) if (!declaredDepCoversAny(dep, reactiveDeps)) unnecessaryDeps.add(dep);
|
|
666
717
|
const hasMissing = missingDeps.size > 0;
|
|
667
718
|
const hasUnnecessary = unnecessaryDeps.size > 0;
|
|
668
719
|
if (!hasMissing && !hasUnnecessary) return;
|
|
@@ -692,7 +743,7 @@ function create$62(context) {
|
|
|
692
743
|
});
|
|
693
744
|
}
|
|
694
745
|
}
|
|
695
|
-
return {
|
|
746
|
+
return defineRuleListener({
|
|
696
747
|
CallExpression(node) {
|
|
697
748
|
if (!isHookWithDeps(node)) return;
|
|
698
749
|
const hookName = getHookName$1(node);
|
|
@@ -719,12 +770,12 @@ function create$62(context) {
|
|
|
719
770
|
"Program:exit"() {
|
|
720
771
|
for (const hookCall of collectedHookCalls) analyzeHookCall(hookCall);
|
|
721
772
|
}
|
|
722
|
-
};
|
|
773
|
+
});
|
|
723
774
|
}
|
|
724
775
|
|
|
725
776
|
//#endregion
|
|
726
777
|
//#region src/rules/jsx-dollar.ts
|
|
727
|
-
const RULE_NAME$
|
|
778
|
+
const RULE_NAME$63 = "jsx-dollar";
|
|
728
779
|
var jsx_dollar_default = createRule({
|
|
729
780
|
meta: {
|
|
730
781
|
type: "problem",
|
|
@@ -737,11 +788,11 @@ var jsx_dollar_default = createRule({
|
|
|
737
788
|
},
|
|
738
789
|
schema: []
|
|
739
790
|
},
|
|
740
|
-
name: RULE_NAME$
|
|
741
|
-
create: create$
|
|
791
|
+
name: RULE_NAME$63,
|
|
792
|
+
create: create$63,
|
|
742
793
|
defaultOptions: []
|
|
743
794
|
});
|
|
744
|
-
function create$
|
|
795
|
+
function create$63(context) {
|
|
745
796
|
/**
|
|
746
797
|
* Visitor function for JSXElement and JSXFragment nodes
|
|
747
798
|
* @param node The JSXElement or JSXFragment node to be checked
|
|
@@ -774,15 +825,15 @@ function create$61(context) {
|
|
|
774
825
|
});
|
|
775
826
|
}
|
|
776
827
|
};
|
|
777
|
-
return {
|
|
828
|
+
return defineRuleListener({
|
|
778
829
|
JSXElement: visitorFunction,
|
|
779
830
|
JSXFragment: visitorFunction
|
|
780
|
-
};
|
|
831
|
+
});
|
|
781
832
|
}
|
|
782
833
|
|
|
783
834
|
//#endregion
|
|
784
835
|
//#region src/rules/jsx-key-before-spread.ts
|
|
785
|
-
const RULE_NAME$
|
|
836
|
+
const RULE_NAME$62 = "jsx-key-before-spread";
|
|
786
837
|
var jsx_key_before_spread_default = createRule({
|
|
787
838
|
meta: {
|
|
788
839
|
type: "problem",
|
|
@@ -790,17 +841,17 @@ var jsx_key_before_spread_default = createRule({
|
|
|
790
841
|
messages: { default: "The 'key' prop must be placed before any spread props when using the new JSX transform." },
|
|
791
842
|
schema: []
|
|
792
843
|
},
|
|
793
|
-
name: RULE_NAME$
|
|
794
|
-
create: create$
|
|
844
|
+
name: RULE_NAME$62,
|
|
845
|
+
create: create$62,
|
|
795
846
|
defaultOptions: []
|
|
796
847
|
});
|
|
797
|
-
function create$
|
|
848
|
+
function create$62(context) {
|
|
798
849
|
const { jsx } = {
|
|
799
850
|
...core.getJsxConfigFromContext(context),
|
|
800
851
|
...core.getJsxConfigFromAnnotation(context)
|
|
801
852
|
};
|
|
802
853
|
if (jsx !== core.JsxEmit.ReactJSX && jsx !== core.JsxEmit.ReactJSXDev) return {};
|
|
803
|
-
return { JSXOpeningElement(node) {
|
|
854
|
+
return defineRuleListener({ JSXOpeningElement(node) {
|
|
804
855
|
let firstSpreadPropIndex = null;
|
|
805
856
|
for (const [index, prop] of node.attributes.entries()) {
|
|
806
857
|
if (prop.type === AST_NODE_TYPES.JSXSpreadAttribute) {
|
|
@@ -813,12 +864,12 @@ function create$60(context) {
|
|
|
813
864
|
node: prop
|
|
814
865
|
});
|
|
815
866
|
}
|
|
816
|
-
} };
|
|
867
|
+
} });
|
|
817
868
|
}
|
|
818
869
|
|
|
819
870
|
//#endregion
|
|
820
871
|
//#region src/rules/jsx-no-comment-textnodes.ts
|
|
821
|
-
const RULE_NAME$
|
|
872
|
+
const RULE_NAME$61 = "jsx-no-comment-textnodes";
|
|
822
873
|
var jsx_no_comment_textnodes_default = createRule({
|
|
823
874
|
meta: {
|
|
824
875
|
type: "problem",
|
|
@@ -826,11 +877,11 @@ var jsx_no_comment_textnodes_default = createRule({
|
|
|
826
877
|
messages: { default: "Possible misused comment in text node. Comments inside children section of tag should be placed inside braces." },
|
|
827
878
|
schema: []
|
|
828
879
|
},
|
|
829
|
-
name: RULE_NAME$
|
|
830
|
-
create: create$
|
|
880
|
+
name: RULE_NAME$61,
|
|
881
|
+
create: create$61,
|
|
831
882
|
defaultOptions: []
|
|
832
883
|
});
|
|
833
|
-
function create$
|
|
884
|
+
function create$61(context) {
|
|
834
885
|
function hasCommentLike(node) {
|
|
835
886
|
if (ast.isOneOf([AST_NODE_TYPES.JSXAttribute, AST_NODE_TYPES.JSXExpressionContainer])(node.parent)) return false;
|
|
836
887
|
return /^\s*\/(?:\/|\*)/mu.test(context.sourceCode.getText(node));
|
|
@@ -843,15 +894,15 @@ function create$59(context) {
|
|
|
843
894
|
node
|
|
844
895
|
});
|
|
845
896
|
};
|
|
846
|
-
return {
|
|
897
|
+
return defineRuleListener({
|
|
847
898
|
JSXText: visitorFunction,
|
|
848
899
|
Literal: visitorFunction
|
|
849
|
-
};
|
|
900
|
+
});
|
|
850
901
|
}
|
|
851
902
|
|
|
852
903
|
//#endregion
|
|
853
904
|
//#region src/rules/jsx-no-duplicate-props.ts
|
|
854
|
-
const RULE_NAME$
|
|
905
|
+
const RULE_NAME$60 = "jsx-no-duplicate-props";
|
|
855
906
|
var jsx_no_duplicate_props_default = createRule({
|
|
856
907
|
meta: {
|
|
857
908
|
type: "problem",
|
|
@@ -859,12 +910,12 @@ var jsx_no_duplicate_props_default = createRule({
|
|
|
859
910
|
messages: { default: "This JSX property is assigned multiple times." },
|
|
860
911
|
schema: []
|
|
861
912
|
},
|
|
862
|
-
name: RULE_NAME$
|
|
863
|
-
create: create$
|
|
913
|
+
name: RULE_NAME$60,
|
|
914
|
+
create: create$60,
|
|
864
915
|
defaultOptions: []
|
|
865
916
|
});
|
|
866
|
-
function create$
|
|
867
|
-
return { JSXOpeningElement(node) {
|
|
917
|
+
function create$60(context) {
|
|
918
|
+
return defineRuleListener({ JSXOpeningElement(node) {
|
|
868
919
|
const props = [];
|
|
869
920
|
for (const attr of node.attributes) {
|
|
870
921
|
if (attr.type === AST_NODE_TYPES.JSXSpreadAttribute) continue;
|
|
@@ -879,43 +930,12 @@ function create$58(context) {
|
|
|
879
930
|
node: attr
|
|
880
931
|
});
|
|
881
932
|
}
|
|
882
|
-
} };
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
//#endregion
|
|
886
|
-
//#region src/rules/jsx-no-iife.ts
|
|
887
|
-
const RULE_NAME$57 = "jsx-no-iife";
|
|
888
|
-
var jsx_no_iife_default = createRule({
|
|
889
|
-
meta: {
|
|
890
|
-
type: "problem",
|
|
891
|
-
docs: { description: "Disallows immediately-invoked function expressions in JSX." },
|
|
892
|
-
messages: { default: "Avoid using immediately-invoked function expressions in JSX." },
|
|
893
|
-
schema: []
|
|
894
|
-
},
|
|
895
|
-
name: RULE_NAME$57,
|
|
896
|
-
create: create$57,
|
|
897
|
-
defaultOptions: []
|
|
898
|
-
});
|
|
899
|
-
function create$57(context) {
|
|
900
|
-
return {
|
|
901
|
-
"JSXElement :function"(node) {
|
|
902
|
-
if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) context.report({
|
|
903
|
-
messageId: "default",
|
|
904
|
-
node: node.parent
|
|
905
|
-
});
|
|
906
|
-
},
|
|
907
|
-
"JSXFragment :function"(node) {
|
|
908
|
-
if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) context.report({
|
|
909
|
-
messageId: "default",
|
|
910
|
-
node: node.parent
|
|
911
|
-
});
|
|
912
|
-
}
|
|
913
|
-
};
|
|
933
|
+
} });
|
|
914
934
|
}
|
|
915
935
|
|
|
916
936
|
//#endregion
|
|
917
937
|
//#region src/rules/jsx-no-undef.ts
|
|
918
|
-
const RULE_NAME$
|
|
938
|
+
const RULE_NAME$59 = "jsx-no-undef";
|
|
919
939
|
var jsx_no_undef_default = createRule({
|
|
920
940
|
meta: {
|
|
921
941
|
type: "problem",
|
|
@@ -923,12 +943,12 @@ var jsx_no_undef_default = createRule({
|
|
|
923
943
|
messages: { default: "JSX variable '{{name}}' is not defined." },
|
|
924
944
|
schema: []
|
|
925
945
|
},
|
|
926
|
-
name: RULE_NAME$
|
|
927
|
-
create: create$
|
|
946
|
+
name: RULE_NAME$59,
|
|
947
|
+
create: create$59,
|
|
928
948
|
defaultOptions: []
|
|
929
949
|
});
|
|
930
|
-
function create$
|
|
931
|
-
return { JSXOpeningElement(node) {
|
|
950
|
+
function create$59(context) {
|
|
951
|
+
return defineRuleListener({ JSXOpeningElement(node) {
|
|
932
952
|
const name = match(node.name).with({ type: AST_NODE_TYPES.JSXIdentifier }, (n) => n.name).with({
|
|
933
953
|
type: AST_NODE_TYPES.JSXMemberExpression,
|
|
934
954
|
object: { type: AST_NODE_TYPES.JSXIdentifier }
|
|
@@ -941,14 +961,14 @@ function create$56(context) {
|
|
|
941
961
|
node,
|
|
942
962
|
data: { name }
|
|
943
963
|
});
|
|
944
|
-
} };
|
|
964
|
+
} });
|
|
945
965
|
}
|
|
946
966
|
|
|
947
967
|
//#endregion
|
|
948
968
|
//#region src/rules/jsx-shorthand-boolean.ts
|
|
949
|
-
const RULE_NAME$
|
|
950
|
-
const defaultOptions$
|
|
951
|
-
const schema$
|
|
969
|
+
const RULE_NAME$58 = "jsx-shorthand-boolean";
|
|
970
|
+
const defaultOptions$4 = [1];
|
|
971
|
+
const schema$4 = [{
|
|
952
972
|
type: "integer",
|
|
953
973
|
enum: [-1, 1]
|
|
954
974
|
}];
|
|
@@ -958,15 +978,15 @@ var jsx_shorthand_boolean_default = createRule({
|
|
|
958
978
|
docs: { description: "Enforces shorthand syntax for boolean props." },
|
|
959
979
|
fixable: "code",
|
|
960
980
|
messages: { default: "{{message}}" },
|
|
961
|
-
schema: schema$
|
|
981
|
+
schema: schema$4
|
|
962
982
|
},
|
|
963
|
-
name: RULE_NAME$
|
|
964
|
-
create: create$
|
|
965
|
-
defaultOptions: defaultOptions$
|
|
983
|
+
name: RULE_NAME$58,
|
|
984
|
+
create: create$58,
|
|
985
|
+
defaultOptions: defaultOptions$4
|
|
966
986
|
});
|
|
967
|
-
function create$
|
|
968
|
-
const policy = context.options[0] ?? defaultOptions$
|
|
969
|
-
return { JSXAttribute(node) {
|
|
987
|
+
function create$58(context) {
|
|
988
|
+
const policy = context.options[0] ?? defaultOptions$4[0];
|
|
989
|
+
return defineRuleListener({ JSXAttribute(node) {
|
|
970
990
|
const { value } = node;
|
|
971
991
|
const propName = core.getJsxAttributeName(context, node);
|
|
972
992
|
switch (true) {
|
|
@@ -978,7 +998,7 @@ function create$55(context) {
|
|
|
978
998
|
fix: (fixer) => fixer.removeRange([node.name.range[1], value.range[1]])
|
|
979
999
|
});
|
|
980
1000
|
break;
|
|
981
|
-
case policy === -1 && value
|
|
1001
|
+
case policy === -1 && value == null:
|
|
982
1002
|
context.report({
|
|
983
1003
|
messageId: "default",
|
|
984
1004
|
node: node.value ?? node,
|
|
@@ -987,14 +1007,14 @@ function create$55(context) {
|
|
|
987
1007
|
});
|
|
988
1008
|
break;
|
|
989
1009
|
}
|
|
990
|
-
} };
|
|
1010
|
+
} });
|
|
991
1011
|
}
|
|
992
1012
|
|
|
993
1013
|
//#endregion
|
|
994
1014
|
//#region src/rules/jsx-shorthand-fragment.ts
|
|
995
|
-
const RULE_NAME$
|
|
996
|
-
const defaultOptions$
|
|
997
|
-
const schema$
|
|
1015
|
+
const RULE_NAME$57 = "jsx-shorthand-fragment";
|
|
1016
|
+
const defaultOptions$3 = [1];
|
|
1017
|
+
const schema$3 = [{
|
|
998
1018
|
type: "integer",
|
|
999
1019
|
enum: [-1, 1]
|
|
1000
1020
|
}];
|
|
@@ -1004,20 +1024,20 @@ var jsx_shorthand_fragment_default = createRule({
|
|
|
1004
1024
|
docs: { description: "Enforces shorthand syntax for fragment elements." },
|
|
1005
1025
|
fixable: "code",
|
|
1006
1026
|
messages: { default: "{{message}}" },
|
|
1007
|
-
schema: schema$
|
|
1027
|
+
schema: schema$3
|
|
1008
1028
|
},
|
|
1009
|
-
name: RULE_NAME$
|
|
1010
|
-
create: create$
|
|
1011
|
-
defaultOptions: defaultOptions$
|
|
1029
|
+
name: RULE_NAME$57,
|
|
1030
|
+
create: create$57,
|
|
1031
|
+
defaultOptions: defaultOptions$3
|
|
1012
1032
|
});
|
|
1013
|
-
function create$
|
|
1014
|
-
const policy = context.options[0] ?? defaultOptions$
|
|
1033
|
+
function create$57(context) {
|
|
1034
|
+
const policy = context.options[0] ?? defaultOptions$3[0];
|
|
1015
1035
|
const jsxConfig = {
|
|
1016
1036
|
...core.getJsxConfigFromContext(context),
|
|
1017
1037
|
...core.getJsxConfigFromAnnotation(context)
|
|
1018
1038
|
};
|
|
1019
1039
|
const { jsxFragmentFactory } = jsxConfig;
|
|
1020
|
-
return match(policy).with(1, () => ({ JSXElement(node) {
|
|
1040
|
+
return match(policy).with(1, () => defineRuleListener({ JSXElement(node) {
|
|
1021
1041
|
if (!core.isJsxFragmentElement(context, node, jsxConfig)) return;
|
|
1022
1042
|
if (node.openingElement.attributes.length > 0) return;
|
|
1023
1043
|
context.report({
|
|
@@ -1030,7 +1050,7 @@ function create$54(context) {
|
|
|
1030
1050
|
return [fixer.replaceTextRange([openingElement.range[0], openingElement.range[1]], "<>"), fixer.replaceTextRange([closingElement.range[0], closingElement.range[1]], "</>")];
|
|
1031
1051
|
}
|
|
1032
1052
|
});
|
|
1033
|
-
} })).with(-1, () => ({ JSXFragment(node) {
|
|
1053
|
+
} })).with(-1, () => defineRuleListener({ JSXFragment(node) {
|
|
1034
1054
|
context.report({
|
|
1035
1055
|
messageId: "default",
|
|
1036
1056
|
node,
|
|
@@ -1045,7 +1065,7 @@ function create$54(context) {
|
|
|
1045
1065
|
|
|
1046
1066
|
//#endregion
|
|
1047
1067
|
//#region src/rules/jsx-uses-react.ts
|
|
1048
|
-
const RULE_NAME$
|
|
1068
|
+
const RULE_NAME$56 = "jsx-uses-react";
|
|
1049
1069
|
var jsx_uses_react_default = createRule({
|
|
1050
1070
|
meta: {
|
|
1051
1071
|
type: "problem",
|
|
@@ -1053,11 +1073,11 @@ var jsx_uses_react_default = createRule({
|
|
|
1053
1073
|
messages: { default: "Marked {{name}} as used." },
|
|
1054
1074
|
schema: []
|
|
1055
1075
|
},
|
|
1056
|
-
name: RULE_NAME$
|
|
1057
|
-
create: create$
|
|
1076
|
+
name: RULE_NAME$56,
|
|
1077
|
+
create: create$56,
|
|
1058
1078
|
defaultOptions: []
|
|
1059
1079
|
});
|
|
1060
|
-
function create$
|
|
1080
|
+
function create$56(context) {
|
|
1061
1081
|
const { jsx, jsxFactory, jsxFragmentFactory } = {
|
|
1062
1082
|
...core.getJsxConfigFromContext(context),
|
|
1063
1083
|
...core.getJsxConfigFromAnnotation(context)
|
|
@@ -1071,11 +1091,11 @@ function create$53(context) {
|
|
|
1071
1091
|
context.sourceCode.markVariableAsUsed(jsxFragmentFactory, node);
|
|
1072
1092
|
debugReport(context, node, jsxFragmentFactory);
|
|
1073
1093
|
}
|
|
1074
|
-
return {
|
|
1094
|
+
return defineRuleListener({
|
|
1075
1095
|
JSXFragment: handleJsxFragment,
|
|
1076
1096
|
JSXOpeningElement: handleJsxElement,
|
|
1077
1097
|
JSXOpeningFragment: handleJsxElement
|
|
1078
|
-
};
|
|
1098
|
+
});
|
|
1079
1099
|
}
|
|
1080
1100
|
function debugReport(context, node, name) {
|
|
1081
1101
|
if (process.env["ESLINT_REACT_DEBUG"] !== "1") return;
|
|
@@ -1088,7 +1108,7 @@ function debugReport(context, node, name) {
|
|
|
1088
1108
|
|
|
1089
1109
|
//#endregion
|
|
1090
1110
|
//#region src/rules/jsx-uses-vars.ts
|
|
1091
|
-
const RULE_NAME$
|
|
1111
|
+
const RULE_NAME$55 = "jsx-uses-vars";
|
|
1092
1112
|
var jsx_uses_vars_default = createRule({
|
|
1093
1113
|
meta: {
|
|
1094
1114
|
type: "problem",
|
|
@@ -1096,12 +1116,12 @@ var jsx_uses_vars_default = createRule({
|
|
|
1096
1116
|
messages: { default: "An identifier in JSX is marked as used." },
|
|
1097
1117
|
schema: []
|
|
1098
1118
|
},
|
|
1099
|
-
name: RULE_NAME$
|
|
1100
|
-
create: create$
|
|
1119
|
+
name: RULE_NAME$55,
|
|
1120
|
+
create: create$55,
|
|
1101
1121
|
defaultOptions: []
|
|
1102
1122
|
});
|
|
1103
|
-
function create$
|
|
1104
|
-
return { JSXOpeningElement(node) {
|
|
1123
|
+
function create$55(context) {
|
|
1124
|
+
return defineRuleListener({ JSXOpeningElement(node) {
|
|
1105
1125
|
switch (node.name.type) {
|
|
1106
1126
|
case AST_NODE_TYPES.JSXIdentifier:
|
|
1107
1127
|
if (/^[a-z]/u.test(node.name.name)) return;
|
|
@@ -1113,12 +1133,12 @@ function create$52(context) {
|
|
|
1113
1133
|
break;
|
|
1114
1134
|
}
|
|
1115
1135
|
}
|
|
1116
|
-
} };
|
|
1136
|
+
} });
|
|
1117
1137
|
}
|
|
1118
1138
|
|
|
1119
1139
|
//#endregion
|
|
1120
1140
|
//#region src/rules/no-access-state-in-setstate.ts
|
|
1121
|
-
const RULE_NAME$
|
|
1141
|
+
const RULE_NAME$54 = "no-access-state-in-setstate";
|
|
1122
1142
|
function isKeyLiteral$2(node, key) {
|
|
1123
1143
|
return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
|
|
1124
1144
|
type: AST_NODE_TYPES.TemplateLiteral,
|
|
@@ -1132,16 +1152,16 @@ var no_access_state_in_setstate_default = createRule({
|
|
|
1132
1152
|
messages: { default: "Do not access 'this.state' within 'setState'. Use the update function instead." },
|
|
1133
1153
|
schema: []
|
|
1134
1154
|
},
|
|
1135
|
-
name: RULE_NAME$
|
|
1136
|
-
create: create$
|
|
1155
|
+
name: RULE_NAME$54,
|
|
1156
|
+
create: create$54,
|
|
1137
1157
|
defaultOptions: []
|
|
1138
1158
|
});
|
|
1139
|
-
function create$
|
|
1159
|
+
function create$54(context) {
|
|
1140
1160
|
if (!context.sourceCode.text.includes("setState")) return {};
|
|
1141
1161
|
const classStack = [];
|
|
1142
1162
|
const methodStack = [];
|
|
1143
1163
|
const setStateStack = [];
|
|
1144
|
-
return {
|
|
1164
|
+
return defineRuleListener({
|
|
1145
1165
|
CallExpression(node) {
|
|
1146
1166
|
if (!core.isThisSetState(node)) return;
|
|
1147
1167
|
setStateStack.push([node, false]);
|
|
@@ -1202,12 +1222,12 @@ function create$51(context) {
|
|
|
1202
1222
|
node
|
|
1203
1223
|
});
|
|
1204
1224
|
}
|
|
1205
|
-
};
|
|
1225
|
+
});
|
|
1206
1226
|
}
|
|
1207
1227
|
|
|
1208
1228
|
//#endregion
|
|
1209
1229
|
//#region src/rules/no-array-index-key.ts
|
|
1210
|
-
const RULE_NAME$
|
|
1230
|
+
const RULE_NAME$53 = "no-array-index-key";
|
|
1211
1231
|
const REACT_CHILDREN_METHOD = ["forEach", "map"];
|
|
1212
1232
|
function getIndexParamPosition(methodName) {
|
|
1213
1233
|
switch (methodName) {
|
|
@@ -1266,11 +1286,11 @@ var no_array_index_key_default = createRule({
|
|
|
1266
1286
|
messages: { default: "Do not use item index in the array as its key." },
|
|
1267
1287
|
schema: []
|
|
1268
1288
|
},
|
|
1269
|
-
name: RULE_NAME$
|
|
1270
|
-
create: create$
|
|
1289
|
+
name: RULE_NAME$53,
|
|
1290
|
+
create: create$53,
|
|
1271
1291
|
defaultOptions: []
|
|
1272
1292
|
});
|
|
1273
|
-
function create$
|
|
1293
|
+
function create$53(context) {
|
|
1274
1294
|
const indexParamNames = [];
|
|
1275
1295
|
function isArrayIndex(node) {
|
|
1276
1296
|
return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name) => name != null && name === node.name);
|
|
@@ -1309,7 +1329,7 @@ function create$50(context) {
|
|
|
1309
1329
|
}
|
|
1310
1330
|
return [];
|
|
1311
1331
|
}
|
|
1312
|
-
return {
|
|
1332
|
+
return defineRuleListener({
|
|
1313
1333
|
CallExpression(node) {
|
|
1314
1334
|
indexParamNames.push(getMapIndexParamName(context, node));
|
|
1315
1335
|
if (node.arguments.length === 0) return;
|
|
@@ -1331,12 +1351,12 @@ function create$50(context) {
|
|
|
1331
1351
|
if (node.value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
|
|
1332
1352
|
for (const descriptor of getReportDescriptors(node.value.expression)) report(context)(descriptor);
|
|
1333
1353
|
}
|
|
1334
|
-
};
|
|
1354
|
+
});
|
|
1335
1355
|
}
|
|
1336
1356
|
|
|
1337
1357
|
//#endregion
|
|
1338
1358
|
//#region src/rules/no-children-count.ts
|
|
1339
|
-
const RULE_NAME$
|
|
1359
|
+
const RULE_NAME$52 = "no-children-count";
|
|
1340
1360
|
var no_children_count_default = createRule({
|
|
1341
1361
|
meta: {
|
|
1342
1362
|
type: "problem",
|
|
@@ -1344,22 +1364,22 @@ var no_children_count_default = createRule({
|
|
|
1344
1364
|
messages: { default: "Using 'Children.count' is uncommon and can lead to fragile code. Use alternatives instead." },
|
|
1345
1365
|
schema: []
|
|
1346
1366
|
},
|
|
1347
|
-
name: RULE_NAME$
|
|
1348
|
-
create: create$
|
|
1367
|
+
name: RULE_NAME$52,
|
|
1368
|
+
create: create$52,
|
|
1349
1369
|
defaultOptions: []
|
|
1350
1370
|
});
|
|
1351
|
-
function create$
|
|
1352
|
-
return { MemberExpression(node) {
|
|
1371
|
+
function create$52(context) {
|
|
1372
|
+
return defineRuleListener({ MemberExpression(node) {
|
|
1353
1373
|
if (core.isChildrenCount(context, node)) context.report({
|
|
1354
1374
|
messageId: "default",
|
|
1355
1375
|
node: node.property
|
|
1356
1376
|
});
|
|
1357
|
-
} };
|
|
1377
|
+
} });
|
|
1358
1378
|
}
|
|
1359
1379
|
|
|
1360
1380
|
//#endregion
|
|
1361
1381
|
//#region src/rules/no-children-for-each.ts
|
|
1362
|
-
const RULE_NAME$
|
|
1382
|
+
const RULE_NAME$51 = "no-children-for-each";
|
|
1363
1383
|
var no_children_for_each_default = createRule({
|
|
1364
1384
|
meta: {
|
|
1365
1385
|
type: "problem",
|
|
@@ -1367,22 +1387,22 @@ var no_children_for_each_default = createRule({
|
|
|
1367
1387
|
messages: { default: "Using 'Children.forEach' is uncommon and can lead to fragile code. Use alternatives instead." },
|
|
1368
1388
|
schema: []
|
|
1369
1389
|
},
|
|
1370
|
-
name: RULE_NAME$
|
|
1371
|
-
create: create$
|
|
1390
|
+
name: RULE_NAME$51,
|
|
1391
|
+
create: create$51,
|
|
1372
1392
|
defaultOptions: []
|
|
1373
1393
|
});
|
|
1374
|
-
function create$
|
|
1375
|
-
return { MemberExpression(node) {
|
|
1394
|
+
function create$51(context) {
|
|
1395
|
+
return defineRuleListener({ MemberExpression(node) {
|
|
1376
1396
|
if (core.isChildrenForEach(context, node)) context.report({
|
|
1377
1397
|
messageId: "default",
|
|
1378
1398
|
node: node.property
|
|
1379
1399
|
});
|
|
1380
|
-
} };
|
|
1400
|
+
} });
|
|
1381
1401
|
}
|
|
1382
1402
|
|
|
1383
1403
|
//#endregion
|
|
1384
1404
|
//#region src/rules/no-children-map.ts
|
|
1385
|
-
const RULE_NAME$
|
|
1405
|
+
const RULE_NAME$50 = "no-children-map";
|
|
1386
1406
|
var no_children_map_default = createRule({
|
|
1387
1407
|
meta: {
|
|
1388
1408
|
type: "problem",
|
|
@@ -1390,22 +1410,22 @@ var no_children_map_default = createRule({
|
|
|
1390
1410
|
messages: { default: "Using 'Children.map' is uncommon and can lead to fragile code. Use alternatives instead." },
|
|
1391
1411
|
schema: []
|
|
1392
1412
|
},
|
|
1393
|
-
name: RULE_NAME$
|
|
1394
|
-
create: create$
|
|
1413
|
+
name: RULE_NAME$50,
|
|
1414
|
+
create: create$50,
|
|
1395
1415
|
defaultOptions: []
|
|
1396
1416
|
});
|
|
1397
|
-
function create$
|
|
1398
|
-
return { MemberExpression(node) {
|
|
1417
|
+
function create$50(context) {
|
|
1418
|
+
return defineRuleListener({ MemberExpression(node) {
|
|
1399
1419
|
if (core.isChildrenMap(context, node)) context.report({
|
|
1400
1420
|
messageId: "default",
|
|
1401
1421
|
node: node.property
|
|
1402
1422
|
});
|
|
1403
|
-
} };
|
|
1423
|
+
} });
|
|
1404
1424
|
}
|
|
1405
1425
|
|
|
1406
1426
|
//#endregion
|
|
1407
1427
|
//#region src/rules/no-children-only.ts
|
|
1408
|
-
const RULE_NAME$
|
|
1428
|
+
const RULE_NAME$49 = "no-children-only";
|
|
1409
1429
|
var no_children_only_default = createRule({
|
|
1410
1430
|
meta: {
|
|
1411
1431
|
type: "problem",
|
|
@@ -1413,22 +1433,22 @@ var no_children_only_default = createRule({
|
|
|
1413
1433
|
messages: { default: "Using 'Children.only' is uncommon and can lead to fragile code. Use alternatives instead." },
|
|
1414
1434
|
schema: []
|
|
1415
1435
|
},
|
|
1416
|
-
name: RULE_NAME$
|
|
1417
|
-
create: create$
|
|
1436
|
+
name: RULE_NAME$49,
|
|
1437
|
+
create: create$49,
|
|
1418
1438
|
defaultOptions: []
|
|
1419
1439
|
});
|
|
1420
|
-
function create$
|
|
1421
|
-
return { MemberExpression(node) {
|
|
1440
|
+
function create$49(context) {
|
|
1441
|
+
return defineRuleListener({ MemberExpression(node) {
|
|
1422
1442
|
if (core.isChildrenOnly(context, node)) context.report({
|
|
1423
1443
|
messageId: "default",
|
|
1424
1444
|
node: node.property
|
|
1425
1445
|
});
|
|
1426
|
-
} };
|
|
1446
|
+
} });
|
|
1427
1447
|
}
|
|
1428
1448
|
|
|
1429
1449
|
//#endregion
|
|
1430
1450
|
//#region src/rules/no-children-prop.ts
|
|
1431
|
-
const RULE_NAME$
|
|
1451
|
+
const RULE_NAME$48 = "no-children-prop";
|
|
1432
1452
|
var no_children_prop_default = createRule({
|
|
1433
1453
|
meta: {
|
|
1434
1454
|
type: "problem",
|
|
@@ -1436,23 +1456,23 @@ var no_children_prop_default = createRule({
|
|
|
1436
1456
|
messages: { default: "Do not pass 'children' as props." },
|
|
1437
1457
|
schema: []
|
|
1438
1458
|
},
|
|
1439
|
-
name: RULE_NAME$
|
|
1440
|
-
create: create$
|
|
1459
|
+
name: RULE_NAME$48,
|
|
1460
|
+
create: create$48,
|
|
1441
1461
|
defaultOptions: []
|
|
1442
1462
|
});
|
|
1443
|
-
function create$
|
|
1444
|
-
return { JSXElement(node) {
|
|
1463
|
+
function create$48(context) {
|
|
1464
|
+
return defineRuleListener({ JSXElement(node) {
|
|
1445
1465
|
const childrenProp = core.getJsxAttribute(context, node)("children");
|
|
1446
1466
|
if (childrenProp != null) context.report({
|
|
1447
1467
|
messageId: "default",
|
|
1448
1468
|
node: childrenProp
|
|
1449
1469
|
});
|
|
1450
|
-
} };
|
|
1470
|
+
} });
|
|
1451
1471
|
}
|
|
1452
1472
|
|
|
1453
1473
|
//#endregion
|
|
1454
1474
|
//#region src/rules/no-children-to-array.ts
|
|
1455
|
-
const RULE_NAME$
|
|
1475
|
+
const RULE_NAME$47 = "no-children-to-array";
|
|
1456
1476
|
var no_children_to_array_default = createRule({
|
|
1457
1477
|
meta: {
|
|
1458
1478
|
type: "problem",
|
|
@@ -1460,22 +1480,22 @@ var no_children_to_array_default = createRule({
|
|
|
1460
1480
|
messages: { default: "Using 'Children.toArray' is uncommon and can lead to fragile code. Use alternatives instead." },
|
|
1461
1481
|
schema: []
|
|
1462
1482
|
},
|
|
1463
|
-
name: RULE_NAME$
|
|
1464
|
-
create: create$
|
|
1483
|
+
name: RULE_NAME$47,
|
|
1484
|
+
create: create$47,
|
|
1465
1485
|
defaultOptions: []
|
|
1466
1486
|
});
|
|
1467
|
-
function create$
|
|
1468
|
-
return { MemberExpression(node) {
|
|
1487
|
+
function create$47(context) {
|
|
1488
|
+
return defineRuleListener({ MemberExpression(node) {
|
|
1469
1489
|
if (core.isChildrenToArray(context, node)) context.report({
|
|
1470
1490
|
messageId: "default",
|
|
1471
1491
|
node: node.property
|
|
1472
1492
|
});
|
|
1473
|
-
} };
|
|
1493
|
+
} });
|
|
1474
1494
|
}
|
|
1475
1495
|
|
|
1476
1496
|
//#endregion
|
|
1477
1497
|
//#region src/rules/no-class-component.ts
|
|
1478
|
-
const RULE_NAME$
|
|
1498
|
+
const RULE_NAME$46 = "no-class-component";
|
|
1479
1499
|
var no_class_component_default = createRule({
|
|
1480
1500
|
meta: {
|
|
1481
1501
|
type: "problem",
|
|
@@ -1483,11 +1503,11 @@ var no_class_component_default = createRule({
|
|
|
1483
1503
|
messages: { default: "Avoid using class components. Use function components instead." },
|
|
1484
1504
|
schema: []
|
|
1485
1505
|
},
|
|
1486
|
-
name: RULE_NAME$
|
|
1487
|
-
create: create$
|
|
1506
|
+
name: RULE_NAME$46,
|
|
1507
|
+
create: create$46,
|
|
1488
1508
|
defaultOptions: []
|
|
1489
1509
|
});
|
|
1490
|
-
function create$
|
|
1510
|
+
function create$46(context) {
|
|
1491
1511
|
if (!context.sourceCode.text.includes("Component")) return {};
|
|
1492
1512
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1493
1513
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -1504,7 +1524,7 @@ function create$43(context) {
|
|
|
1504
1524
|
|
|
1505
1525
|
//#endregion
|
|
1506
1526
|
//#region src/rules/no-clone-element.ts
|
|
1507
|
-
const RULE_NAME$
|
|
1527
|
+
const RULE_NAME$45 = "no-clone-element";
|
|
1508
1528
|
var no_clone_element_default = createRule({
|
|
1509
1529
|
meta: {
|
|
1510
1530
|
type: "problem",
|
|
@@ -1512,22 +1532,22 @@ var no_clone_element_default = createRule({
|
|
|
1512
1532
|
messages: { default: "Using 'cloneElement' is uncommon and can lead to fragile code. Use alternatives instead." },
|
|
1513
1533
|
schema: []
|
|
1514
1534
|
},
|
|
1515
|
-
name: RULE_NAME$
|
|
1516
|
-
create: create$
|
|
1535
|
+
name: RULE_NAME$45,
|
|
1536
|
+
create: create$45,
|
|
1517
1537
|
defaultOptions: []
|
|
1518
1538
|
});
|
|
1519
|
-
function create$
|
|
1520
|
-
return { CallExpression(node) {
|
|
1539
|
+
function create$45(context) {
|
|
1540
|
+
return defineRuleListener({ CallExpression(node) {
|
|
1521
1541
|
if (core.isCloneElementCall(context, node)) context.report({
|
|
1522
1542
|
messageId: "default",
|
|
1523
1543
|
node
|
|
1524
1544
|
});
|
|
1525
|
-
} };
|
|
1545
|
+
} });
|
|
1526
1546
|
}
|
|
1527
1547
|
|
|
1528
1548
|
//#endregion
|
|
1529
1549
|
//#region src/rules/no-component-will-mount.ts
|
|
1530
|
-
const RULE_NAME$
|
|
1550
|
+
const RULE_NAME$44 = "no-component-will-mount";
|
|
1531
1551
|
var no_component_will_mount_default = createRule({
|
|
1532
1552
|
meta: {
|
|
1533
1553
|
type: "problem",
|
|
@@ -1536,11 +1556,11 @@ var no_component_will_mount_default = createRule({
|
|
|
1536
1556
|
messages: { default: "[Deprecated] Use 'UNSAFE_componentWillMount' instead." },
|
|
1537
1557
|
schema: []
|
|
1538
1558
|
},
|
|
1539
|
-
name: RULE_NAME$
|
|
1540
|
-
create: create$
|
|
1559
|
+
name: RULE_NAME$44,
|
|
1560
|
+
create: create$44,
|
|
1541
1561
|
defaultOptions: []
|
|
1542
1562
|
});
|
|
1543
|
-
function create$
|
|
1563
|
+
function create$44(context) {
|
|
1544
1564
|
if (!context.sourceCode.text.includes("componentWillMount")) return {};
|
|
1545
1565
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1546
1566
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -1560,7 +1580,7 @@ function create$41(context) {
|
|
|
1560
1580
|
|
|
1561
1581
|
//#endregion
|
|
1562
1582
|
//#region src/rules/no-component-will-receive-props.ts
|
|
1563
|
-
const RULE_NAME$
|
|
1583
|
+
const RULE_NAME$43 = "no-component-will-receive-props";
|
|
1564
1584
|
var no_component_will_receive_props_default = createRule({
|
|
1565
1585
|
meta: {
|
|
1566
1586
|
type: "problem",
|
|
@@ -1569,11 +1589,11 @@ var no_component_will_receive_props_default = createRule({
|
|
|
1569
1589
|
messages: { default: "[Deprecated] Use 'UNSAFE_componentWillReceiveProps' instead." },
|
|
1570
1590
|
schema: []
|
|
1571
1591
|
},
|
|
1572
|
-
name: RULE_NAME$
|
|
1573
|
-
create: create$
|
|
1592
|
+
name: RULE_NAME$43,
|
|
1593
|
+
create: create$43,
|
|
1574
1594
|
defaultOptions: []
|
|
1575
1595
|
});
|
|
1576
|
-
function create$
|
|
1596
|
+
function create$43(context) {
|
|
1577
1597
|
if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {};
|
|
1578
1598
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1579
1599
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -1593,7 +1613,7 @@ function create$40(context) {
|
|
|
1593
1613
|
|
|
1594
1614
|
//#endregion
|
|
1595
1615
|
//#region src/rules/no-component-will-update.ts
|
|
1596
|
-
const RULE_NAME$
|
|
1616
|
+
const RULE_NAME$42 = "no-component-will-update";
|
|
1597
1617
|
var no_component_will_update_default = createRule({
|
|
1598
1618
|
meta: {
|
|
1599
1619
|
type: "problem",
|
|
@@ -1602,11 +1622,11 @@ var no_component_will_update_default = createRule({
|
|
|
1602
1622
|
messages: { default: "[Deprecated] Use 'UNSAFE_componentWillUpdate' instead." },
|
|
1603
1623
|
schema: []
|
|
1604
1624
|
},
|
|
1605
|
-
name: RULE_NAME$
|
|
1606
|
-
create: create$
|
|
1625
|
+
name: RULE_NAME$42,
|
|
1626
|
+
create: create$42,
|
|
1607
1627
|
defaultOptions: []
|
|
1608
1628
|
});
|
|
1609
|
-
function create$
|
|
1629
|
+
function create$42(context) {
|
|
1610
1630
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
1611
1631
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1612
1632
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -1626,7 +1646,7 @@ function create$39(context) {
|
|
|
1626
1646
|
|
|
1627
1647
|
//#endregion
|
|
1628
1648
|
//#region src/rules/no-context-provider.ts
|
|
1629
|
-
const RULE_NAME$
|
|
1649
|
+
const RULE_NAME$41 = "no-context-provider";
|
|
1630
1650
|
var no_context_provider_default = createRule({
|
|
1631
1651
|
meta: {
|
|
1632
1652
|
type: "problem",
|
|
@@ -1635,15 +1655,15 @@ var no_context_provider_default = createRule({
|
|
|
1635
1655
|
messages: { default: "In React 19, you can render '<Context>' as a provider instead of '<Context.Provider>'." },
|
|
1636
1656
|
schema: []
|
|
1637
1657
|
},
|
|
1638
|
-
name: RULE_NAME$
|
|
1639
|
-
create: create$
|
|
1658
|
+
name: RULE_NAME$41,
|
|
1659
|
+
create: create$41,
|
|
1640
1660
|
defaultOptions: []
|
|
1641
1661
|
});
|
|
1642
|
-
function create$
|
|
1662
|
+
function create$41(context) {
|
|
1643
1663
|
if (!context.sourceCode.text.includes("Provider")) return {};
|
|
1644
1664
|
const { version } = getSettingsFromContext(context);
|
|
1645
1665
|
if (compare(version, "19.0.0", "<")) return {};
|
|
1646
|
-
return { JSXElement(node) {
|
|
1666
|
+
return defineRuleListener({ JSXElement(node) {
|
|
1647
1667
|
const parts = core.getJsxElementType(context, node).split(".");
|
|
1648
1668
|
const selfName = parts.pop();
|
|
1649
1669
|
const contextFullName = parts.join(".");
|
|
@@ -1661,12 +1681,12 @@ function create$38(context) {
|
|
|
1661
1681
|
return [fixer.replaceText(openingElement.name, contextFullName), fixer.replaceText(closingElement.name, contextFullName)];
|
|
1662
1682
|
}
|
|
1663
1683
|
});
|
|
1664
|
-
} };
|
|
1684
|
+
} });
|
|
1665
1685
|
}
|
|
1666
1686
|
|
|
1667
1687
|
//#endregion
|
|
1668
1688
|
//#region src/rules/no-create-ref.ts
|
|
1669
|
-
const RULE_NAME$
|
|
1689
|
+
const RULE_NAME$40 = "no-create-ref";
|
|
1670
1690
|
var no_create_ref_default = createRule({
|
|
1671
1691
|
meta: {
|
|
1672
1692
|
type: "problem",
|
|
@@ -1674,22 +1694,22 @@ var no_create_ref_default = createRule({
|
|
|
1674
1694
|
messages: { default: "[Deprecated] Use 'useRef' instead." },
|
|
1675
1695
|
schema: []
|
|
1676
1696
|
},
|
|
1677
|
-
name: RULE_NAME$
|
|
1678
|
-
create: create$
|
|
1697
|
+
name: RULE_NAME$40,
|
|
1698
|
+
create: create$40,
|
|
1679
1699
|
defaultOptions: []
|
|
1680
1700
|
});
|
|
1681
|
-
function create$
|
|
1682
|
-
return { CallExpression(node) {
|
|
1701
|
+
function create$40(context) {
|
|
1702
|
+
return defineRuleListener({ CallExpression(node) {
|
|
1683
1703
|
if (core.isCreateRefCall(context, node) && ast.findParentNode(node, core.isClassComponent) == null) context.report({
|
|
1684
1704
|
messageId: "default",
|
|
1685
1705
|
node
|
|
1686
1706
|
});
|
|
1687
|
-
} };
|
|
1707
|
+
} });
|
|
1688
1708
|
}
|
|
1689
1709
|
|
|
1690
1710
|
//#endregion
|
|
1691
1711
|
//#region src/rules/no-direct-mutation-state.ts
|
|
1692
|
-
const RULE_NAME$
|
|
1712
|
+
const RULE_NAME$39 = "no-direct-mutation-state";
|
|
1693
1713
|
function isConstructorFunction(node) {
|
|
1694
1714
|
return ast.isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && ast.isMethodOrProperty(node.parent) && node.parent.key.type === AST_NODE_TYPES.Identifier && node.parent.key.name === "constructor";
|
|
1695
1715
|
}
|
|
@@ -1700,12 +1720,12 @@ var no_direct_mutation_state_default = createRule({
|
|
|
1700
1720
|
messages: { default: "Do not mutate state directly. Use 'setState()' instead." },
|
|
1701
1721
|
schema: []
|
|
1702
1722
|
},
|
|
1703
|
-
name: RULE_NAME$
|
|
1704
|
-
create: create$
|
|
1723
|
+
name: RULE_NAME$39,
|
|
1724
|
+
create: create$39,
|
|
1705
1725
|
defaultOptions: []
|
|
1706
1726
|
});
|
|
1707
|
-
function create$
|
|
1708
|
-
return { AssignmentExpression(node) {
|
|
1727
|
+
function create$39(context) {
|
|
1728
|
+
return defineRuleListener({ AssignmentExpression(node) {
|
|
1709
1729
|
if (!core.isAssignmentToThisState(node)) return;
|
|
1710
1730
|
const parentClass = ast.findParentNode(node, ast.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
|
|
1711
1731
|
if (parentClass == null) return;
|
|
@@ -1713,12 +1733,12 @@ function create$36(context) {
|
|
|
1713
1733
|
messageId: "default",
|
|
1714
1734
|
node
|
|
1715
1735
|
});
|
|
1716
|
-
} };
|
|
1736
|
+
} });
|
|
1717
1737
|
}
|
|
1718
1738
|
|
|
1719
1739
|
//#endregion
|
|
1720
1740
|
//#region src/rules/no-duplicate-key.ts
|
|
1721
|
-
const RULE_NAME$
|
|
1741
|
+
const RULE_NAME$38 = "no-duplicate-key";
|
|
1722
1742
|
var no_duplicate_key_default = createRule({
|
|
1723
1743
|
meta: {
|
|
1724
1744
|
type: "problem",
|
|
@@ -1726,11 +1746,11 @@ var no_duplicate_key_default = createRule({
|
|
|
1726
1746
|
messages: { default: "The 'key' prop must be unique to its sibling elements." },
|
|
1727
1747
|
schema: []
|
|
1728
1748
|
},
|
|
1729
|
-
name: RULE_NAME$
|
|
1730
|
-
create: create$
|
|
1749
|
+
name: RULE_NAME$38,
|
|
1750
|
+
create: create$38,
|
|
1731
1751
|
defaultOptions: []
|
|
1732
1752
|
});
|
|
1733
|
-
function create$
|
|
1753
|
+
function create$38(context) {
|
|
1734
1754
|
if (!context.sourceCode.text.includes("key=")) return {};
|
|
1735
1755
|
const keyedEntries = /* @__PURE__ */ new Map();
|
|
1736
1756
|
function isKeyValueEqual(a, b) {
|
|
@@ -1739,7 +1759,7 @@ function create$35(context) {
|
|
|
1739
1759
|
if (aValue == null || bValue == null) return false;
|
|
1740
1760
|
return ast.isNodeEqual(aValue, bValue);
|
|
1741
1761
|
}
|
|
1742
|
-
return {
|
|
1762
|
+
return defineRuleListener({
|
|
1743
1763
|
"JSXAttribute[name.name='key']"(node) {
|
|
1744
1764
|
const jsxElement = node.parent.parent;
|
|
1745
1765
|
switch (jsxElement.parent.type) {
|
|
@@ -1780,12 +1800,12 @@ function create$35(context) {
|
|
|
1780
1800
|
});
|
|
1781
1801
|
}
|
|
1782
1802
|
}
|
|
1783
|
-
};
|
|
1803
|
+
});
|
|
1784
1804
|
}
|
|
1785
1805
|
|
|
1786
1806
|
//#endregion
|
|
1787
1807
|
//#region src/rules/no-forward-ref.ts
|
|
1788
|
-
const RULE_NAME$
|
|
1808
|
+
const RULE_NAME$37 = "no-forward-ref";
|
|
1789
1809
|
var no_forward_ref_default = createRule({
|
|
1790
1810
|
meta: {
|
|
1791
1811
|
type: "problem",
|
|
@@ -1794,15 +1814,15 @@ var no_forward_ref_default = createRule({
|
|
|
1794
1814
|
messages: { default: "In React 19, 'forwardRef' is no longer necessary. Pass 'ref' as a prop instead." },
|
|
1795
1815
|
schema: []
|
|
1796
1816
|
},
|
|
1797
|
-
name: RULE_NAME$
|
|
1798
|
-
create: create$
|
|
1817
|
+
name: RULE_NAME$37,
|
|
1818
|
+
create: create$37,
|
|
1799
1819
|
defaultOptions: []
|
|
1800
1820
|
});
|
|
1801
|
-
function create$
|
|
1821
|
+
function create$37(context) {
|
|
1802
1822
|
if (!context.sourceCode.text.includes("forwardRef")) return {};
|
|
1803
1823
|
const { version } = getSettingsFromContext(context);
|
|
1804
1824
|
if (compare(version, "19.0.0", "<")) return {};
|
|
1805
|
-
return { CallExpression(node) {
|
|
1825
|
+
return defineRuleListener({ CallExpression(node) {
|
|
1806
1826
|
if (!core.isForwardRefCall(context, node)) return;
|
|
1807
1827
|
const id = ast.getFunctionId(node);
|
|
1808
1828
|
const fix = canFix(context, node) ? getFix(context, node) : null;
|
|
@@ -1811,7 +1831,7 @@ function create$34(context) {
|
|
|
1811
1831
|
node: id ?? node,
|
|
1812
1832
|
fix
|
|
1813
1833
|
});
|
|
1814
|
-
} };
|
|
1834
|
+
} });
|
|
1815
1835
|
}
|
|
1816
1836
|
/**
|
|
1817
1837
|
* Determine whether the given CallExpression can be safely auto-fixed by replacing
|
|
@@ -1893,7 +1913,7 @@ function getComponentPropsFixes(context, fixer, node, typeArguments) {
|
|
|
1893
1913
|
|
|
1894
1914
|
//#endregion
|
|
1895
1915
|
//#region src/rules/no-implicit-key.ts
|
|
1896
|
-
const RULE_NAME$
|
|
1916
|
+
const RULE_NAME$36 = "no-implicit-key";
|
|
1897
1917
|
var no_implicit_key_default = createRule({
|
|
1898
1918
|
meta: {
|
|
1899
1919
|
type: "problem",
|
|
@@ -1901,14 +1921,14 @@ var no_implicit_key_default = createRule({
|
|
|
1901
1921
|
messages: { default: "This spread attribute implicitly passes the 'key' prop to a component, this could lead to unexpected behavior. If you intend to pass the 'key' prop, use 'key={value}'." },
|
|
1902
1922
|
schema: []
|
|
1903
1923
|
},
|
|
1904
|
-
name: RULE_NAME$
|
|
1905
|
-
create: create$
|
|
1924
|
+
name: RULE_NAME$36,
|
|
1925
|
+
create: create$36,
|
|
1906
1926
|
defaultOptions: []
|
|
1907
1927
|
});
|
|
1908
|
-
function create$
|
|
1928
|
+
function create$36(context) {
|
|
1909
1929
|
const services = ESLintUtils.getParserServices(context, false);
|
|
1910
1930
|
const checker = services.program.getTypeChecker();
|
|
1911
|
-
return { JSXSpreadAttribute(node) {
|
|
1931
|
+
return defineRuleListener({ JSXSpreadAttribute(node) {
|
|
1912
1932
|
for (const type of unionConstituents(getConstrainedTypeAtLocation(services, node.argument))) {
|
|
1913
1933
|
const key = type.getProperty("key");
|
|
1914
1934
|
if (key == null) continue;
|
|
@@ -1918,12 +1938,12 @@ function create$33(context) {
|
|
|
1918
1938
|
node
|
|
1919
1939
|
});
|
|
1920
1940
|
}
|
|
1921
|
-
} };
|
|
1941
|
+
} });
|
|
1922
1942
|
}
|
|
1923
1943
|
|
|
1924
1944
|
//#endregion
|
|
1925
1945
|
//#region src/rules/no-leaked-conditional-rendering.ts
|
|
1926
|
-
const RULE_NAME$
|
|
1946
|
+
const RULE_NAME$35 = "no-leaked-conditional-rendering";
|
|
1927
1947
|
var no_leaked_conditional_rendering_default = createRule({
|
|
1928
1948
|
meta: {
|
|
1929
1949
|
type: "problem",
|
|
@@ -1931,11 +1951,11 @@ var no_leaked_conditional_rendering_default = createRule({
|
|
|
1931
1951
|
messages: { default: "Potential leaked value {{value}} that might cause unintentionally rendered values or rendering crashes." },
|
|
1932
1952
|
schema: []
|
|
1933
1953
|
},
|
|
1934
|
-
name: RULE_NAME$
|
|
1935
|
-
create: create$
|
|
1954
|
+
name: RULE_NAME$35,
|
|
1955
|
+
create: create$35,
|
|
1936
1956
|
defaultOptions: []
|
|
1937
1957
|
});
|
|
1938
|
-
function create$
|
|
1958
|
+
function create$35(context) {
|
|
1939
1959
|
if (!context.sourceCode.text.includes("&&")) return {};
|
|
1940
1960
|
const { version } = getSettingsFromContext(context);
|
|
1941
1961
|
const allowedVariants = [
|
|
@@ -1987,12 +2007,12 @@ function create$32(context) {
|
|
|
1987
2007
|
return match(variableDefNode).with({ init: P.select({ type: P.not(AST_NODE_TYPES.VariableDeclaration) }) }, getReportDescriptor).otherwise(() => unit);
|
|
1988
2008
|
}).otherwise(() => unit);
|
|
1989
2009
|
}
|
|
1990
|
-
return { JSXExpressionContainer: flow(getReportDescriptor, report(context)) };
|
|
2010
|
+
return defineRuleListener({ JSXExpressionContainer: flow(getReportDescriptor, report(context)) });
|
|
1991
2011
|
}
|
|
1992
2012
|
|
|
1993
2013
|
//#endregion
|
|
1994
2014
|
//#region src/rules/no-missing-component-display-name.ts
|
|
1995
|
-
const RULE_NAME$
|
|
2015
|
+
const RULE_NAME$34 = "no-missing-component-display-name";
|
|
1996
2016
|
var no_missing_component_display_name_default = createRule({
|
|
1997
2017
|
meta: {
|
|
1998
2018
|
type: "problem",
|
|
@@ -2000,11 +2020,11 @@ var no_missing_component_display_name_default = createRule({
|
|
|
2000
2020
|
messages: { default: "Add missing 'displayName' for component." },
|
|
2001
2021
|
schema: []
|
|
2002
2022
|
},
|
|
2003
|
-
name: RULE_NAME$
|
|
2004
|
-
create: create$
|
|
2023
|
+
name: RULE_NAME$34,
|
|
2024
|
+
create: create$34,
|
|
2005
2025
|
defaultOptions: []
|
|
2006
2026
|
});
|
|
2007
|
-
function create$
|
|
2027
|
+
function create$34(context) {
|
|
2008
2028
|
if (!context.sourceCode.text.includes("memo") && !context.sourceCode.text.includes("forwardRef")) return {};
|
|
2009
2029
|
const { ctx, visitor } = core.useComponentCollector(context, {
|
|
2010
2030
|
collectDisplayName: true,
|
|
@@ -2026,7 +2046,7 @@ function create$31(context) {
|
|
|
2026
2046
|
|
|
2027
2047
|
//#endregion
|
|
2028
2048
|
//#region src/rules/no-missing-context-display-name.ts
|
|
2029
|
-
const RULE_NAME$
|
|
2049
|
+
const RULE_NAME$33 = "no-missing-context-display-name";
|
|
2030
2050
|
var no_missing_context_display_name_default = createRule({
|
|
2031
2051
|
meta: {
|
|
2032
2052
|
type: "problem",
|
|
@@ -2035,15 +2055,15 @@ var no_missing_context_display_name_default = createRule({
|
|
|
2035
2055
|
messages: { default: "Add missing 'displayName' for context." },
|
|
2036
2056
|
schema: []
|
|
2037
2057
|
},
|
|
2038
|
-
name: RULE_NAME$
|
|
2039
|
-
create: create$
|
|
2058
|
+
name: RULE_NAME$33,
|
|
2059
|
+
create: create$33,
|
|
2040
2060
|
defaultOptions: []
|
|
2041
2061
|
});
|
|
2042
|
-
function create$
|
|
2062
|
+
function create$33(context) {
|
|
2043
2063
|
if (!context.sourceCode.text.includes("createContext")) return {};
|
|
2044
2064
|
const createCalls = [];
|
|
2045
2065
|
const displayNameAssignments = [];
|
|
2046
|
-
return {
|
|
2066
|
+
return defineRuleListener({
|
|
2047
2067
|
[ast.SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION](node) {
|
|
2048
2068
|
displayNameAssignments.push(node);
|
|
2049
2069
|
},
|
|
@@ -2086,12 +2106,12 @@ function create$30(context) {
|
|
|
2086
2106
|
});
|
|
2087
2107
|
}
|
|
2088
2108
|
}
|
|
2089
|
-
};
|
|
2109
|
+
});
|
|
2090
2110
|
}
|
|
2091
2111
|
|
|
2092
2112
|
//#endregion
|
|
2093
2113
|
//#region src/rules/no-missing-key.ts
|
|
2094
|
-
const RULE_NAME$
|
|
2114
|
+
const RULE_NAME$32 = "no-missing-key";
|
|
2095
2115
|
var no_missing_key_default = createRule({
|
|
2096
2116
|
meta: {
|
|
2097
2117
|
type: "problem",
|
|
@@ -2102,11 +2122,11 @@ var no_missing_key_default = createRule({
|
|
|
2102
2122
|
},
|
|
2103
2123
|
schema: []
|
|
2104
2124
|
},
|
|
2105
|
-
name: RULE_NAME$
|
|
2106
|
-
create: create$
|
|
2125
|
+
name: RULE_NAME$32,
|
|
2126
|
+
create: create$32,
|
|
2107
2127
|
defaultOptions: []
|
|
2108
2128
|
});
|
|
2109
|
-
function create$
|
|
2129
|
+
function create$32(ctx) {
|
|
2110
2130
|
let inChildrenToArray = false;
|
|
2111
2131
|
function check(node) {
|
|
2112
2132
|
if (node.type === AST_NODE_TYPES.JSXElement) return core.getJsxAttribute(ctx, node)("key") == null ? {
|
|
@@ -2129,9 +2149,16 @@ function create$29(ctx) {
|
|
|
2129
2149
|
}
|
|
2130
2150
|
}
|
|
2131
2151
|
function checkBlock(node) {
|
|
2132
|
-
|
|
2152
|
+
const descriptors = [];
|
|
2153
|
+
for (const stmt of ast.getNestedReturnStatements(node)) {
|
|
2154
|
+
if (stmt.argument == null) continue;
|
|
2155
|
+
const desc = check(stmt.argument);
|
|
2156
|
+
if (desc == null) continue;
|
|
2157
|
+
descriptors.push(desc);
|
|
2158
|
+
}
|
|
2159
|
+
return descriptors;
|
|
2133
2160
|
}
|
|
2134
|
-
return {
|
|
2161
|
+
return defineRuleListener({
|
|
2135
2162
|
ArrayExpression(node) {
|
|
2136
2163
|
if (inChildrenToArray) return;
|
|
2137
2164
|
const elements = node.elements.filter(ast.is(AST_NODE_TYPES.JSXElement));
|
|
@@ -2165,12 +2192,12 @@ function create$29(ctx) {
|
|
|
2165
2192
|
node
|
|
2166
2193
|
});
|
|
2167
2194
|
}
|
|
2168
|
-
};
|
|
2195
|
+
});
|
|
2169
2196
|
}
|
|
2170
2197
|
|
|
2171
2198
|
//#endregion
|
|
2172
2199
|
//#region src/rules/no-misused-capture-owner-stack.ts
|
|
2173
|
-
const RULE_NAME$
|
|
2200
|
+
const RULE_NAME$31 = "no-misused-capture-owner-stack";
|
|
2174
2201
|
var no_misused_capture_owner_stack_default = createRule({
|
|
2175
2202
|
meta: {
|
|
2176
2203
|
type: "problem",
|
|
@@ -2181,14 +2208,14 @@ var no_misused_capture_owner_stack_default = createRule({
|
|
|
2181
2208
|
},
|
|
2182
2209
|
schema: []
|
|
2183
2210
|
},
|
|
2184
|
-
name: RULE_NAME$
|
|
2185
|
-
create: create$
|
|
2211
|
+
name: RULE_NAME$31,
|
|
2212
|
+
create: create$31,
|
|
2186
2213
|
defaultOptions: []
|
|
2187
2214
|
});
|
|
2188
|
-
function create$
|
|
2215
|
+
function create$31(context) {
|
|
2189
2216
|
if (!context.sourceCode.text.includes("captureOwnerStack")) return {};
|
|
2190
2217
|
const { importSource } = getSettingsFromContext(context);
|
|
2191
|
-
return {
|
|
2218
|
+
return defineRuleListener({
|
|
2192
2219
|
CallExpression(node) {
|
|
2193
2220
|
if (!core.isCaptureOwnerStackCall(context, node)) return;
|
|
2194
2221
|
if (ast.findParentNode(node, isDevelopmentOnlyCheck) == null) context.report({
|
|
@@ -2207,7 +2234,7 @@ function create$28(context) {
|
|
|
2207
2234
|
});
|
|
2208
2235
|
}
|
|
2209
2236
|
}
|
|
2210
|
-
};
|
|
2237
|
+
});
|
|
2211
2238
|
}
|
|
2212
2239
|
function isDevelopmentOnlyCheck(node) {
|
|
2213
2240
|
if (node.type !== AST_NODE_TYPES.IfStatement) return false;
|
|
@@ -2216,7 +2243,7 @@ function isDevelopmentOnlyCheck(node) {
|
|
|
2216
2243
|
|
|
2217
2244
|
//#endregion
|
|
2218
2245
|
//#region src/rules/no-nested-component-definitions.ts
|
|
2219
|
-
const RULE_NAME$
|
|
2246
|
+
const RULE_NAME$30 = "no-nested-component-definitions";
|
|
2220
2247
|
var no_nested_component_definitions_default = createRule({
|
|
2221
2248
|
meta: {
|
|
2222
2249
|
type: "problem",
|
|
@@ -2224,11 +2251,11 @@ var no_nested_component_definitions_default = createRule({
|
|
|
2224
2251
|
messages: { default: "Do not nest component definitions inside other components or props. {{suggestion}}" },
|
|
2225
2252
|
schema: []
|
|
2226
2253
|
},
|
|
2227
|
-
name: RULE_NAME$
|
|
2228
|
-
create: create$
|
|
2254
|
+
name: RULE_NAME$30,
|
|
2255
|
+
create: create$30,
|
|
2229
2256
|
defaultOptions: []
|
|
2230
2257
|
});
|
|
2231
|
-
function create$
|
|
2258
|
+
function create$30(context) {
|
|
2232
2259
|
const hint = core.ComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.ComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.ComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.ComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.ComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.ComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.ComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
|
|
2233
2260
|
const fCollector = core.useComponentCollector(context, { hint });
|
|
2234
2261
|
const cCollector = core.useComponentCollectorLegacy(context);
|
|
@@ -2333,7 +2360,7 @@ function isInsideCreateElementProps(context, node) {
|
|
|
2333
2360
|
|
|
2334
2361
|
//#endregion
|
|
2335
2362
|
//#region src/rules/no-nested-lazy-component-declarations.ts
|
|
2336
|
-
const RULE_NAME$
|
|
2363
|
+
const RULE_NAME$29 = "no-nested-lazy-component-declarations";
|
|
2337
2364
|
var no_nested_lazy_component_declarations_default = createRule({
|
|
2338
2365
|
meta: {
|
|
2339
2366
|
type: "problem",
|
|
@@ -2341,11 +2368,11 @@ var no_nested_lazy_component_declarations_default = createRule({
|
|
|
2341
2368
|
messages: { default: "Do not declare lazy components inside other components. Instead, always declare them at the top level of your module." },
|
|
2342
2369
|
schema: []
|
|
2343
2370
|
},
|
|
2344
|
-
name: RULE_NAME$
|
|
2345
|
-
create: create$
|
|
2371
|
+
name: RULE_NAME$29,
|
|
2372
|
+
create: create$29,
|
|
2346
2373
|
defaultOptions: []
|
|
2347
2374
|
});
|
|
2348
|
-
function create$
|
|
2375
|
+
function create$29(context) {
|
|
2349
2376
|
const hint = core.ComponentDetectionHint.None;
|
|
2350
2377
|
const collector = core.useComponentCollector(context, { hint });
|
|
2351
2378
|
const collectorLegacy = core.useComponentCollectorLegacy(context);
|
|
@@ -2374,7 +2401,7 @@ function create$26(context) {
|
|
|
2374
2401
|
|
|
2375
2402
|
//#endregion
|
|
2376
2403
|
//#region src/rules/no-redundant-should-component-update.ts
|
|
2377
|
-
const RULE_NAME$
|
|
2404
|
+
const RULE_NAME$28 = "no-redundant-should-component-update";
|
|
2378
2405
|
function isShouldComponentUpdate(node) {
|
|
2379
2406
|
return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "shouldComponentUpdate";
|
|
2380
2407
|
}
|
|
@@ -2385,11 +2412,11 @@ var no_redundant_should_component_update_default = createRule({
|
|
|
2385
2412
|
messages: { default: "'{{componentName}}' does not need 'shouldComponentUpdate' when extending 'React.PureComponent'." },
|
|
2386
2413
|
schema: []
|
|
2387
2414
|
},
|
|
2388
|
-
name: RULE_NAME$
|
|
2389
|
-
create: create$
|
|
2415
|
+
name: RULE_NAME$28,
|
|
2416
|
+
create: create$28,
|
|
2390
2417
|
defaultOptions: []
|
|
2391
2418
|
});
|
|
2392
|
-
function create$
|
|
2419
|
+
function create$28(context) {
|
|
2393
2420
|
if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {};
|
|
2394
2421
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2395
2422
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -2407,7 +2434,7 @@ function create$25(context) {
|
|
|
2407
2434
|
|
|
2408
2435
|
//#endregion
|
|
2409
2436
|
//#region src/rules/no-set-state-in-component-did-mount.ts
|
|
2410
|
-
const RULE_NAME$
|
|
2437
|
+
const RULE_NAME$27 = "no-set-state-in-component-did-mount";
|
|
2411
2438
|
var no_set_state_in_component_did_mount_default = createRule({
|
|
2412
2439
|
meta: {
|
|
2413
2440
|
type: "problem",
|
|
@@ -2415,13 +2442,13 @@ var no_set_state_in_component_did_mount_default = createRule({
|
|
|
2415
2442
|
messages: { default: "Do not call `this.setState` in `componentDidMount` outside functions such as callbacks." },
|
|
2416
2443
|
schema: []
|
|
2417
2444
|
},
|
|
2418
|
-
name: RULE_NAME$
|
|
2419
|
-
create: create$
|
|
2445
|
+
name: RULE_NAME$27,
|
|
2446
|
+
create: create$27,
|
|
2420
2447
|
defaultOptions: []
|
|
2421
2448
|
});
|
|
2422
|
-
function create$
|
|
2449
|
+
function create$27(context) {
|
|
2423
2450
|
if (!context.sourceCode.text.includes("componentDidMount")) return {};
|
|
2424
|
-
return { CallExpression(node) {
|
|
2451
|
+
return defineRuleListener({ CallExpression(node) {
|
|
2425
2452
|
if (!core.isThisSetState(node)) return;
|
|
2426
2453
|
const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
|
|
2427
2454
|
const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentDidMount(n));
|
|
@@ -2432,12 +2459,12 @@ function create$24(context) {
|
|
|
2432
2459
|
messageId: "default",
|
|
2433
2460
|
node
|
|
2434
2461
|
});
|
|
2435
|
-
} };
|
|
2462
|
+
} });
|
|
2436
2463
|
}
|
|
2437
2464
|
|
|
2438
2465
|
//#endregion
|
|
2439
2466
|
//#region src/rules/no-set-state-in-component-did-update.ts
|
|
2440
|
-
const RULE_NAME$
|
|
2467
|
+
const RULE_NAME$26 = "no-set-state-in-component-did-update";
|
|
2441
2468
|
var no_set_state_in_component_did_update_default = createRule({
|
|
2442
2469
|
meta: {
|
|
2443
2470
|
type: "problem",
|
|
@@ -2445,13 +2472,13 @@ var no_set_state_in_component_did_update_default = createRule({
|
|
|
2445
2472
|
messages: { default: "Do not call `this.setState` in `componentDidUpdate` outside functions such as callbacks." },
|
|
2446
2473
|
schema: []
|
|
2447
2474
|
},
|
|
2448
|
-
name: RULE_NAME$
|
|
2449
|
-
create: create$
|
|
2475
|
+
name: RULE_NAME$26,
|
|
2476
|
+
create: create$26,
|
|
2450
2477
|
defaultOptions: []
|
|
2451
2478
|
});
|
|
2452
|
-
function create$
|
|
2479
|
+
function create$26(context) {
|
|
2453
2480
|
if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
|
|
2454
|
-
return { CallExpression(node) {
|
|
2481
|
+
return defineRuleListener({ CallExpression(node) {
|
|
2455
2482
|
if (!core.isThisSetState(node)) return;
|
|
2456
2483
|
const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
|
|
2457
2484
|
const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentDidUpdate(n));
|
|
@@ -2462,12 +2489,12 @@ function create$23(context) {
|
|
|
2462
2489
|
messageId: "default",
|
|
2463
2490
|
node
|
|
2464
2491
|
});
|
|
2465
|
-
} };
|
|
2492
|
+
} });
|
|
2466
2493
|
}
|
|
2467
2494
|
|
|
2468
2495
|
//#endregion
|
|
2469
2496
|
//#region src/rules/no-set-state-in-component-will-update.ts
|
|
2470
|
-
const RULE_NAME$
|
|
2497
|
+
const RULE_NAME$25 = "no-set-state-in-component-will-update";
|
|
2471
2498
|
var no_set_state_in_component_will_update_default = createRule({
|
|
2472
2499
|
meta: {
|
|
2473
2500
|
type: "problem",
|
|
@@ -2475,13 +2502,13 @@ var no_set_state_in_component_will_update_default = createRule({
|
|
|
2475
2502
|
messages: { default: "Do not call `this.setState` in `componentWillUpdate` outside functions such as callbacks." },
|
|
2476
2503
|
schema: []
|
|
2477
2504
|
},
|
|
2478
|
-
name: RULE_NAME$
|
|
2479
|
-
create: create$
|
|
2505
|
+
name: RULE_NAME$25,
|
|
2506
|
+
create: create$25,
|
|
2480
2507
|
defaultOptions: []
|
|
2481
2508
|
});
|
|
2482
|
-
function create$
|
|
2509
|
+
function create$25(context) {
|
|
2483
2510
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
2484
|
-
return { CallExpression(node) {
|
|
2511
|
+
return defineRuleListener({ CallExpression(node) {
|
|
2485
2512
|
if (!core.isThisSetState(node)) return;
|
|
2486
2513
|
const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
|
|
2487
2514
|
const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentWillUpdate(n));
|
|
@@ -2492,12 +2519,12 @@ function create$22(context) {
|
|
|
2492
2519
|
messageId: "default",
|
|
2493
2520
|
node
|
|
2494
2521
|
});
|
|
2495
|
-
} };
|
|
2522
|
+
} });
|
|
2496
2523
|
}
|
|
2497
2524
|
|
|
2498
2525
|
//#endregion
|
|
2499
2526
|
//#region src/rules/no-unnecessary-use-callback.ts
|
|
2500
|
-
const RULE_NAME$
|
|
2527
|
+
const RULE_NAME$24 = "no-unnecessary-use-callback";
|
|
2501
2528
|
var no_unnecessary_use_callback_default = createRule({
|
|
2502
2529
|
meta: {
|
|
2503
2530
|
type: "problem",
|
|
@@ -2508,13 +2535,13 @@ var no_unnecessary_use_callback_default = createRule({
|
|
|
2508
2535
|
},
|
|
2509
2536
|
schema: []
|
|
2510
2537
|
},
|
|
2511
|
-
name: RULE_NAME$
|
|
2512
|
-
create: create$
|
|
2538
|
+
name: RULE_NAME$24,
|
|
2539
|
+
create: create$24,
|
|
2513
2540
|
defaultOptions: []
|
|
2514
2541
|
});
|
|
2515
|
-
function create$
|
|
2542
|
+
function create$24(context) {
|
|
2516
2543
|
if (!context.sourceCode.text.includes("useCallback")) return {};
|
|
2517
|
-
return { VariableDeclarator(node) {
|
|
2544
|
+
return defineRuleListener({ VariableDeclarator(node) {
|
|
2518
2545
|
const { id, init } = node;
|
|
2519
2546
|
if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !core.isUseCallbackCall(init)) return;
|
|
2520
2547
|
const [cbk, ...rest] = context.sourceCode.getDeclaredVariables(node);
|
|
@@ -2526,7 +2553,7 @@ function create$21(context) {
|
|
|
2526
2553
|
const [arg0, arg1] = init.arguments;
|
|
2527
2554
|
if (arg0 == null || arg1 == null) return;
|
|
2528
2555
|
if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2529
|
-
const variableNode =
|
|
2556
|
+
const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
|
|
2530
2557
|
if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) return false;
|
|
2531
2558
|
return variableNode.elements.length === 0;
|
|
2532
2559
|
}).otherwise(() => false)) {
|
|
@@ -2537,7 +2564,7 @@ function create$21(context) {
|
|
|
2537
2564
|
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) return n.body;
|
|
2538
2565
|
return n;
|
|
2539
2566
|
}).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2540
|
-
const variableNode =
|
|
2567
|
+
const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
|
|
2541
2568
|
if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) return null;
|
|
2542
2569
|
return variableNode;
|
|
2543
2570
|
}).otherwise(() => null);
|
|
@@ -2550,7 +2577,7 @@ function create$21(context) {
|
|
|
2550
2577
|
return;
|
|
2551
2578
|
}
|
|
2552
2579
|
report(context)(checkForUsageInsideUseEffectReport);
|
|
2553
|
-
} };
|
|
2580
|
+
} });
|
|
2554
2581
|
}
|
|
2555
2582
|
function checkForUsageInsideUseEffect$1(sourceCode, node) {
|
|
2556
2583
|
if (!/use\w*Effect/u.test(sourceCode.text)) return;
|
|
@@ -2574,7 +2601,7 @@ function checkForUsageInsideUseEffect$1(sourceCode, node) {
|
|
|
2574
2601
|
|
|
2575
2602
|
//#endregion
|
|
2576
2603
|
//#region src/rules/no-unnecessary-use-memo.ts
|
|
2577
|
-
const RULE_NAME$
|
|
2604
|
+
const RULE_NAME$23 = "no-unnecessary-use-memo";
|
|
2578
2605
|
var no_unnecessary_use_memo_default = createRule({
|
|
2579
2606
|
meta: {
|
|
2580
2607
|
type: "problem",
|
|
@@ -2585,13 +2612,13 @@ var no_unnecessary_use_memo_default = createRule({
|
|
|
2585
2612
|
},
|
|
2586
2613
|
schema: []
|
|
2587
2614
|
},
|
|
2588
|
-
name: RULE_NAME$
|
|
2589
|
-
create: create$
|
|
2615
|
+
name: RULE_NAME$23,
|
|
2616
|
+
create: create$23,
|
|
2590
2617
|
defaultOptions: []
|
|
2591
2618
|
});
|
|
2592
|
-
function create$
|
|
2619
|
+
function create$23(context) {
|
|
2593
2620
|
if (!context.sourceCode.text.includes("useMemo")) return {};
|
|
2594
|
-
return { VariableDeclarator(node) {
|
|
2621
|
+
return defineRuleListener({ VariableDeclarator(node) {
|
|
2595
2622
|
const { id, init } = node;
|
|
2596
2623
|
if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !core.isUseMemoCall(init)) return;
|
|
2597
2624
|
const [mem, ...rest] = context.sourceCode.getDeclaredVariables(node);
|
|
@@ -2607,7 +2634,7 @@ function create$20(context) {
|
|
|
2607
2634
|
return;
|
|
2608
2635
|
}
|
|
2609
2636
|
if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2610
|
-
const variableNode =
|
|
2637
|
+
const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
|
|
2611
2638
|
if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) return false;
|
|
2612
2639
|
return variableNode.elements.length === 0;
|
|
2613
2640
|
}).otherwise(() => false)) {
|
|
@@ -2618,7 +2645,7 @@ function create$20(context) {
|
|
|
2618
2645
|
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) return n.body;
|
|
2619
2646
|
return n;
|
|
2620
2647
|
}).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2621
|
-
const variableNode =
|
|
2648
|
+
const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
|
|
2622
2649
|
if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) return null;
|
|
2623
2650
|
return variableNode;
|
|
2624
2651
|
}).otherwise(() => null);
|
|
@@ -2631,7 +2658,7 @@ function create$20(context) {
|
|
|
2631
2658
|
return;
|
|
2632
2659
|
}
|
|
2633
2660
|
report(context)(checkForUsageInsideUseEffectReport);
|
|
2634
|
-
} };
|
|
2661
|
+
} });
|
|
2635
2662
|
}
|
|
2636
2663
|
function checkForUsageInsideUseEffect(sourceCode, node) {
|
|
2637
2664
|
if (!/use\w*Effect/u.test(sourceCode.text)) return;
|
|
@@ -2655,7 +2682,7 @@ function checkForUsageInsideUseEffect(sourceCode, node) {
|
|
|
2655
2682
|
|
|
2656
2683
|
//#endregion
|
|
2657
2684
|
//#region src/rules/no-unnecessary-use-prefix.ts
|
|
2658
|
-
const RULE_NAME$
|
|
2685
|
+
const RULE_NAME$22 = "no-unnecessary-use-prefix";
|
|
2659
2686
|
const WELL_KNOWN_HOOKS = ["useMDXComponents"];
|
|
2660
2687
|
function containsUseComments(context, node) {
|
|
2661
2688
|
return context.sourceCode.getCommentsInside(node).some(({ value }) => /use\([\s\S]*?\)/u.test(value) || /use[A-Z0-9]\w*\([\s\S]*?\)/u.test(value));
|
|
@@ -2667,11 +2694,11 @@ var no_unnecessary_use_prefix_default = createRule({
|
|
|
2667
2694
|
messages: { default: "If your function doesn't call any Hooks, avoid the 'use' prefix. Instead, write it as a regular function without the 'use' prefix." },
|
|
2668
2695
|
schema: []
|
|
2669
2696
|
},
|
|
2670
|
-
name: RULE_NAME$
|
|
2671
|
-
create: create$
|
|
2697
|
+
name: RULE_NAME$22,
|
|
2698
|
+
create: create$22,
|
|
2672
2699
|
defaultOptions: []
|
|
2673
2700
|
});
|
|
2674
|
-
function create$
|
|
2701
|
+
function create$22(context) {
|
|
2675
2702
|
const { ctx, visitor } = core.useHookCollector(context);
|
|
2676
2703
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
2677
2704
|
for (const { id, name, node, hookCalls } of ctx.getAllHooks(program)) {
|
|
@@ -2691,7 +2718,7 @@ function create$19(context) {
|
|
|
2691
2718
|
|
|
2692
2719
|
//#endregion
|
|
2693
2720
|
//#region src/rules/no-unsafe-component-will-mount.ts
|
|
2694
|
-
const RULE_NAME$
|
|
2721
|
+
const RULE_NAME$21 = "no-unsafe-component-will-mount";
|
|
2695
2722
|
var no_unsafe_component_will_mount_default = createRule({
|
|
2696
2723
|
meta: {
|
|
2697
2724
|
type: "problem",
|
|
@@ -2699,11 +2726,11 @@ var no_unsafe_component_will_mount_default = createRule({
|
|
|
2699
2726
|
messages: { default: "Do not use 'UNSAFE_componentWillMount'." },
|
|
2700
2727
|
schema: []
|
|
2701
2728
|
},
|
|
2702
|
-
name: RULE_NAME$
|
|
2703
|
-
create: create$
|
|
2729
|
+
name: RULE_NAME$21,
|
|
2730
|
+
create: create$21,
|
|
2704
2731
|
defaultOptions: []
|
|
2705
2732
|
});
|
|
2706
|
-
function create$
|
|
2733
|
+
function create$21(context) {
|
|
2707
2734
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {};
|
|
2708
2735
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2709
2736
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -2719,7 +2746,7 @@ function create$18(context) {
|
|
|
2719
2746
|
|
|
2720
2747
|
//#endregion
|
|
2721
2748
|
//#region src/rules/no-unsafe-component-will-receive-props.ts
|
|
2722
|
-
const RULE_NAME$
|
|
2749
|
+
const RULE_NAME$20 = "no-unsafe-component-will-receive-props";
|
|
2723
2750
|
var no_unsafe_component_will_receive_props_default = createRule({
|
|
2724
2751
|
meta: {
|
|
2725
2752
|
type: "problem",
|
|
@@ -2727,11 +2754,11 @@ var no_unsafe_component_will_receive_props_default = createRule({
|
|
|
2727
2754
|
messages: { default: "Do not use 'UNSAFE_componentWillReceiveProps'." },
|
|
2728
2755
|
schema: []
|
|
2729
2756
|
},
|
|
2730
|
-
name: RULE_NAME$
|
|
2731
|
-
create: create$
|
|
2757
|
+
name: RULE_NAME$20,
|
|
2758
|
+
create: create$20,
|
|
2732
2759
|
defaultOptions: []
|
|
2733
2760
|
});
|
|
2734
|
-
function create$
|
|
2761
|
+
function create$20(context) {
|
|
2735
2762
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) return {};
|
|
2736
2763
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2737
2764
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -2747,7 +2774,7 @@ function create$17(context) {
|
|
|
2747
2774
|
|
|
2748
2775
|
//#endregion
|
|
2749
2776
|
//#region src/rules/no-unsafe-component-will-update.ts
|
|
2750
|
-
const RULE_NAME$
|
|
2777
|
+
const RULE_NAME$19 = "no-unsafe-component-will-update";
|
|
2751
2778
|
var no_unsafe_component_will_update_default = createRule({
|
|
2752
2779
|
meta: {
|
|
2753
2780
|
type: "problem",
|
|
@@ -2755,11 +2782,11 @@ var no_unsafe_component_will_update_default = createRule({
|
|
|
2755
2782
|
messages: { default: "Do not use 'UNSAFE_componentWillUpdate'." },
|
|
2756
2783
|
schema: []
|
|
2757
2784
|
},
|
|
2758
|
-
name: RULE_NAME$
|
|
2759
|
-
create: create$
|
|
2785
|
+
name: RULE_NAME$19,
|
|
2786
|
+
create: create$19,
|
|
2760
2787
|
defaultOptions: []
|
|
2761
2788
|
});
|
|
2762
|
-
function create$
|
|
2789
|
+
function create$19(context) {
|
|
2763
2790
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {};
|
|
2764
2791
|
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2765
2792
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
@@ -2775,7 +2802,7 @@ function create$16(context) {
|
|
|
2775
2802
|
|
|
2776
2803
|
//#endregion
|
|
2777
2804
|
//#region src/rules/no-unstable-context-value.ts
|
|
2778
|
-
const RULE_NAME$
|
|
2805
|
+
const RULE_NAME$18 = "no-unstable-context-value";
|
|
2779
2806
|
var no_unstable_context_value_default = createRule({
|
|
2780
2807
|
meta: {
|
|
2781
2808
|
type: "problem",
|
|
@@ -2783,13 +2810,14 @@ var no_unstable_context_value_default = createRule({
|
|
|
2783
2810
|
messages: { unstableContextValue: "A/an '{{kind}}' passed as the value prop to the context provider should not be constructed. It will change on every render. {{suggestion}}" },
|
|
2784
2811
|
schema: []
|
|
2785
2812
|
},
|
|
2786
|
-
name: RULE_NAME$
|
|
2787
|
-
create: create$
|
|
2813
|
+
name: RULE_NAME$18,
|
|
2814
|
+
create: create$18,
|
|
2788
2815
|
defaultOptions: []
|
|
2789
2816
|
});
|
|
2790
|
-
function create$
|
|
2791
|
-
const {
|
|
2792
|
-
if (
|
|
2817
|
+
function create$18(context) {
|
|
2818
|
+
const { compilationMode, version } = getSettingsFromContext(context);
|
|
2819
|
+
if (compilationMode === "infer" || compilationMode === "all") return {};
|
|
2820
|
+
if (compilationMode === "annotation" && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
|
|
2793
2821
|
const isReact18OrBelow = compare(version, "19.0.0", "<");
|
|
2794
2822
|
const { ctx, visitor } = core.useComponentCollector(context);
|
|
2795
2823
|
const constructions = /* @__PURE__ */ new WeakMap();
|
|
@@ -2800,7 +2828,7 @@ function create$15(context) {
|
|
|
2800
2828
|
if (!isContextName(selfName, isReact18OrBelow)) return;
|
|
2801
2829
|
const functionEntry = ctx.getCurrentEntry();
|
|
2802
2830
|
if (functionEntry == null) return;
|
|
2803
|
-
if (
|
|
2831
|
+
if (compilationMode === "annotation" && ast.isDirectiveInFunction(functionEntry.node, "use memo")) return;
|
|
2804
2832
|
const attribute = node.attributes.find((attribute) => attribute.type === AST_NODE_TYPES.JSXAttribute && attribute.name.name === "value");
|
|
2805
2833
|
if (attribute == null || !("value" in attribute)) return;
|
|
2806
2834
|
const value = attribute.value;
|
|
@@ -2812,18 +2840,20 @@ function create$15(context) {
|
|
|
2812
2840
|
getOrElseUpdate(constructions, functionEntry.node, () => []).push(construction);
|
|
2813
2841
|
},
|
|
2814
2842
|
"Program:exit"(program) {
|
|
2815
|
-
for (const { node: component, directives } of ctx.getAllComponents(program))
|
|
2816
|
-
if (directives.some((d) => d.directive === "use memo"))
|
|
2817
|
-
const
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2843
|
+
for (const { node: component, directives } of ctx.getAllComponents(program)) {
|
|
2844
|
+
if (compilationMode === "annotation" && directives.some((d) => d.directive === "use memo")) continue;
|
|
2845
|
+
for (const construction of constructions.get(component) ?? []) {
|
|
2846
|
+
const { kind, node: constructionNode } = construction;
|
|
2847
|
+
const suggestion = kind === "function" ? "Consider wrapping it in a useCallback hook." : "Consider wrapping it in a useMemo hook.";
|
|
2848
|
+
context.report({
|
|
2849
|
+
messageId: "unstableContextValue",
|
|
2850
|
+
node: constructionNode,
|
|
2851
|
+
data: {
|
|
2852
|
+
kind: ast.getHumanReadableKind(constructionNode),
|
|
2853
|
+
suggestion
|
|
2854
|
+
}
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2827
2857
|
}
|
|
2828
2858
|
}
|
|
2829
2859
|
});
|
|
@@ -2836,9 +2866,9 @@ function isContextName(name, isReact18OrBelow) {
|
|
|
2836
2866
|
|
|
2837
2867
|
//#endregion
|
|
2838
2868
|
//#region src/rules/no-unstable-default-props.ts
|
|
2839
|
-
const RULE_NAME$
|
|
2840
|
-
const defaultOptions$
|
|
2841
|
-
const schema$
|
|
2869
|
+
const RULE_NAME$17 = "no-unstable-default-props";
|
|
2870
|
+
const defaultOptions$2 = [{ safeDefaultProps: [] }];
|
|
2871
|
+
const schema$2 = [{
|
|
2842
2872
|
type: "object",
|
|
2843
2873
|
additionalProperties: false,
|
|
2844
2874
|
properties: { safeDefaultProps: {
|
|
@@ -2851,11 +2881,11 @@ var no_unstable_default_props_default = createRule({
|
|
|
2851
2881
|
type: "problem",
|
|
2852
2882
|
docs: { description: "Prevents using referential-type values as default props in object destructuring." },
|
|
2853
2883
|
messages: { default: "A/an '{{kind}}' as default prop. This could lead to potential infinite render loop in React. Use a variable instead of '{{kind}}'." },
|
|
2854
|
-
schema: schema$
|
|
2884
|
+
schema: schema$2
|
|
2855
2885
|
},
|
|
2856
|
-
name: RULE_NAME$
|
|
2857
|
-
create: create$
|
|
2858
|
-
defaultOptions: defaultOptions$
|
|
2886
|
+
name: RULE_NAME$17,
|
|
2887
|
+
create: create$17,
|
|
2888
|
+
defaultOptions: defaultOptions$2
|
|
2859
2889
|
});
|
|
2860
2890
|
function extractIdentifier(node) {
|
|
2861
2891
|
if (node.type === AST_NODE_TYPES.NewExpression && node.callee.type === AST_NODE_TYPES.Identifier) return node.callee.name;
|
|
@@ -2865,9 +2895,10 @@ function extractIdentifier(node) {
|
|
|
2865
2895
|
}
|
|
2866
2896
|
return null;
|
|
2867
2897
|
}
|
|
2868
|
-
function create$
|
|
2869
|
-
const {
|
|
2870
|
-
if (
|
|
2898
|
+
function create$17(context, [options]) {
|
|
2899
|
+
const { compilationMode } = getSettingsFromContext(context);
|
|
2900
|
+
if (compilationMode === "infer" || compilationMode === "all") return {};
|
|
2901
|
+
if (compilationMode === "annotation" && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
|
|
2871
2902
|
const { ctx, visitor } = core.useComponentCollector(context);
|
|
2872
2903
|
const declarators = /* @__PURE__ */ new WeakMap();
|
|
2873
2904
|
const { safeDefaultProps = [] } = options;
|
|
@@ -2910,7 +2941,7 @@ function create$14(context, [options]) {
|
|
|
2910
2941
|
|
|
2911
2942
|
//#endregion
|
|
2912
2943
|
//#region src/rules/no-unused-class-component-members.ts
|
|
2913
|
-
const RULE_NAME$
|
|
2944
|
+
const RULE_NAME$16 = "no-unused-class-component-members";
|
|
2914
2945
|
const LIFECYCLE_METHODS = new Set([
|
|
2915
2946
|
"componentDidCatch",
|
|
2916
2947
|
"componentDidMount",
|
|
@@ -2941,11 +2972,11 @@ var no_unused_class_component_members_default = createRule({
|
|
|
2941
2972
|
messages: { default: "Unused method or property '{{methodName}}'' of class '{{className}}'." },
|
|
2942
2973
|
schema: []
|
|
2943
2974
|
},
|
|
2944
|
-
name: RULE_NAME$
|
|
2945
|
-
create: create$
|
|
2975
|
+
name: RULE_NAME$16,
|
|
2976
|
+
create: create$16,
|
|
2946
2977
|
defaultOptions: []
|
|
2947
2978
|
});
|
|
2948
|
-
function create$
|
|
2979
|
+
function create$16(context) {
|
|
2949
2980
|
const classStack = [];
|
|
2950
2981
|
const methodStack = [];
|
|
2951
2982
|
const propertyDefs = /* @__PURE__ */ new WeakMap();
|
|
@@ -2987,7 +3018,7 @@ function create$13(context) {
|
|
|
2987
3018
|
function methodExit() {
|
|
2988
3019
|
methodStack.pop();
|
|
2989
3020
|
}
|
|
2990
|
-
return {
|
|
3021
|
+
return defineRuleListener({
|
|
2991
3022
|
ClassDeclaration: classEnter,
|
|
2992
3023
|
"ClassDeclaration:exit": classExit,
|
|
2993
3024
|
ClassExpression: classEnter,
|
|
@@ -3021,12 +3052,12 @@ function create$13(context) {
|
|
|
3021
3052
|
}
|
|
3022
3053
|
}
|
|
3023
3054
|
}
|
|
3024
|
-
};
|
|
3055
|
+
});
|
|
3025
3056
|
}
|
|
3026
3057
|
|
|
3027
3058
|
//#endregion
|
|
3028
3059
|
//#region src/rules/no-unused-props.ts
|
|
3029
|
-
const RULE_NAME$
|
|
3060
|
+
const RULE_NAME$15 = "no-unused-props";
|
|
3030
3061
|
var no_unused_props_default = createRule({
|
|
3031
3062
|
meta: {
|
|
3032
3063
|
type: "problem",
|
|
@@ -3034,15 +3065,15 @@ var no_unused_props_default = createRule({
|
|
|
3034
3065
|
messages: { default: "Prop `{{name}}` is declared but never used" },
|
|
3035
3066
|
schema: []
|
|
3036
3067
|
},
|
|
3037
|
-
name: RULE_NAME$
|
|
3038
|
-
create: create$
|
|
3068
|
+
name: RULE_NAME$15,
|
|
3069
|
+
create: create$15,
|
|
3039
3070
|
defaultOptions: []
|
|
3040
3071
|
});
|
|
3041
|
-
function create$
|
|
3072
|
+
function create$15(context) {
|
|
3042
3073
|
const services = ESLintUtils.getParserServices(context, false);
|
|
3074
|
+
const checker = services.program.getTypeChecker();
|
|
3043
3075
|
const { ctx, visitor } = core.useComponentCollector(context);
|
|
3044
3076
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
3045
|
-
const checker = services.program.getTypeChecker();
|
|
3046
3077
|
const totalDeclaredProps = /* @__PURE__ */ new Set();
|
|
3047
3078
|
const totalUsedProps = /* @__PURE__ */ new Set();
|
|
3048
3079
|
for (const component of ctx.getAllComponents(program)) {
|
|
@@ -3117,7 +3148,9 @@ function collectUsedPropKeysOfReference(context, usedPropKeys, identifier, ref)
|
|
|
3117
3148
|
function getKeyOfExpression(expr) {
|
|
3118
3149
|
switch (expr.type) {
|
|
3119
3150
|
case AST_NODE_TYPES.Identifier: return expr.name;
|
|
3120
|
-
case AST_NODE_TYPES.Literal:
|
|
3151
|
+
case AST_NODE_TYPES.Literal:
|
|
3152
|
+
if (typeof expr.value === "string") return expr.value;
|
|
3153
|
+
break;
|
|
3121
3154
|
}
|
|
3122
3155
|
return null;
|
|
3123
3156
|
}
|
|
@@ -3136,7 +3169,7 @@ function reportUnusedProp(context, services, prop) {
|
|
|
3136
3169
|
|
|
3137
3170
|
//#endregion
|
|
3138
3171
|
//#region src/rules/no-unused-state.ts
|
|
3139
|
-
const RULE_NAME$
|
|
3172
|
+
const RULE_NAME$14 = "no-unused-state";
|
|
3140
3173
|
function isKeyLiteral(node, key) {
|
|
3141
3174
|
return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
|
|
3142
3175
|
type: AST_NODE_TYPES.TemplateLiteral,
|
|
@@ -3150,11 +3183,11 @@ var no_unused_state_default = createRule({
|
|
|
3150
3183
|
messages: { default: "Unused class component state in '{{className}}'" },
|
|
3151
3184
|
schema: []
|
|
3152
3185
|
},
|
|
3153
|
-
name: RULE_NAME$
|
|
3154
|
-
create: create$
|
|
3186
|
+
name: RULE_NAME$14,
|
|
3187
|
+
create: create$14,
|
|
3155
3188
|
defaultOptions: []
|
|
3156
3189
|
});
|
|
3157
|
-
function create$
|
|
3190
|
+
function create$14(context) {
|
|
3158
3191
|
const classStack = [];
|
|
3159
3192
|
const methodStack = [];
|
|
3160
3193
|
const constructorStack = [];
|
|
@@ -3202,7 +3235,7 @@ function create$11(context) {
|
|
|
3202
3235
|
function constructorExit() {
|
|
3203
3236
|
constructorStack.pop();
|
|
3204
3237
|
}
|
|
3205
|
-
return {
|
|
3238
|
+
return defineRuleListener({
|
|
3206
3239
|
AssignmentExpression(node) {
|
|
3207
3240
|
if (!core.isAssignmentToThisState(node)) return;
|
|
3208
3241
|
const currentClass = classStack.at(-1);
|
|
@@ -3258,12 +3291,12 @@ function create$11(context) {
|
|
|
3258
3291
|
isUsed: true
|
|
3259
3292
|
});
|
|
3260
3293
|
}
|
|
3261
|
-
};
|
|
3294
|
+
});
|
|
3262
3295
|
}
|
|
3263
3296
|
|
|
3264
3297
|
//#endregion
|
|
3265
3298
|
//#region src/rules/no-use-context.ts
|
|
3266
|
-
const RULE_NAME$
|
|
3299
|
+
const RULE_NAME$13 = "no-use-context";
|
|
3267
3300
|
var no_use_context_default = createRule({
|
|
3268
3301
|
meta: {
|
|
3269
3302
|
type: "problem",
|
|
@@ -3272,16 +3305,16 @@ var no_use_context_default = createRule({
|
|
|
3272
3305
|
messages: { default: "In React 19, 'use' is preferred over 'useContext' because it is more flexible." },
|
|
3273
3306
|
schema: []
|
|
3274
3307
|
},
|
|
3275
|
-
name: RULE_NAME$
|
|
3276
|
-
create: create$
|
|
3308
|
+
name: RULE_NAME$13,
|
|
3309
|
+
create: create$13,
|
|
3277
3310
|
defaultOptions: []
|
|
3278
3311
|
});
|
|
3279
|
-
function create$
|
|
3312
|
+
function create$13(context) {
|
|
3280
3313
|
if (!context.sourceCode.text.includes("useContext")) return {};
|
|
3281
3314
|
const settings = getSettingsFromContext(context);
|
|
3282
3315
|
if (compare(settings.version, "19.0.0", "<")) return {};
|
|
3283
3316
|
const hookCalls = /* @__PURE__ */ new Set();
|
|
3284
|
-
return {
|
|
3317
|
+
return defineRuleListener({
|
|
3285
3318
|
CallExpression(node) {
|
|
3286
3319
|
if (!core.isHookCall(node)) return;
|
|
3287
3320
|
hookCalls.add(node);
|
|
@@ -3328,7 +3361,7 @@ function create$10(context) {
|
|
|
3328
3361
|
});
|
|
3329
3362
|
}
|
|
3330
3363
|
}
|
|
3331
|
-
};
|
|
3364
|
+
});
|
|
3332
3365
|
}
|
|
3333
3366
|
function getCorrelativeTokens(context, node) {
|
|
3334
3367
|
const tokenBefore = context.sourceCode.getTokenBefore(node);
|
|
@@ -3341,7 +3374,7 @@ function getCorrelativeTokens(context, node) {
|
|
|
3341
3374
|
|
|
3342
3375
|
//#endregion
|
|
3343
3376
|
//#region src/rules/no-useless-forward-ref.ts
|
|
3344
|
-
const RULE_NAME$
|
|
3377
|
+
const RULE_NAME$12 = "no-useless-forward-ref";
|
|
3345
3378
|
var no_useless_forward_ref_default = createRule({
|
|
3346
3379
|
meta: {
|
|
3347
3380
|
type: "problem",
|
|
@@ -3349,12 +3382,12 @@ var no_useless_forward_ref_default = createRule({
|
|
|
3349
3382
|
messages: { default: "A 'forwardRef' is used with this component but no 'ref' parameter is set." },
|
|
3350
3383
|
schema: []
|
|
3351
3384
|
},
|
|
3352
|
-
name: RULE_NAME$
|
|
3353
|
-
create: create$
|
|
3385
|
+
name: RULE_NAME$12,
|
|
3386
|
+
create: create$12,
|
|
3354
3387
|
defaultOptions: []
|
|
3355
3388
|
});
|
|
3356
|
-
function create$
|
|
3357
|
-
return { CallExpression(node) {
|
|
3389
|
+
function create$12(context) {
|
|
3390
|
+
return defineRuleListener({ CallExpression(node) {
|
|
3358
3391
|
if (!core.isForwardRefCall(context, node)) return;
|
|
3359
3392
|
const [component] = node.arguments;
|
|
3360
3393
|
if (component == null || !ast.isFunction(component)) return;
|
|
@@ -3363,17 +3396,17 @@ function create$9(context) {
|
|
|
3363
3396
|
messageId: "default",
|
|
3364
3397
|
node: node.callee
|
|
3365
3398
|
});
|
|
3366
|
-
} };
|
|
3399
|
+
} });
|
|
3367
3400
|
}
|
|
3368
3401
|
|
|
3369
3402
|
//#endregion
|
|
3370
3403
|
//#region src/rules/no-useless-fragment.ts
|
|
3371
|
-
const RULE_NAME$
|
|
3372
|
-
const defaultOptions = [{
|
|
3404
|
+
const RULE_NAME$11 = "no-useless-fragment";
|
|
3405
|
+
const defaultOptions$1 = [{
|
|
3373
3406
|
allowEmptyFragment: false,
|
|
3374
3407
|
allowExpressions: true
|
|
3375
3408
|
}];
|
|
3376
|
-
const schema = [{
|
|
3409
|
+
const schema$1 = [{
|
|
3377
3410
|
type: "object",
|
|
3378
3411
|
additionalProperties: false,
|
|
3379
3412
|
properties: {
|
|
@@ -3390,17 +3423,17 @@ const schema = [{
|
|
|
3390
3423
|
var no_useless_fragment_default = createRule({
|
|
3391
3424
|
meta: {
|
|
3392
3425
|
type: "problem",
|
|
3393
|
-
defaultOptions: [...defaultOptions],
|
|
3426
|
+
defaultOptions: [...defaultOptions$1],
|
|
3394
3427
|
docs: { description: "Disallows useless fragment elements." },
|
|
3395
3428
|
fixable: "code",
|
|
3396
3429
|
messages: { default: "A fragment {{reason}} is useless." },
|
|
3397
|
-
schema
|
|
3430
|
+
schema: schema$1
|
|
3398
3431
|
},
|
|
3399
|
-
name: RULE_NAME$
|
|
3400
|
-
create: create$
|
|
3401
|
-
defaultOptions
|
|
3432
|
+
name: RULE_NAME$11,
|
|
3433
|
+
create: create$11,
|
|
3434
|
+
defaultOptions: defaultOptions$1
|
|
3402
3435
|
});
|
|
3403
|
-
function create$
|
|
3436
|
+
function create$11(context, [option]) {
|
|
3404
3437
|
const { allowEmptyFragment = false, allowExpressions = true } = option;
|
|
3405
3438
|
const jsxConfig = {
|
|
3406
3439
|
...core.getJsxConfigFromContext(context),
|
|
@@ -3473,7 +3506,7 @@ function create$8(context, [option]) {
|
|
|
3473
3506
|
if (node.children.length === 0) return false;
|
|
3474
3507
|
return !node.children.some((child) => core.isJsxText(child) && !isWhiteSpace(child) || ast.is(AST_NODE_TYPES.JSXExpressionContainer)(child));
|
|
3475
3508
|
}
|
|
3476
|
-
return {
|
|
3509
|
+
return defineRuleListener({
|
|
3477
3510
|
JSXElement(node) {
|
|
3478
3511
|
if (!core.isJsxFragmentElement(context, node, jsxConfig)) return;
|
|
3479
3512
|
checkNode(context, node);
|
|
@@ -3481,7 +3514,7 @@ function create$8(context, [option]) {
|
|
|
3481
3514
|
JSXFragment(node) {
|
|
3482
3515
|
checkNode(context, node);
|
|
3483
3516
|
}
|
|
3484
|
-
};
|
|
3517
|
+
});
|
|
3485
3518
|
}
|
|
3486
3519
|
/**
|
|
3487
3520
|
* Check if a Literal or JSXText node is whitespace
|
|
@@ -3508,7 +3541,7 @@ function trimLikeReact(text) {
|
|
|
3508
3541
|
|
|
3509
3542
|
//#endregion
|
|
3510
3543
|
//#region src/rules/prefer-destructuring-assignment.ts
|
|
3511
|
-
const RULE_NAME$
|
|
3544
|
+
const RULE_NAME$10 = "prefer-destructuring-assignment";
|
|
3512
3545
|
var prefer_destructuring_assignment_default = createRule({
|
|
3513
3546
|
meta: {
|
|
3514
3547
|
type: "problem",
|
|
@@ -3516,11 +3549,11 @@ var prefer_destructuring_assignment_default = createRule({
|
|
|
3516
3549
|
messages: { default: "Use destructuring assignment for component props." },
|
|
3517
3550
|
schema: []
|
|
3518
3551
|
},
|
|
3519
|
-
name: RULE_NAME$
|
|
3520
|
-
create: create$
|
|
3552
|
+
name: RULE_NAME$10,
|
|
3553
|
+
create: create$10,
|
|
3521
3554
|
defaultOptions: []
|
|
3522
3555
|
});
|
|
3523
|
-
function create$
|
|
3556
|
+
function create$10(context) {
|
|
3524
3557
|
const { ctx, visitor } = core.useComponentCollector(context);
|
|
3525
3558
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
3526
3559
|
for (const component of ctx.getAllComponents(program)) {
|
|
@@ -3544,7 +3577,7 @@ function create$7(context) {
|
|
|
3544
3577
|
|
|
3545
3578
|
//#endregion
|
|
3546
3579
|
//#region src/rules/prefer-namespace-import.ts
|
|
3547
|
-
const RULE_NAME$
|
|
3580
|
+
const RULE_NAME$9 = "prefer-namespace-import";
|
|
3548
3581
|
var prefer_namespace_import_default = createRule({
|
|
3549
3582
|
meta: {
|
|
3550
3583
|
type: "problem",
|
|
@@ -3553,13 +3586,13 @@ var prefer_namespace_import_default = createRule({
|
|
|
3553
3586
|
messages: { default: "Prefer importing React as 'import * as React from \"{{importSource}}\"';" },
|
|
3554
3587
|
schema: []
|
|
3555
3588
|
},
|
|
3556
|
-
name: RULE_NAME$
|
|
3557
|
-
create: create$
|
|
3589
|
+
name: RULE_NAME$9,
|
|
3590
|
+
create: create$9,
|
|
3558
3591
|
defaultOptions: []
|
|
3559
3592
|
});
|
|
3560
|
-
function create$
|
|
3593
|
+
function create$9(context) {
|
|
3561
3594
|
const { importSource } = getSettingsFromContext(context);
|
|
3562
|
-
return { [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
|
|
3595
|
+
return defineRuleListener({ [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
|
|
3563
3596
|
const hasOtherSpecifiers = node.parent.specifiers.length > 1;
|
|
3564
3597
|
context.report({
|
|
3565
3598
|
messageId: "default",
|
|
@@ -3576,12 +3609,12 @@ function create$6(context) {
|
|
|
3576
3609
|
return fixer.replaceText(node.parent, [`${importStringPrefix} * as ${node.local.name} from ${importSourceQuoted}${semi}`, `${importStringPrefix} ${specifiers} from ${importSourceQuoted}${semi}`].join("\n"));
|
|
3577
3610
|
}
|
|
3578
3611
|
});
|
|
3579
|
-
} };
|
|
3612
|
+
} });
|
|
3580
3613
|
}
|
|
3581
3614
|
|
|
3582
3615
|
//#endregion
|
|
3583
3616
|
//#region src/rules/prefer-read-only-props.ts
|
|
3584
|
-
const RULE_NAME$
|
|
3617
|
+
const RULE_NAME$8 = "prefer-read-only-props";
|
|
3585
3618
|
var prefer_read_only_props_default = createRule({
|
|
3586
3619
|
meta: {
|
|
3587
3620
|
type: "problem",
|
|
@@ -3589,11 +3622,11 @@ var prefer_read_only_props_default = createRule({
|
|
|
3589
3622
|
messages: { default: "A function component's props should be read-only." },
|
|
3590
3623
|
schema: []
|
|
3591
3624
|
},
|
|
3592
|
-
name: RULE_NAME$
|
|
3593
|
-
create: create$
|
|
3625
|
+
name: RULE_NAME$8,
|
|
3626
|
+
create: create$8,
|
|
3594
3627
|
defaultOptions: []
|
|
3595
3628
|
});
|
|
3596
|
-
function create$
|
|
3629
|
+
function create$8(context) {
|
|
3597
3630
|
const services = ESLintUtils.getParserServices(context, false);
|
|
3598
3631
|
const checker = services.program.getTypeChecker();
|
|
3599
3632
|
const { ctx, visitor } = core.useComponentCollector(context);
|
|
@@ -3632,55 +3665,9 @@ function isClassOrInterfaceReadonlyLoose(checker, type) {
|
|
|
3632
3665
|
});
|
|
3633
3666
|
}
|
|
3634
3667
|
|
|
3635
|
-
//#endregion
|
|
3636
|
-
//#region src/rules/prefer-use-state-lazy-initialization.ts
|
|
3637
|
-
const RULE_NAME$4 = "prefer-use-state-lazy-initialization";
|
|
3638
|
-
const ALLOW_LIST = [
|
|
3639
|
-
"Boolean",
|
|
3640
|
-
"String",
|
|
3641
|
-
"Number"
|
|
3642
|
-
];
|
|
3643
|
-
var prefer_use_state_lazy_initialization_default = createRule({
|
|
3644
|
-
meta: {
|
|
3645
|
-
type: "problem",
|
|
3646
|
-
docs: { description: "Enforces wrapping function calls made inside 'useState' in an 'initializer function'." },
|
|
3647
|
-
messages: { default: "To prevent re-computation, consider using lazy initial state for useState calls that involve function calls. Ex: 'useState(() => getValue())'." },
|
|
3648
|
-
schema: []
|
|
3649
|
-
},
|
|
3650
|
-
name: RULE_NAME$4,
|
|
3651
|
-
create: create$4,
|
|
3652
|
-
defaultOptions: []
|
|
3653
|
-
});
|
|
3654
|
-
function create$4(context) {
|
|
3655
|
-
return { CallExpression(node) {
|
|
3656
|
-
if (!core.isUseStateCall(node)) return;
|
|
3657
|
-
const [useStateInput] = node.arguments;
|
|
3658
|
-
if (useStateInput == null) return;
|
|
3659
|
-
for (const expr of ast.getNestedNewExpressions(useStateInput)) {
|
|
3660
|
-
if (!("name" in expr.callee)) continue;
|
|
3661
|
-
if (ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
3662
|
-
if (ast.findParentNode(expr, core.isUseCall) != null) continue;
|
|
3663
|
-
context.report({
|
|
3664
|
-
messageId: "default",
|
|
3665
|
-
node: expr
|
|
3666
|
-
});
|
|
3667
|
-
}
|
|
3668
|
-
for (const expr of ast.getNestedCallExpressions(useStateInput)) {
|
|
3669
|
-
if (!("name" in expr.callee)) continue;
|
|
3670
|
-
if (core.isHookName(expr.callee.name)) continue;
|
|
3671
|
-
if (ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
3672
|
-
if (ast.findParentNode(expr, core.isUseCall) != null) continue;
|
|
3673
|
-
context.report({
|
|
3674
|
-
messageId: "default",
|
|
3675
|
-
node: expr
|
|
3676
|
-
});
|
|
3677
|
-
}
|
|
3678
|
-
} };
|
|
3679
|
-
}
|
|
3680
|
-
|
|
3681
3668
|
//#endregion
|
|
3682
3669
|
//#region src/rules/purity.ts
|
|
3683
|
-
const RULE_NAME$
|
|
3670
|
+
const RULE_NAME$7 = "purity";
|
|
3684
3671
|
function isImpureMemberCall(node) {
|
|
3685
3672
|
if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
|
|
3686
3673
|
const { object, property } = node.callee;
|
|
@@ -3712,11 +3699,11 @@ var purity_default = createRule({
|
|
|
3712
3699
|
messages: { default: "Do not call '{{name}}' during render. Components and hooks must be pure. Move this call into an event handler, effect, or state initializer." },
|
|
3713
3700
|
schema: []
|
|
3714
3701
|
},
|
|
3715
|
-
name: RULE_NAME$
|
|
3716
|
-
create: create$
|
|
3702
|
+
name: RULE_NAME$7,
|
|
3703
|
+
create: create$7,
|
|
3717
3704
|
defaultOptions: []
|
|
3718
3705
|
});
|
|
3719
|
-
function create$
|
|
3706
|
+
function create$7(context) {
|
|
3720
3707
|
const hCollector = core.useHookCollector(context);
|
|
3721
3708
|
const cCollector = core.useComponentCollector(context);
|
|
3722
3709
|
const cExprs = [];
|
|
@@ -3762,9 +3749,188 @@ function create$3(context) {
|
|
|
3762
3749
|
});
|
|
3763
3750
|
}
|
|
3764
3751
|
|
|
3752
|
+
//#endregion
|
|
3753
|
+
//#region src/rules/refs.ts
|
|
3754
|
+
const RULE_NAME$6 = "refs";
|
|
3755
|
+
function isWriteAccess(node) {
|
|
3756
|
+
const { parent } = node;
|
|
3757
|
+
if (parent.type === AST_NODE_TYPES.AssignmentExpression && parent.left === node) return true;
|
|
3758
|
+
if (parent.type === AST_NODE_TYPES.UpdateExpression && parent.argument === node) return true;
|
|
3759
|
+
return false;
|
|
3760
|
+
}
|
|
3761
|
+
function isInsideNestedFunction(node, boundary) {
|
|
3762
|
+
let current = node.parent;
|
|
3763
|
+
while (current != null && current !== boundary) {
|
|
3764
|
+
if (ast.isFunction(current)) return true;
|
|
3765
|
+
current = current.parent;
|
|
3766
|
+
}
|
|
3767
|
+
return false;
|
|
3768
|
+
}
|
|
3769
|
+
/**
|
|
3770
|
+
* Check if a ref.current access is part of a lazy initialization pattern.
|
|
3771
|
+
*
|
|
3772
|
+
* Standard:
|
|
3773
|
+
* if (ref.current === null) { ref.current = value; }
|
|
3774
|
+
*
|
|
3775
|
+
* Inverted (with early return):
|
|
3776
|
+
* if (ref.current !== null) { return ...; }
|
|
3777
|
+
* ref.current = computeValue();
|
|
3778
|
+
* @param node The MemberExpression node for ref.current
|
|
3779
|
+
* @param isWrite Whether this access is a write (assignment/update) or a read
|
|
3780
|
+
* @returns true if this access is part of a lazy initialization pattern and should be allowed during render
|
|
3781
|
+
*/
|
|
3782
|
+
function isPartOfLazyInitialization(node, isWrite) {
|
|
3783
|
+
if (node.object.type !== AST_NODE_TYPES.Identifier) return false;
|
|
3784
|
+
const refName = node.object.name;
|
|
3785
|
+
if (isInNullCheckTest(node)) return true;
|
|
3786
|
+
if (findEnclosingRefNullCheckIf(node, refName) != null) return true;
|
|
3787
|
+
if (isWrite && isWriteAfterNullCheckIf(node, refName)) return true;
|
|
3788
|
+
return false;
|
|
3789
|
+
}
|
|
3790
|
+
function isNullCheckOperator(operator) {
|
|
3791
|
+
return operator === "===" || operator === "==" || operator === "!==" || operator === "!=";
|
|
3792
|
+
}
|
|
3793
|
+
/**
|
|
3794
|
+
* Check if a test expression is a null check on `ref.current` for a given ref name.
|
|
3795
|
+
* @param test The test expression to check
|
|
3796
|
+
* @param refName The name of the ref variable (e.g. "myRef") to check against
|
|
3797
|
+
* @returns true if the test is of the form `ref.current === null` or `null === ref.current`
|
|
3798
|
+
*/
|
|
3799
|
+
function isRefCurrentNullCheck(test, refName) {
|
|
3800
|
+
if (test.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
3801
|
+
if (!isNullCheckOperator(test.operator)) return false;
|
|
3802
|
+
const { left, right } = test;
|
|
3803
|
+
const isRefSide = (side) => side.type === AST_NODE_TYPES.MemberExpression && side.object.type === AST_NODE_TYPES.Identifier && side.object.name === refName && side.property.type === AST_NODE_TYPES.Identifier && side.property.name === "current";
|
|
3804
|
+
const isNullSide = (side) => side.type === AST_NODE_TYPES.Literal && side.value == null;
|
|
3805
|
+
return isRefSide(left) && isNullSide(right) || isRefSide(right) && isNullSide(left);
|
|
3806
|
+
}
|
|
3807
|
+
/**
|
|
3808
|
+
* Check if the node is the operand of a `ref.current === null` test inside an IfStatement.
|
|
3809
|
+
* @param node The MemberExpression node for ref.current
|
|
3810
|
+
* @returns true if the node is part of a null check test in an if statement
|
|
3811
|
+
*/
|
|
3812
|
+
function isInNullCheckTest(node) {
|
|
3813
|
+
const { parent } = node;
|
|
3814
|
+
if (parent.type !== AST_NODE_TYPES.BinaryExpression) return false;
|
|
3815
|
+
if (!isNullCheckOperator(parent.operator)) return false;
|
|
3816
|
+
const otherSide = parent.left === node ? parent.right : parent.left;
|
|
3817
|
+
if (otherSide.type !== AST_NODE_TYPES.Literal || otherSide.value != null) return false;
|
|
3818
|
+
return parent.parent.type === AST_NODE_TYPES.IfStatement && parent.parent.test === parent;
|
|
3819
|
+
}
|
|
3820
|
+
/**
|
|
3821
|
+
* Walk up from the node to find a containing IfStatement whose test is a null-check
|
|
3822
|
+
* on `ref.current` with the given ref name.
|
|
3823
|
+
* @param node The MemberExpression node for ref.current
|
|
3824
|
+
* @param refName The name of the ref variable (e.g. "myRef") to check against
|
|
3825
|
+
* @returns the enclosing IfStatement node if found, or null if not found
|
|
3826
|
+
*/
|
|
3827
|
+
function findEnclosingRefNullCheckIf(node, refName) {
|
|
3828
|
+
let current = node.parent;
|
|
3829
|
+
while (current != null) {
|
|
3830
|
+
if (current.type === AST_NODE_TYPES.IfStatement) return isRefCurrentNullCheck(current.test, refName) ? current : null;
|
|
3831
|
+
switch (current.type) {
|
|
3832
|
+
case AST_NODE_TYPES.ExpressionStatement:
|
|
3833
|
+
case AST_NODE_TYPES.BlockStatement:
|
|
3834
|
+
case AST_NODE_TYPES.ReturnStatement:
|
|
3835
|
+
case AST_NODE_TYPES.JSXExpressionContainer:
|
|
3836
|
+
case AST_NODE_TYPES.JSXElement:
|
|
3837
|
+
case AST_NODE_TYPES.JSXOpeningElement:
|
|
3838
|
+
case AST_NODE_TYPES.JSXClosingElement:
|
|
3839
|
+
case AST_NODE_TYPES.AssignmentExpression:
|
|
3840
|
+
case AST_NODE_TYPES.VariableDeclaration:
|
|
3841
|
+
case AST_NODE_TYPES.VariableDeclarator:
|
|
3842
|
+
case AST_NODE_TYPES.MemberExpression:
|
|
3843
|
+
case AST_NODE_TYPES.ChainExpression:
|
|
3844
|
+
case AST_NODE_TYPES.CallExpression: break;
|
|
3845
|
+
default: return null;
|
|
3846
|
+
}
|
|
3847
|
+
current = current.parent;
|
|
3848
|
+
}
|
|
3849
|
+
return null;
|
|
3850
|
+
}
|
|
3851
|
+
/**
|
|
3852
|
+
* Check if a write to `ref.current` comes after a sibling if-statement that null-checks
|
|
3853
|
+
* the same ref (inverted lazy init with early return pattern):
|
|
3854
|
+
*
|
|
3855
|
+
* if (ref.current !== null) { return ...; }
|
|
3856
|
+
* ref.current = value; // ← this write
|
|
3857
|
+
* @param node The MemberExpression node for ref.current being written to
|
|
3858
|
+
* @param refName The name of the ref variable (e.g. "myRef") to check against
|
|
3859
|
+
* @returns true if there is a preceding sibling if-statement that null-checks the same ref
|
|
3860
|
+
*/
|
|
3861
|
+
function isWriteAfterNullCheckIf(node, refName) {
|
|
3862
|
+
let stmt = node;
|
|
3863
|
+
while (stmt.parent != null && stmt.parent.type !== AST_NODE_TYPES.BlockStatement) stmt = stmt.parent;
|
|
3864
|
+
if (stmt.parent?.type !== AST_NODE_TYPES.BlockStatement) return false;
|
|
3865
|
+
const block = stmt.parent;
|
|
3866
|
+
const stmtIdx = block.body.indexOf(stmt);
|
|
3867
|
+
if (stmtIdx < 0) return false;
|
|
3868
|
+
for (let i = stmtIdx - 1; i >= 0; i--) {
|
|
3869
|
+
const sibling = block.body[i];
|
|
3870
|
+
if (sibling == null) continue;
|
|
3871
|
+
if (sibling.type === AST_NODE_TYPES.IfStatement && isRefCurrentNullCheck(sibling.test, refName)) return true;
|
|
3872
|
+
}
|
|
3873
|
+
return false;
|
|
3874
|
+
}
|
|
3875
|
+
var refs_default = createRule({
|
|
3876
|
+
meta: {
|
|
3877
|
+
type: "problem",
|
|
3878
|
+
docs: { description: "Validates correct usage of refs by checking that 'ref.current' is not read or written during render." },
|
|
3879
|
+
messages: {
|
|
3880
|
+
readDuringRender: "Do not read 'ref.current' during render. Refs are not available during rendering and their values may be stale or inconsistent. Move this read into an effect or event handler.",
|
|
3881
|
+
writeDuringRender: "Do not write to 'ref.current' during render. Refs should only be mutated in effects or event handlers. Move this write into an effect or event handler."
|
|
3882
|
+
},
|
|
3883
|
+
schema: []
|
|
3884
|
+
},
|
|
3885
|
+
name: RULE_NAME$6,
|
|
3886
|
+
create: create$6,
|
|
3887
|
+
defaultOptions: []
|
|
3888
|
+
});
|
|
3889
|
+
function create$6(context) {
|
|
3890
|
+
const hCollector = core.useHookCollector(context);
|
|
3891
|
+
const cCollector = core.useComponentCollector(context);
|
|
3892
|
+
const refAccesses = [];
|
|
3893
|
+
const jsxRefIdentifiers = /* @__PURE__ */ new Set();
|
|
3894
|
+
function isRefIdentifier(node) {
|
|
3895
|
+
if (node.type !== AST_NODE_TYPES.Identifier) return false;
|
|
3896
|
+
if (core.isRefLikeName(node.name)) return true;
|
|
3897
|
+
if (jsxRefIdentifiers.has(node.name)) return true;
|
|
3898
|
+
return core.isInitializedFromRef(node.name, context.sourceCode.getScope(node));
|
|
3899
|
+
}
|
|
3900
|
+
return defineRuleListener(hCollector.visitor, cCollector.visitor, {
|
|
3901
|
+
JSXAttribute(node) {
|
|
3902
|
+
if (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) jsxRefIdentifiers.add(node.value.expression.name);
|
|
3903
|
+
},
|
|
3904
|
+
MemberExpression(node) {
|
|
3905
|
+
if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== "current") return;
|
|
3906
|
+
refAccesses.push({
|
|
3907
|
+
node,
|
|
3908
|
+
isWrite: isWriteAccess(node)
|
|
3909
|
+
});
|
|
3910
|
+
},
|
|
3911
|
+
"Program:exit"(program) {
|
|
3912
|
+
const components = cCollector.ctx.getAllComponents(program);
|
|
3913
|
+
const hooks = hCollector.ctx.getAllHooks(program);
|
|
3914
|
+
const componentAndHookFns = new Set([...components.map((c) => c.node), ...hooks.map((h) => h.node)]);
|
|
3915
|
+
const isComponentOrHookFn = (n) => ast.isFunction(n) && componentAndHookFns.has(n);
|
|
3916
|
+
for (const { node, isWrite } of refAccesses) {
|
|
3917
|
+
if (!isRefIdentifier(node.object)) continue;
|
|
3918
|
+
const boundary = ast.findParentNode(node, isComponentOrHookFn);
|
|
3919
|
+
if (boundary == null) continue;
|
|
3920
|
+
if (isInsideNestedFunction(node, boundary)) continue;
|
|
3921
|
+
if (isPartOfLazyInitialization(node, isWrite)) continue;
|
|
3922
|
+
context.report({
|
|
3923
|
+
messageId: isWrite ? "writeDuringRender" : "readDuringRender",
|
|
3924
|
+
node
|
|
3925
|
+
});
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
});
|
|
3929
|
+
}
|
|
3930
|
+
|
|
3765
3931
|
//#endregion
|
|
3766
3932
|
//#region src/rules/rules-of-hooks.ts
|
|
3767
|
-
const RULE_NAME$
|
|
3933
|
+
const RULE_NAME$5 = "rules-of-hooks";
|
|
3768
3934
|
var rules_of_hooks_default = createRule({
|
|
3769
3935
|
meta: {
|
|
3770
3936
|
type: "problem",
|
|
@@ -3782,8 +3948,8 @@ var rules_of_hooks_default = createRule({
|
|
|
3782
3948
|
},
|
|
3783
3949
|
schema: []
|
|
3784
3950
|
},
|
|
3785
|
-
name: RULE_NAME$
|
|
3786
|
-
create: create$
|
|
3951
|
+
name: RULE_NAME$5,
|
|
3952
|
+
create: create$5,
|
|
3787
3953
|
defaultOptions: []
|
|
3788
3954
|
});
|
|
3789
3955
|
function getHookName(node) {
|
|
@@ -3818,7 +3984,7 @@ function isLoopNode(node) {
|
|
|
3818
3984
|
function isTryCatchNode(node) {
|
|
3819
3985
|
return node.type === AST_NODE_TYPES.TryStatement;
|
|
3820
3986
|
}
|
|
3821
|
-
function create$
|
|
3987
|
+
function create$5(context) {
|
|
3822
3988
|
const functionStack = [];
|
|
3823
3989
|
function findEnclosingComponentOrHook() {
|
|
3824
3990
|
for (let i = functionStack.length - 1; i >= 0; i--) {
|
|
@@ -3826,6 +3992,7 @@ function create$2(context) {
|
|
|
3826
3992
|
if (entry == null) continue;
|
|
3827
3993
|
if (entry.kind === "component" || entry.kind === "hook") return entry;
|
|
3828
3994
|
}
|
|
3995
|
+
return unit;
|
|
3829
3996
|
}
|
|
3830
3997
|
function checkHookCall(node) {
|
|
3831
3998
|
const hookName = getHookName(node);
|
|
@@ -3934,7 +4101,7 @@ function create$2(context) {
|
|
|
3934
4101
|
return;
|
|
3935
4102
|
}
|
|
3936
4103
|
}
|
|
3937
|
-
return {
|
|
4104
|
+
return defineRuleListener({
|
|
3938
4105
|
":function"(node) {
|
|
3939
4106
|
const kind = getFunctionEntryKind(node);
|
|
3940
4107
|
functionStack.push({
|
|
@@ -3966,24 +4133,24 @@ function create$2(context) {
|
|
|
3966
4133
|
const idx = body.indexOf(stmt);
|
|
3967
4134
|
if (idx !== -1 && idx < body.length - 1) entry.hasEarlyReturn = true;
|
|
3968
4135
|
}
|
|
3969
|
-
};
|
|
4136
|
+
});
|
|
3970
4137
|
}
|
|
3971
4138
|
|
|
3972
4139
|
//#endregion
|
|
3973
4140
|
//#region src/rules/set-state-in-effect.ts
|
|
3974
|
-
const RULE_NAME$
|
|
4141
|
+
const RULE_NAME$4 = "set-state-in-effect";
|
|
3975
4142
|
var set_state_in_effect_default = createRule({
|
|
3976
4143
|
meta: {
|
|
3977
4144
|
type: "problem",
|
|
3978
|
-
docs: { description: "Validates against
|
|
4145
|
+
docs: { description: "Validates against setting state synchronously in an effect, which can lead to re-renders that degrade performance." },
|
|
3979
4146
|
messages: { default: "Do not call the 'set' function '{{name}}' of 'useState' synchronously in an effect. This can lead to unnecessary re-renders and performance issues." },
|
|
3980
4147
|
schema: []
|
|
3981
4148
|
},
|
|
3982
|
-
name: RULE_NAME$
|
|
3983
|
-
create: create$
|
|
4149
|
+
name: RULE_NAME$4,
|
|
4150
|
+
create: create$4,
|
|
3984
4151
|
defaultOptions: []
|
|
3985
4152
|
});
|
|
3986
|
-
function create$
|
|
4153
|
+
function create$4(context) {
|
|
3987
4154
|
if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
|
|
3988
4155
|
const { additionalStateHooks } = getSettingsFromContext(context);
|
|
3989
4156
|
const functionEntries = [];
|
|
@@ -4028,7 +4195,7 @@ function create$1(context) {
|
|
|
4028
4195
|
}
|
|
4029
4196
|
}
|
|
4030
4197
|
function isIdFromUseStateCall(topLevelId, at) {
|
|
4031
|
-
const variableNode =
|
|
4198
|
+
const variableNode = getVariableInitializer(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
|
|
4032
4199
|
if (variableNode == null) return false;
|
|
4033
4200
|
if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
4034
4201
|
if (!isUseStateCall(variableNode)) return false;
|
|
@@ -4056,7 +4223,18 @@ function create$1(context) {
|
|
|
4056
4223
|
default: return false;
|
|
4057
4224
|
}
|
|
4058
4225
|
}
|
|
4059
|
-
|
|
4226
|
+
function isHookDecl(node) {
|
|
4227
|
+
if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
|
|
4228
|
+
if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
|
|
4229
|
+
const init = node.init;
|
|
4230
|
+
if (init == null || init.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
4231
|
+
switch (init.callee.type) {
|
|
4232
|
+
case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
|
|
4233
|
+
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
|
|
4234
|
+
default: return false;
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
return defineRuleListener({
|
|
4060
4238
|
":function"(node) {
|
|
4061
4239
|
const kind = getFunctionKind(node);
|
|
4062
4240
|
functionEntries.push({
|
|
@@ -4079,15 +4257,31 @@ function create$1(context) {
|
|
|
4079
4257
|
case entry.kind === "deferred":
|
|
4080
4258
|
case entry.node.async: break;
|
|
4081
4259
|
case entry.node === setupFunction:
|
|
4082
|
-
case entry.kind === "immediate" && ast.findParentNode(entry.node, ast.isFunction) === setupFunction:
|
|
4260
|
+
case entry.kind === "immediate" && ast.findParentNode(entry.node, ast.isFunction) === setupFunction: {
|
|
4261
|
+
const args0 = node.arguments.at(0);
|
|
4262
|
+
if (args0 == null) return;
|
|
4263
|
+
function isArgumentUsingRefValue(context, node) {
|
|
4264
|
+
const isUsingRefValue = (n) => {
|
|
4265
|
+
switch (n.type) {
|
|
4266
|
+
case AST_NODE_TYPES.Identifier: return core.isInitializedFromRef(n.name, context.sourceCode.getScope(n));
|
|
4267
|
+
case AST_NODE_TYPES.MemberExpression: return isUsingRefValue(n.object);
|
|
4268
|
+
case AST_NODE_TYPES.CallExpression: return isUsingRefValue(n.callee) || ast.getNestedIdentifiers(n).some(isUsingRefValue);
|
|
4269
|
+
default: return false;
|
|
4270
|
+
}
|
|
4271
|
+
};
|
|
4272
|
+
if (isUsingRefValue(node)) return true;
|
|
4273
|
+
return ast.isFunction(node) && context.sourceCode.getScope(node.body).references.some((r) => isUsingRefValue(r.identifier));
|
|
4274
|
+
}
|
|
4275
|
+
if (isArgumentUsingRefValue(context, args0)) return;
|
|
4083
4276
|
context.report({
|
|
4084
4277
|
messageId: "default",
|
|
4085
4278
|
node,
|
|
4086
4279
|
data: { name: context.sourceCode.getText(node.callee) }
|
|
4087
4280
|
});
|
|
4088
4281
|
return;
|
|
4282
|
+
}
|
|
4089
4283
|
default: {
|
|
4090
|
-
const init = ast.findParentNode(node,
|
|
4284
|
+
const init = ast.findParentNode(node, isHookDecl)?.init;
|
|
4091
4285
|
if (init == null) getOrElseUpdate(setStateCallsByFn, entry.node, () => []).push(node);
|
|
4092
4286
|
else getOrElseUpdate(setStateInHookCallbacks, init, () => []).push(node);
|
|
4093
4287
|
}
|
|
@@ -4108,14 +4302,14 @@ function create$1(context) {
|
|
|
4108
4302
|
const parent = node.parent.parent;
|
|
4109
4303
|
if (parent.type !== AST_NODE_TYPES.CallExpression) break;
|
|
4110
4304
|
if (!core.isUseMemoCall(parent)) break;
|
|
4111
|
-
const init = ast.findParentNode(parent,
|
|
4305
|
+
const init = ast.findParentNode(parent, isHookDecl)?.init;
|
|
4112
4306
|
if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
|
|
4113
4307
|
break;
|
|
4114
4308
|
}
|
|
4115
4309
|
case AST_NODE_TYPES.CallExpression:
|
|
4116
4310
|
if (node !== node.parent.arguments.at(0)) break;
|
|
4117
4311
|
if (core.isUseCallbackCall(node.parent)) {
|
|
4118
|
-
const init = ast.findParentNode(node.parent,
|
|
4312
|
+
const init = ast.findParentNode(node.parent, isHookDecl)?.init;
|
|
4119
4313
|
if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
|
|
4120
4314
|
break;
|
|
4121
4315
|
}
|
|
@@ -4124,7 +4318,7 @@ function create$1(context) {
|
|
|
4124
4318
|
},
|
|
4125
4319
|
"Program:exit"() {
|
|
4126
4320
|
const getSetStateCalls = (id, initialScope) => {
|
|
4127
|
-
const node =
|
|
4321
|
+
const node = getVariableInitializer(findVariable(id, initialScope), 0);
|
|
4128
4322
|
switch (node?.type) {
|
|
4129
4323
|
case AST_NODE_TYPES.ArrowFunctionExpression:
|
|
4130
4324
|
case AST_NODE_TYPES.FunctionDeclaration:
|
|
@@ -4157,25 +4351,12 @@ function create$1(context) {
|
|
|
4157
4351
|
});
|
|
4158
4352
|
}
|
|
4159
4353
|
}
|
|
4160
|
-
};
|
|
4161
|
-
}
|
|
4162
|
-
function isInitFromHookCall(init) {
|
|
4163
|
-
if (init?.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
4164
|
-
switch (init.callee.type) {
|
|
4165
|
-
case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
|
|
4166
|
-
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
|
|
4167
|
-
default: return false;
|
|
4168
|
-
}
|
|
4169
|
-
}
|
|
4170
|
-
function isVariableDeclaratorFromHookCall(node) {
|
|
4171
|
-
if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
|
|
4172
|
-
if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
|
|
4173
|
-
return isInitFromHookCall(node.init);
|
|
4354
|
+
});
|
|
4174
4355
|
}
|
|
4175
4356
|
|
|
4176
4357
|
//#endregion
|
|
4177
4358
|
//#region src/rules/set-state-in-render.ts
|
|
4178
|
-
const RULE_NAME = "set-state-in-render";
|
|
4359
|
+
const RULE_NAME$3 = "set-state-in-render";
|
|
4179
4360
|
var set_state_in_render_default = createRule({
|
|
4180
4361
|
meta: {
|
|
4181
4362
|
type: "problem",
|
|
@@ -4183,11 +4364,11 @@ var set_state_in_render_default = createRule({
|
|
|
4183
4364
|
messages: { default: "Do not call the 'set' function '{{name}}' unconditionally during render. This will trigger an infinite render loop." },
|
|
4184
4365
|
schema: []
|
|
4185
4366
|
},
|
|
4186
|
-
name: RULE_NAME,
|
|
4187
|
-
create,
|
|
4367
|
+
name: RULE_NAME$3,
|
|
4368
|
+
create: create$3,
|
|
4188
4369
|
defaultOptions: []
|
|
4189
4370
|
});
|
|
4190
|
-
function create(context) {
|
|
4371
|
+
function create$3(context) {
|
|
4191
4372
|
const { additionalStateHooks } = getSettingsFromContext(context);
|
|
4192
4373
|
const functionEntries = [];
|
|
4193
4374
|
const componentFnRef = { current: null };
|
|
@@ -4196,7 +4377,7 @@ function create(context) {
|
|
|
4196
4377
|
return core.isUseStateLikeCall(node, additionalStateHooks);
|
|
4197
4378
|
}
|
|
4198
4379
|
function isIdFromUseStateCall(topLevelId, at) {
|
|
4199
|
-
const variableNode =
|
|
4380
|
+
const variableNode = getVariableInitializer(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
|
|
4200
4381
|
if (variableNode == null) return false;
|
|
4201
4382
|
if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
4202
4383
|
if (!isUseStateCall(variableNode)) return false;
|
|
@@ -4247,20 +4428,20 @@ function create(context) {
|
|
|
4247
4428
|
}
|
|
4248
4429
|
return false;
|
|
4249
4430
|
}
|
|
4250
|
-
function
|
|
4431
|
+
function isComponentOrHookLikeFunction(node) {
|
|
4251
4432
|
const id = ast.getFunctionId(node);
|
|
4252
4433
|
if (id == null) return false;
|
|
4253
|
-
if (id.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.name);
|
|
4254
|
-
if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.property.name);
|
|
4434
|
+
if (id.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.name) || core.isHookName(id.name);
|
|
4435
|
+
if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.property.name) || core.isHookName(id.property.name);
|
|
4255
4436
|
return false;
|
|
4256
4437
|
}
|
|
4257
4438
|
function getFunctionKind(node) {
|
|
4258
|
-
if (
|
|
4439
|
+
if (isComponentOrHookLikeFunction(node)) return "component";
|
|
4259
4440
|
const parent = ast.findParentNode(node, not(ast.isTypeExpression)) ?? node.parent;
|
|
4260
4441
|
if (parent.type === AST_NODE_TYPES.CallExpression && parent.callee !== node) return "callback";
|
|
4261
4442
|
return "other";
|
|
4262
4443
|
}
|
|
4263
|
-
return {
|
|
4444
|
+
return defineRuleListener({
|
|
4264
4445
|
":function"(node) {
|
|
4265
4446
|
const kind = getFunctionKind(node);
|
|
4266
4447
|
functionEntries.push({
|
|
@@ -4307,7 +4488,260 @@ function create(context) {
|
|
|
4307
4488
|
const idx = body.indexOf(stmt);
|
|
4308
4489
|
if (idx !== -1 && idx < body.length - 1) componentHasEarlyReturn.current = true;
|
|
4309
4490
|
}
|
|
4310
|
-
};
|
|
4491
|
+
});
|
|
4492
|
+
}
|
|
4493
|
+
|
|
4494
|
+
//#endregion
|
|
4495
|
+
//#region src/rules/unsupported-syntax.ts
|
|
4496
|
+
const RULE_NAME$2 = "unsupported-syntax";
|
|
4497
|
+
var unsupported_syntax_default = createRule({
|
|
4498
|
+
meta: {
|
|
4499
|
+
type: "problem",
|
|
4500
|
+
docs: { description: "Validates against syntax that React Compiler does not support." },
|
|
4501
|
+
messages: {
|
|
4502
|
+
eval: "Do not use 'eval' inside components or hooks. 'eval' cannot be statically analyzed and is not supported by React Compiler.",
|
|
4503
|
+
iife: "Do not use immediately-invoked function expressions in JSX. IIFEs will not be optimized by React Compiler.",
|
|
4504
|
+
with: "Do not use 'with' statements inside components or hooks. 'with' changes scope dynamically and is not supported by React Compiler."
|
|
4505
|
+
},
|
|
4506
|
+
schema: []
|
|
4507
|
+
},
|
|
4508
|
+
name: RULE_NAME$2,
|
|
4509
|
+
create: create$2,
|
|
4510
|
+
defaultOptions: []
|
|
4511
|
+
});
|
|
4512
|
+
function isEvalCall(node) {
|
|
4513
|
+
return node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === "eval";
|
|
4514
|
+
}
|
|
4515
|
+
function isIifeCall(node) {
|
|
4516
|
+
return node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
|
|
4517
|
+
}
|
|
4518
|
+
function create$2(context) {
|
|
4519
|
+
const hCollector = core.useHookCollector(context);
|
|
4520
|
+
const cCollector = core.useComponentCollector(context);
|
|
4521
|
+
const evalCalls = [];
|
|
4522
|
+
const withStmts = [];
|
|
4523
|
+
return defineRuleListener(hCollector.visitor, cCollector.visitor, {
|
|
4524
|
+
CallExpression(node) {
|
|
4525
|
+
if (!isEvalCall(node)) return;
|
|
4526
|
+
const func = ast.findParentNode(node, ast.isFunction);
|
|
4527
|
+
if (func == null) return;
|
|
4528
|
+
evalCalls.push({
|
|
4529
|
+
node,
|
|
4530
|
+
func
|
|
4531
|
+
});
|
|
4532
|
+
},
|
|
4533
|
+
"JSXElement :function"(node) {
|
|
4534
|
+
if (isIifeCall(node)) context.report({
|
|
4535
|
+
messageId: "iife",
|
|
4536
|
+
node: node.parent
|
|
4537
|
+
});
|
|
4538
|
+
},
|
|
4539
|
+
"JSXFragment :function"(node) {
|
|
4540
|
+
if (isIifeCall(node)) context.report({
|
|
4541
|
+
messageId: "iife",
|
|
4542
|
+
node: node.parent
|
|
4543
|
+
});
|
|
4544
|
+
},
|
|
4545
|
+
"Program:exit"(node) {
|
|
4546
|
+
const components = cCollector.ctx.getAllComponents(node);
|
|
4547
|
+
const hooks = hCollector.ctx.getAllHooks(node);
|
|
4548
|
+
const funcs = [...components, ...hooks];
|
|
4549
|
+
for (const { node, func } of evalCalls) {
|
|
4550
|
+
if (!funcs.some((f) => f.node === func)) continue;
|
|
4551
|
+
context.report({
|
|
4552
|
+
messageId: "eval",
|
|
4553
|
+
node
|
|
4554
|
+
});
|
|
4555
|
+
}
|
|
4556
|
+
for (const { node, func } of withStmts) {
|
|
4557
|
+
if (!funcs.some((f) => f.node === func)) continue;
|
|
4558
|
+
context.report({
|
|
4559
|
+
messageId: "with",
|
|
4560
|
+
node
|
|
4561
|
+
});
|
|
4562
|
+
}
|
|
4563
|
+
},
|
|
4564
|
+
WithStatement(node) {
|
|
4565
|
+
const func = ast.findParentNode(node, ast.isFunction);
|
|
4566
|
+
if (func == null) return;
|
|
4567
|
+
withStmts.push({
|
|
4568
|
+
node,
|
|
4569
|
+
func
|
|
4570
|
+
});
|
|
4571
|
+
}
|
|
4572
|
+
});
|
|
4573
|
+
}
|
|
4574
|
+
|
|
4575
|
+
//#endregion
|
|
4576
|
+
//#region src/rules/use-memo.ts
|
|
4577
|
+
const RULE_NAME$1 = "use-memo";
|
|
4578
|
+
var use_memo_default = createRule({
|
|
4579
|
+
meta: {
|
|
4580
|
+
type: "problem",
|
|
4581
|
+
docs: { description: "Validates that 'useMemo' is called with a callback that returns a value." },
|
|
4582
|
+
messages: {
|
|
4583
|
+
missingReturnValue: "The callback passed to 'useMemo' must return a value. Without a return value, 'useMemo' always returns 'undefined', which defeats its purpose.",
|
|
4584
|
+
notAssignedToVariable: "The return value of 'useMemo' must be assigned to a variable. Calling 'useMemo' without capturing its return value is likely a mistake — use 'useEffect' for side effects instead."
|
|
4585
|
+
},
|
|
4586
|
+
schema: []
|
|
4587
|
+
},
|
|
4588
|
+
name: RULE_NAME$1,
|
|
4589
|
+
create: create$1,
|
|
4590
|
+
defaultOptions: []
|
|
4591
|
+
});
|
|
4592
|
+
function create$1(context) {
|
|
4593
|
+
if (!context.sourceCode.text.includes("useMemo")) return {};
|
|
4594
|
+
return defineRuleListener({ CallExpression(node) {
|
|
4595
|
+
if (!core.isUseMemoCall(node)) return;
|
|
4596
|
+
const parent = node.parent;
|
|
4597
|
+
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)) {
|
|
4598
|
+
context.report({
|
|
4599
|
+
messageId: "notAssignedToVariable",
|
|
4600
|
+
node
|
|
4601
|
+
});
|
|
4602
|
+
return;
|
|
4603
|
+
}
|
|
4604
|
+
const [callbackArg] = node.arguments;
|
|
4605
|
+
if (callbackArg == null) return;
|
|
4606
|
+
if (!ast.isFunction(callbackArg)) return;
|
|
4607
|
+
if (callbackArg.type === AST_NODE_TYPES.ArrowFunctionExpression && callbackArg.body.type !== AST_NODE_TYPES.BlockStatement) return;
|
|
4608
|
+
if (callbackArg.body.type !== AST_NODE_TYPES.BlockStatement) return;
|
|
4609
|
+
const returnStatements = ast.getNestedReturnStatements(callbackArg);
|
|
4610
|
+
if (returnStatements.length === 0) {
|
|
4611
|
+
context.report({
|
|
4612
|
+
messageId: "missingReturnValue",
|
|
4613
|
+
node: callbackArg
|
|
4614
|
+
});
|
|
4615
|
+
return;
|
|
4616
|
+
}
|
|
4617
|
+
if (!returnStatements.some((stmt) => stmt.argument != null)) context.report({
|
|
4618
|
+
messageId: "missingReturnValue",
|
|
4619
|
+
node: callbackArg
|
|
4620
|
+
});
|
|
4621
|
+
} });
|
|
4622
|
+
}
|
|
4623
|
+
|
|
4624
|
+
//#endregion
|
|
4625
|
+
//#region src/rules/use-state.ts
|
|
4626
|
+
const RULE_NAME = "use-state";
|
|
4627
|
+
const defaultOptions = [{
|
|
4628
|
+
enforceAssignment: true,
|
|
4629
|
+
enforceLazyInitialization: true,
|
|
4630
|
+
enforceSetterName: true
|
|
4631
|
+
}];
|
|
4632
|
+
const schema = [{
|
|
4633
|
+
type: "object",
|
|
4634
|
+
additionalProperties: false,
|
|
4635
|
+
properties: {
|
|
4636
|
+
enforceAssignment: {
|
|
4637
|
+
type: "boolean",
|
|
4638
|
+
default: true
|
|
4639
|
+
},
|
|
4640
|
+
enforceLazyInitialization: {
|
|
4641
|
+
type: "boolean",
|
|
4642
|
+
default: true
|
|
4643
|
+
},
|
|
4644
|
+
enforceSetterName: {
|
|
4645
|
+
type: "boolean",
|
|
4646
|
+
default: true
|
|
4647
|
+
}
|
|
4648
|
+
}
|
|
4649
|
+
}];
|
|
4650
|
+
const LAZY_INIT_ALLOW_LIST = [
|
|
4651
|
+
"Boolean",
|
|
4652
|
+
"String",
|
|
4653
|
+
"Number"
|
|
4654
|
+
];
|
|
4655
|
+
var use_state_default = createRule({
|
|
4656
|
+
meta: {
|
|
4657
|
+
type: "suggestion",
|
|
4658
|
+
docs: { description: "Enforces correct usage of 'useState', including destructuring, symmetric naming of the value and setter, and wrapping expensive initializers in a lazy initializer function." },
|
|
4659
|
+
messages: {
|
|
4660
|
+
invalidAssignment: "useState should be destructured into a value and setter pair, e.g., const [state, setState] = useState(...).",
|
|
4661
|
+
invalidInitialization: "To prevent re-computation, consider using lazy initial state for useState calls that involve function calls. Ex: 'useState(() => getValue())'.",
|
|
4662
|
+
invalidSetterName: "The setter should be named 'set' followed by the capitalized state variable name, e.g., 'setState' for 'state'."
|
|
4663
|
+
},
|
|
4664
|
+
schema
|
|
4665
|
+
},
|
|
4666
|
+
name: RULE_NAME,
|
|
4667
|
+
create,
|
|
4668
|
+
defaultOptions
|
|
4669
|
+
});
|
|
4670
|
+
function create(context) {
|
|
4671
|
+
if (!context.sourceCode.text.includes("useState")) return {};
|
|
4672
|
+
const { enforceAssignment = true, enforceLazyInitialization = true, enforceSetterName = true } = context.options[0] ?? defaultOptions[0];
|
|
4673
|
+
return defineRuleListener({ CallExpression(node) {
|
|
4674
|
+
if (!core.isUseStateCall(node)) return;
|
|
4675
|
+
if (enforceLazyInitialization) {
|
|
4676
|
+
const [useStateInput] = node.arguments;
|
|
4677
|
+
if (useStateInput != null) {
|
|
4678
|
+
for (const expr of ast.getNestedNewExpressions(useStateInput)) {
|
|
4679
|
+
if (!("name" in expr.callee)) continue;
|
|
4680
|
+
if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
4681
|
+
if (ast.findParentNode(expr, core.isUseCall) != null) continue;
|
|
4682
|
+
context.report({
|
|
4683
|
+
messageId: "invalidInitialization",
|
|
4684
|
+
node: expr
|
|
4685
|
+
});
|
|
4686
|
+
}
|
|
4687
|
+
for (const expr of ast.getNestedCallExpressions(useStateInput)) {
|
|
4688
|
+
if (!("name" in expr.callee)) continue;
|
|
4689
|
+
if (core.isHookName(expr.callee.name)) continue;
|
|
4690
|
+
if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
4691
|
+
if (ast.findParentNode(expr, core.isUseCall) != null) continue;
|
|
4692
|
+
context.report({
|
|
4693
|
+
messageId: "invalidInitialization",
|
|
4694
|
+
node: expr
|
|
4695
|
+
});
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
|
|
4700
|
+
if (!enforceAssignment) return;
|
|
4701
|
+
context.report({
|
|
4702
|
+
messageId: "invalidAssignment",
|
|
4703
|
+
node
|
|
4704
|
+
});
|
|
4705
|
+
return;
|
|
4706
|
+
}
|
|
4707
|
+
const id = findEnclosingAssignmentTarget(node);
|
|
4708
|
+
if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
|
|
4709
|
+
if (!enforceAssignment) return;
|
|
4710
|
+
context.report({
|
|
4711
|
+
messageId: "invalidAssignment",
|
|
4712
|
+
node: id ?? node
|
|
4713
|
+
});
|
|
4714
|
+
return;
|
|
4715
|
+
}
|
|
4716
|
+
const [value, setter] = id.elements;
|
|
4717
|
+
if (value == null) {
|
|
4718
|
+
if (!enforceAssignment) return;
|
|
4719
|
+
context.report({
|
|
4720
|
+
messageId: "invalidAssignment",
|
|
4721
|
+
node: id
|
|
4722
|
+
});
|
|
4723
|
+
return;
|
|
4724
|
+
}
|
|
4725
|
+
if (setter == null || !enforceSetterName) return;
|
|
4726
|
+
if (value.type !== AST_NODE_TYPES.Identifier) {
|
|
4727
|
+
context.report({
|
|
4728
|
+
messageId: "invalidAssignment",
|
|
4729
|
+
node: value
|
|
4730
|
+
});
|
|
4731
|
+
return;
|
|
4732
|
+
}
|
|
4733
|
+
if (setter.type !== AST_NODE_TYPES.Identifier || !setter.name.startsWith("set")) {
|
|
4734
|
+
context.report({
|
|
4735
|
+
messageId: "invalidSetterName",
|
|
4736
|
+
node: setter
|
|
4737
|
+
});
|
|
4738
|
+
return;
|
|
4739
|
+
}
|
|
4740
|
+
if (snakeCase(setter.name) !== `set_${snakeCase(value.name)}`) context.report({
|
|
4741
|
+
messageId: "invalidSetterName",
|
|
4742
|
+
node: setter
|
|
4743
|
+
});
|
|
4744
|
+
} });
|
|
4311
4745
|
}
|
|
4312
4746
|
|
|
4313
4747
|
//#endregion
|
|
@@ -4325,7 +4759,6 @@ const plugin = {
|
|
|
4325
4759
|
"jsx-key-before-spread": jsx_key_before_spread_default,
|
|
4326
4760
|
"jsx-no-comment-textnodes": jsx_no_comment_textnodes_default,
|
|
4327
4761
|
"jsx-no-duplicate-props": jsx_no_duplicate_props_default,
|
|
4328
|
-
"jsx-no-iife": jsx_no_iife_default,
|
|
4329
4762
|
"jsx-no-undef": jsx_no_undef_default,
|
|
4330
4763
|
"jsx-shorthand-boolean": jsx_shorthand_boolean_default,
|
|
4331
4764
|
"jsx-shorthand-fragment": jsx_shorthand_fragment_default,
|
|
@@ -4378,11 +4811,14 @@ const plugin = {
|
|
|
4378
4811
|
"prefer-destructuring-assignment": prefer_destructuring_assignment_default,
|
|
4379
4812
|
"prefer-namespace-import": prefer_namespace_import_default,
|
|
4380
4813
|
"prefer-read-only-props": prefer_read_only_props_default,
|
|
4381
|
-
"prefer-use-state-lazy-initialization": prefer_use_state_lazy_initialization_default,
|
|
4382
4814
|
purity: purity_default,
|
|
4815
|
+
refs: refs_default,
|
|
4383
4816
|
"rules-of-hooks": rules_of_hooks_default,
|
|
4384
4817
|
"set-state-in-effect": set_state_in_effect_default,
|
|
4385
|
-
"set-state-in-render": set_state_in_render_default
|
|
4818
|
+
"set-state-in-render": set_state_in_render_default,
|
|
4819
|
+
"unsupported-syntax": unsupported_syntax_default,
|
|
4820
|
+
"use-memo": use_memo_default,
|
|
4821
|
+
"use-state": use_state_default
|
|
4386
4822
|
}
|
|
4387
4823
|
};
|
|
4388
4824
|
|
|
@@ -4432,11 +4868,13 @@ const rules$6 = {
|
|
|
4432
4868
|
"react-x/no-unsafe-component-will-update": "warn",
|
|
4433
4869
|
"react-x/no-use-context": "warn",
|
|
4434
4870
|
"react-x/no-useless-forward-ref": "warn",
|
|
4435
|
-
"react-x/prefer-use-state-lazy-initialization": "warn",
|
|
4436
4871
|
"react-x/purity": "warn",
|
|
4437
4872
|
"react-x/rules-of-hooks": "error",
|
|
4438
4873
|
"react-x/set-state-in-effect": "warn",
|
|
4439
|
-
"react-x/set-state-in-render": "error"
|
|
4874
|
+
"react-x/set-state-in-render": "error",
|
|
4875
|
+
"react-x/unsupported-syntax": "error",
|
|
4876
|
+
"react-x/use-memo": "error",
|
|
4877
|
+
"react-x/use-state": "warn"
|
|
4440
4878
|
};
|
|
4441
4879
|
const plugins$5 = { "react-x": plugin };
|
|
4442
4880
|
const settings$5 = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS };
|
|
@@ -4497,7 +4935,6 @@ var strict_exports = /* @__PURE__ */ __exportAll({
|
|
|
4497
4935
|
const name$2 = "react-x/strict";
|
|
4498
4936
|
const rules$2 = {
|
|
4499
4937
|
...rules$6,
|
|
4500
|
-
"react-x/jsx-no-iife": "error",
|
|
4501
4938
|
"react-x/no-children-prop": "error",
|
|
4502
4939
|
"react-x/no-class-component": "error",
|
|
4503
4940
|
"react-x/no-misused-capture-owner-stack": "error",
|