@eslint-react/core 3.0.0-next.2 → 3.0.0-next.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +121 -128
- package/dist/index.js +118 -127
- package/package.json +8 -8
package/dist/index.d.ts
CHANGED
|
@@ -78,19 +78,19 @@ declare const isForwardRefCall: isReactAPICall.ReturnType;
|
|
|
78
78
|
declare const isMemoCall: isReactAPICall.ReturnType;
|
|
79
79
|
declare const isLazyCall: isReactAPICall.ReturnType;
|
|
80
80
|
//#endregion
|
|
81
|
-
//#region src/component/component-detection
|
|
81
|
+
//#region src/component/component-detection.d.ts
|
|
82
82
|
type ComponentDetectionHint = bigint;
|
|
83
83
|
/**
|
|
84
84
|
* Hints for component collector
|
|
85
85
|
*/
|
|
86
86
|
declare const ComponentDetectionHint: {
|
|
87
|
-
readonly
|
|
87
|
+
readonly DoNotIncludeFunctionDefinedAsArrayFlatMapCallback: bigint;
|
|
88
|
+
readonly DoNotIncludeFunctionDefinedAsArrayMapCallback: bigint;
|
|
89
|
+
readonly DoNotIncludeFunctionDefinedInArrayExpression: bigint;
|
|
90
|
+
readonly DoNotIncludeFunctionDefinedInArrayPattern: bigint;
|
|
88
91
|
readonly DoNotIncludeFunctionDefinedOnClassMethod: bigint;
|
|
89
92
|
readonly DoNotIncludeFunctionDefinedOnClassProperty: bigint;
|
|
90
|
-
readonly
|
|
91
|
-
readonly DoNotIncludeFunctionDefinedInArrayExpression: bigint;
|
|
92
|
-
readonly DoNotIncludeFunctionDefinedAsArrayMapCallback: bigint;
|
|
93
|
-
readonly DoNotIncludeFunctionDefinedAsArrayFlatMapCallback: bigint;
|
|
93
|
+
readonly DoNotIncludeFunctionDefinedOnObjectMethod: bigint;
|
|
94
94
|
readonly None: 0n;
|
|
95
95
|
readonly DoNotIncludeJsxWithNullValue: bigint;
|
|
96
96
|
readonly DoNotIncludeJsxWithNumberValue: bigint;
|
|
@@ -108,6 +108,77 @@ declare const ComponentDetectionHint: {
|
|
|
108
108
|
* Default component detection hint
|
|
109
109
|
*/
|
|
110
110
|
declare const DEFAULT_COMPONENT_DETECTION_HINT: bigint;
|
|
111
|
+
/**
|
|
112
|
+
* Check whether given node is a render method of a class component
|
|
113
|
+
* @example
|
|
114
|
+
* ```tsx
|
|
115
|
+
* class Component extends React.Component {
|
|
116
|
+
* renderHeader = () => <div />;
|
|
117
|
+
* renderFooter = () => <div />;
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
* @param node The AST node to check
|
|
121
|
+
* @returns `true` if node is a render function, `false` if not
|
|
122
|
+
*/
|
|
123
|
+
declare function isRenderMethodLike(node: TSESTree.Node): node is ast.TSESTreeMethodOrProperty;
|
|
124
|
+
/**
|
|
125
|
+
* Unsafe check whether given node is a render function
|
|
126
|
+
* ```tsx
|
|
127
|
+
* const renderRow = () => <div />
|
|
128
|
+
* ` ^^^^^^^^^^^^`
|
|
129
|
+
* _ = <Component renderRow={() => <div />} />
|
|
130
|
+
* ` ^^^^^^^^^^^^^ `
|
|
131
|
+
* ```
|
|
132
|
+
* @param context The rule context
|
|
133
|
+
* @param node The AST node to check
|
|
134
|
+
* @returns `true` if node is a render function, `false` if not
|
|
135
|
+
*/
|
|
136
|
+
declare function isRenderFunctionLoose(context: RuleContext, node: TSESTree.Node): node is ast.TSESTreeFunction;
|
|
137
|
+
/**
|
|
138
|
+
* Unsafe check whether given JSXAttribute is a render prop
|
|
139
|
+
* ```tsx
|
|
140
|
+
* _ = <Component renderRow={() => <div />} />
|
|
141
|
+
* ` ^^^^^^^^^^^^^^^^^^^^^^^^^ `
|
|
142
|
+
* ```
|
|
143
|
+
* @param context The rule context
|
|
144
|
+
* @param node The AST node to check
|
|
145
|
+
* @returns `true` if node is a render prop, `false` if not
|
|
146
|
+
*/
|
|
147
|
+
declare function isRenderPropLoose(context: RuleContext, node: TSESTree.JSXAttribute): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Unsafe check whether given node is declared directly inside a render property
|
|
150
|
+
* ```tsx
|
|
151
|
+
* const rows = { render: () => <div /> }
|
|
152
|
+
* ` ^^^^^^^^^^^^^ `
|
|
153
|
+
* _ = <Component rows={ [{ render: () => <div /> }] } />
|
|
154
|
+
* ` ^^^^^^^^^^^^^ `
|
|
155
|
+
* ```
|
|
156
|
+
* @internal
|
|
157
|
+
* @param node The AST node to check
|
|
158
|
+
* @returns `true` if component is declared inside a render property, `false` if not
|
|
159
|
+
*/
|
|
160
|
+
declare function isDirectValueOfRenderPropertyLoose(node: TSESTree.Node): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Unsafe check whether given node is declared inside a render prop
|
|
163
|
+
* ```tsx
|
|
164
|
+
* _ = <Component renderRow={"node"} />
|
|
165
|
+
* ` ^^^^^^ `
|
|
166
|
+
* _ = <Component rows={ [{ render: "node" }] } />
|
|
167
|
+
* ` ^^^^^^ `
|
|
168
|
+
* ```
|
|
169
|
+
* @param node The AST node to check
|
|
170
|
+
* @returns `true` if component is declared inside a render prop, `false` if not
|
|
171
|
+
*/
|
|
172
|
+
declare function isDeclaredInRenderPropLoose(node: TSESTree.Node): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Determine if a function node represents a valid React component definition
|
|
175
|
+
*
|
|
176
|
+
* @param context The rule context
|
|
177
|
+
* @param node The function node to analyze
|
|
178
|
+
* @param hint Component detection hints (bit flags) to customize detection logic
|
|
179
|
+
* @returns `true` if the node is considered a component definition
|
|
180
|
+
*/
|
|
181
|
+
declare function isComponentDefinition(context: RuleContext, node: ast.TSESTreeFunction, hint: bigint): boolean;
|
|
111
182
|
//#endregion
|
|
112
183
|
//#region src/semantic/semantic-node.d.ts
|
|
113
184
|
/**
|
|
@@ -155,19 +226,6 @@ interface SemanticFunc extends SemanticNode {
|
|
|
155
226
|
typeParameters: TSESTree.TSTypeParameterDeclaration | unit;
|
|
156
227
|
}
|
|
157
228
|
//#endregion
|
|
158
|
-
//#region src/component/component-flag.d.ts
|
|
159
|
-
type ComponentFlag = bigint;
|
|
160
|
-
/**
|
|
161
|
-
* Component flag constants
|
|
162
|
-
*/
|
|
163
|
-
declare const ComponentFlag: {
|
|
164
|
-
/** No flags set */None: bigint; /** Indicates the component is a pure component (e.g., extends PureComponent) */
|
|
165
|
-
PureComponent: bigint; /** Indicates the component creates elements using `createElement` instead of JSX */
|
|
166
|
-
CreateElement: bigint; /** Indicates the component is memoized (e.g., React.memo) */
|
|
167
|
-
Memo: bigint; /** Indicates the component forwards a ref (e.g., React.forwardRef) */
|
|
168
|
-
ForwardRef: bigint;
|
|
169
|
-
};
|
|
170
|
-
//#endregion
|
|
171
229
|
//#region src/component/component-semantic-node.d.ts
|
|
172
230
|
/**
|
|
173
231
|
* Represents a React Function Component
|
|
@@ -188,11 +246,11 @@ interface FunctionComponentSemanticNode extends SemanticNode {
|
|
|
188
246
|
/**
|
|
189
247
|
* Flags describing the component's characteristics
|
|
190
248
|
*/
|
|
191
|
-
flag:
|
|
249
|
+
flag: bigint;
|
|
192
250
|
/**
|
|
193
251
|
* Hint for how the component was detected
|
|
194
252
|
*/
|
|
195
|
-
hint:
|
|
253
|
+
hint: bigint;
|
|
196
254
|
/**
|
|
197
255
|
* List of expressions returned by the component
|
|
198
256
|
*/
|
|
@@ -241,11 +299,11 @@ interface ClassComponentSemanticNode extends SemanticNode {
|
|
|
241
299
|
/**
|
|
242
300
|
* Flags describing the component's characteristics
|
|
243
301
|
*/
|
|
244
|
-
flag:
|
|
302
|
+
flag: bigint;
|
|
245
303
|
/**
|
|
246
304
|
* Hint for how the component was detected
|
|
247
305
|
*/
|
|
248
|
-
hint:
|
|
306
|
+
hint: bigint;
|
|
249
307
|
/**
|
|
250
308
|
* List of methods and properties in the class
|
|
251
309
|
*/
|
|
@@ -314,16 +372,23 @@ declare function isThisSetState(node: TSESTree$1.CallExpression): boolean;
|
|
|
314
372
|
*/
|
|
315
373
|
declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression): boolean;
|
|
316
374
|
//#endregion
|
|
317
|
-
//#region src/component/component-
|
|
375
|
+
//#region src/component/component-flag.d.ts
|
|
318
376
|
/**
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
* @param context The rule context
|
|
322
|
-
* @param node The function node to analyze
|
|
323
|
-
* @param hint Component detection hints (bit flags) to customize detection logic
|
|
324
|
-
* @returns `true` if the node is considered a component definition
|
|
377
|
+
* Component flag constants
|
|
325
378
|
*/
|
|
326
|
-
declare
|
|
379
|
+
declare const ComponentFlag: {
|
|
380
|
+
/** Indicates the component creates elements using `createElement` instead of JSX */CreateElement: bigint; /** Indicates the component forwards a ref (e.g., React.forwardRef) */
|
|
381
|
+
ForwardRef: bigint; /** Indicates the component is memoized (e.g., React.memo) */
|
|
382
|
+
Memo: bigint; /** No flags set */
|
|
383
|
+
None: bigint; /** Indicates the component is a pure component (e.g., extends PureComponent) */
|
|
384
|
+
PureComponent: bigint;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Get component flag from init path
|
|
388
|
+
* @param initPath The init path of the function component
|
|
389
|
+
* @returns The component flag
|
|
390
|
+
*/
|
|
391
|
+
declare function getComponentFlagFromInitPath(initPath: FunctionComponentSemanticNode["initPath"]): bigint;
|
|
327
392
|
//#endregion
|
|
328
393
|
//#region src/component/component-id.d.ts
|
|
329
394
|
/**
|
|
@@ -334,15 +399,8 @@ declare function isComponentDefinition(context: RuleContext, node: ast.TSESTreeF
|
|
|
334
399
|
*/
|
|
335
400
|
declare function getFunctionComponentId(context: RuleContext, node: ast.TSESTreeFunction): ast.FunctionID | unit;
|
|
336
401
|
//#endregion
|
|
337
|
-
//#region src/component/component-
|
|
338
|
-
|
|
339
|
-
* Get component flag from init path
|
|
340
|
-
* @param initPath The init path of the function component
|
|
341
|
-
* @returns The component flag
|
|
342
|
-
*/
|
|
343
|
-
declare function getComponentFlagFromInitPath(initPath: FunctionComponentSemanticNode["initPath"]): bigint;
|
|
344
|
-
//#endregion
|
|
345
|
-
//#region src/component/component-is.d.ts
|
|
402
|
+
//#region src/component/component-kind.d.ts
|
|
403
|
+
type ComponentKind = "class-component" | "pure-component" | "function-component";
|
|
346
404
|
/**
|
|
347
405
|
* Check if a node is a React class component
|
|
348
406
|
* @param node The AST node to check
|
|
@@ -356,21 +414,7 @@ declare function isClassComponent(node: TSESTree.Node): node is ast.TSESTreeClas
|
|
|
356
414
|
*/
|
|
357
415
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
358
416
|
//#endregion
|
|
359
|
-
//#region src/component/component-method
|
|
360
|
-
/**
|
|
361
|
-
* Check if the given node is a componentDidMount callback
|
|
362
|
-
* @param node The node to check
|
|
363
|
-
* @returns True if the node is a componentDidMount callback, false otherwise
|
|
364
|
-
*/
|
|
365
|
-
declare function isComponentDidMountCallback(node: TSESTree.Node): boolean;
|
|
366
|
-
/**
|
|
367
|
-
* Check if the given node is a componentWillUnmount callback
|
|
368
|
-
* @param node The node to check
|
|
369
|
-
* @returns True if the node is a componentWillUnmount callback, false otherwise
|
|
370
|
-
*/
|
|
371
|
-
declare function isComponentWillUnmountCallback(node: TSESTree.Node): boolean;
|
|
372
|
-
//#endregion
|
|
373
|
-
//#region src/component/component-method-is.d.ts
|
|
417
|
+
//#region src/component/component-method.d.ts
|
|
374
418
|
declare const isRender: (node: TSESTree.Node) => node is ast.TSESTreeMethodOrProperty;
|
|
375
419
|
declare const isComponentDidCatch: (node: TSESTree.Node) => node is ast.TSESTreeMethodOrProperty;
|
|
376
420
|
declare const isComponentDidMount: (node: TSESTree.Node) => node is ast.TSESTreeMethodOrProperty;
|
|
@@ -389,6 +433,18 @@ declare const isUnsafeComponentWillUpdate: (node: TSESTree.Node) => node is ast.
|
|
|
389
433
|
declare const isGetDefaultProps: (node: TSESTree.Node) => node is ast.TSESTreeMethodOrProperty;
|
|
390
434
|
declare const isGetDerivedStateFromProps: (node: TSESTree.Node) => node is ast.TSESTreeMethodOrProperty;
|
|
391
435
|
declare const isGetDerivedStateFromError: (node: TSESTree.Node) => node is ast.TSESTreeMethodOrProperty;
|
|
436
|
+
/**
|
|
437
|
+
* Check if the given node is a componentDidMount callback
|
|
438
|
+
* @param node The node to check
|
|
439
|
+
* @returns True if the node is a componentDidMount callback, false otherwise
|
|
440
|
+
*/
|
|
441
|
+
declare function isComponentDidMountCallback(node: TSESTree.Node): boolean;
|
|
442
|
+
/**
|
|
443
|
+
* Check if the given node is a componentWillUnmount callback
|
|
444
|
+
* @param node The node to check
|
|
445
|
+
* @returns True if the node is a componentWillUnmount callback, false otherwise
|
|
446
|
+
*/
|
|
447
|
+
declare function isComponentWillUnmountCallback(node: TSESTree.Node): boolean;
|
|
392
448
|
//#endregion
|
|
393
449
|
//#region src/component/component-name.d.ts
|
|
394
450
|
/**
|
|
@@ -410,72 +466,6 @@ declare function isComponentNameLoose(name: string): boolean;
|
|
|
410
466
|
*/
|
|
411
467
|
declare function isFunctionWithLooseComponentName(context: RuleContext, fn: ast.TSESTreeFunction, allowNone?: boolean): boolean;
|
|
412
468
|
//#endregion
|
|
413
|
-
//#region src/component/component-render-method.d.ts
|
|
414
|
-
/**
|
|
415
|
-
* Check whether given node is a render method of a class component
|
|
416
|
-
* @example
|
|
417
|
-
* ```tsx
|
|
418
|
-
* class Component extends React.Component {
|
|
419
|
-
* renderHeader = () => <div />;
|
|
420
|
-
* renderFooter = () => <div />;
|
|
421
|
-
* }
|
|
422
|
-
* ```
|
|
423
|
-
* @param node The AST node to check
|
|
424
|
-
* @returns `true` if node is a render function, `false` if not
|
|
425
|
-
*/
|
|
426
|
-
declare function isRenderMethodLike(node: TSESTree.Node): node is ast.TSESTreeMethodOrProperty;
|
|
427
|
-
//#endregion
|
|
428
|
-
//#region src/component/component-render-prop.d.ts
|
|
429
|
-
/**
|
|
430
|
-
* Unsafe check whether given node is a render function
|
|
431
|
-
* ```tsx
|
|
432
|
-
* const renderRow = () => <div />
|
|
433
|
-
* ` ^^^^^^^^^^^^`
|
|
434
|
-
* _ = <Component renderRow={() => <div />} />
|
|
435
|
-
* ` ^^^^^^^^^^^^^ `
|
|
436
|
-
* ```
|
|
437
|
-
* @param context The rule context
|
|
438
|
-
* @param node The AST node to check
|
|
439
|
-
* @returns `true` if node is a render function, `false` if not
|
|
440
|
-
*/
|
|
441
|
-
declare function isRenderFunctionLoose(context: RuleContext, node: TSESTree.Node): node is ast.TSESTreeFunction;
|
|
442
|
-
/**
|
|
443
|
-
* Unsafe check whether given JSXAttribute is a render prop
|
|
444
|
-
* ```tsx
|
|
445
|
-
* _ = <Component renderRow={() => <div />} />
|
|
446
|
-
* ` ^^^^^^^^^^^^^^^^^^^^^^^^^ `
|
|
447
|
-
* ```
|
|
448
|
-
* @param context The rule context
|
|
449
|
-
* @param node The AST node to check
|
|
450
|
-
* @returns `true` if node is a render prop, `false` if not
|
|
451
|
-
*/
|
|
452
|
-
declare function isRenderPropLoose(context: RuleContext, node: TSESTree.JSXAttribute): boolean;
|
|
453
|
-
/**
|
|
454
|
-
* Unsafe check whether given node is declared directly inside a render property
|
|
455
|
-
* ```tsx
|
|
456
|
-
* const rows = { render: () => <div /> }
|
|
457
|
-
* ` ^^^^^^^^^^^^^ `
|
|
458
|
-
* _ = <Component rows={ [{ render: () => <div /> }] } />
|
|
459
|
-
* ` ^^^^^^^^^^^^^ `
|
|
460
|
-
* ```
|
|
461
|
-
* @internal
|
|
462
|
-
* @param node The AST node to check
|
|
463
|
-
* @returns `true` if component is declared inside a render property, `false` if not
|
|
464
|
-
*/
|
|
465
|
-
declare function isDirectValueOfRenderPropertyLoose(node: TSESTree.Node): boolean;
|
|
466
|
-
/**
|
|
467
|
-
* Unsafe check whether given node is declared inside a render prop
|
|
468
|
-
* ```tsx
|
|
469
|
-
* _ = <Component renderRow={"node"} />
|
|
470
|
-
* ` ^^^^^^ `
|
|
471
|
-
* _ = <Component rows={ [{ render: "node" }] } />
|
|
472
|
-
* ` ^^^^^^ `
|
|
473
|
-
* ```
|
|
474
|
-
* @param node The AST node to check
|
|
475
|
-
* @returns `true` if component is declared inside a render prop, `false` if not
|
|
476
|
-
*/
|
|
477
|
-
declare function isDeclaredInRenderPropLoose(node: TSESTree.Node): boolean;
|
|
478
|
-
//#endregion
|
|
479
469
|
//#region src/component/component-wrapper.d.ts
|
|
480
470
|
/**
|
|
481
471
|
* Check if the node is a call expression for a component wrapper
|
|
@@ -510,7 +500,7 @@ declare function isComponentWrapperCallbackLoose(context: RuleContext, node: TSE
|
|
|
510
500
|
/**
|
|
511
501
|
* Represents the kind of a React function
|
|
512
502
|
*/
|
|
513
|
-
type
|
|
503
|
+
type FunctionKind = "client-function" | "server-function";
|
|
514
504
|
//#endregion
|
|
515
505
|
//#region src/function/function-semantic-node.d.ts
|
|
516
506
|
/**
|
|
@@ -544,7 +534,7 @@ type FindEnclosingComponentOrHookFilter = (n: TSESTree.Node, name: string | null
|
|
|
544
534
|
* @param test Optional test function to customize component or hook identification
|
|
545
535
|
* @returns The enclosing component or hook node, or `null` if none is ASAST.
|
|
546
536
|
*/
|
|
547
|
-
declare function findEnclosingComponentOrHook(node: TSESTree.Node | unit, test?: FindEnclosingComponentOrHookFilter): TSESTree.ArrowFunctionExpression | TSESTree.
|
|
537
|
+
declare function findEnclosingComponentOrHook(node: TSESTree.Node | unit, test?: FindEnclosingComponentOrHookFilter): TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.FunctionExpression | undefined;
|
|
548
538
|
//#endregion
|
|
549
539
|
//#region src/hierarchy/is-inside-component-or-hook.d.ts
|
|
550
540
|
/**
|
|
@@ -742,7 +732,7 @@ declare function resolveJsxAttributeValue(context: RuleContext, attribute: ast.T
|
|
|
742
732
|
readonly toStatic: () => string | number | bigint | boolean | RegExp | null;
|
|
743
733
|
} | {
|
|
744
734
|
readonly kind: "expression";
|
|
745
|
-
readonly node: TSESTree.
|
|
735
|
+
readonly node: TSESTree.JSXEmptyExpression | TSESTree.Expression;
|
|
746
736
|
readonly toStatic: () => unknown;
|
|
747
737
|
} | {
|
|
748
738
|
readonly kind: "element";
|
|
@@ -750,7 +740,7 @@ declare function resolveJsxAttributeValue(context: RuleContext, attribute: ast.T
|
|
|
750
740
|
readonly toStatic: () => undefined;
|
|
751
741
|
} | {
|
|
752
742
|
readonly kind: "spreadChild";
|
|
753
|
-
readonly node: TSESTree.
|
|
743
|
+
readonly node: TSESTree.JSXEmptyExpression | TSESTree.Expression;
|
|
754
744
|
readonly toStatic: () => undefined;
|
|
755
745
|
} | {
|
|
756
746
|
readonly kind: "spreadProps";
|
|
@@ -889,7 +879,10 @@ declare function findParentJsxAttribute(node: TSESTree.Node, test?: (node: TSEST
|
|
|
889
879
|
*/
|
|
890
880
|
declare function stringifyJsx(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXNamespacedName | TSESTree$1.JSXMemberExpression | TSESTree$1.JSXOpeningElement | TSESTree$1.JSXClosingElement | TSESTree$1.JSXOpeningFragment | TSESTree$1.JSXClosingFragment | TSESTree$1.JSXText): string;
|
|
891
881
|
//#endregion
|
|
892
|
-
//#region src/ref/
|
|
882
|
+
//#region src/ref/ref-id.d.ts
|
|
883
|
+
declare function isRefId(node: TSESTree.Expression | TSESTree.PrivateIdentifier): boolean;
|
|
884
|
+
//#endregion
|
|
885
|
+
//#region src/ref/ref-init.d.ts
|
|
893
886
|
/**
|
|
894
887
|
* Check if the variable with the given name is initialized or derived from a ref
|
|
895
888
|
* @param name The variable name
|
|
@@ -911,6 +904,6 @@ declare function getRefInit(name: string, initialScope: Scope): TSESTree$1.Expre
|
|
|
911
904
|
* @param name The name to check
|
|
912
905
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
913
906
|
*/
|
|
914
|
-
declare function
|
|
907
|
+
declare function isRefLikeName(name: string): boolean;
|
|
915
908
|
//#endregion
|
|
916
|
-
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentKind, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FindEnclosingComponentOrHookFilter, FunctionComponentSemanticNode, FunctionSemanticNode, HookSemanticNode, JsxAttributeValue, JsxConfig, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findEnclosingComponentOrHook, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, getRefInit, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isInsideComponentOrHook, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall,
|
|
909
|
+
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentKind, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FindEnclosingComponentOrHookFilter, FunctionComponentSemanticNode, FunctionKind, FunctionSemanticNode, HookSemanticNode, JsxAttributeValue, JsxConfig, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findEnclosingComponentOrHook, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, getRefInit, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isInsideComponentOrHook, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefId, isRefLikeName, isRender, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStoreCall, isUseTransitionCall, resolveJsxAttributeValue, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { findImportSource, findProperty, findVariable,
|
|
1
|
+
import { findImportSource, findProperty, findVariable, getVariableInitializer } from "@eslint-react/var";
|
|
2
2
|
import * as ast from "@eslint-react/ast";
|
|
3
3
|
import { constFalse, constTrue, dual, flip, getOrElseUpdate, identity, unit } from "@eslint-react/eff";
|
|
4
4
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
@@ -260,7 +260,7 @@ function isHookId(id) {
|
|
|
260
260
|
|
|
261
261
|
//#endregion
|
|
262
262
|
//#region src/hook/hook-collector.ts
|
|
263
|
-
const idGen$2 = new IdGenerator("
|
|
263
|
+
const idGen$2 = new IdGenerator("hook:");
|
|
264
264
|
/**
|
|
265
265
|
* Get a ctx and visitor object for the rule to collect hooks
|
|
266
266
|
* @param context The ESLint rule context
|
|
@@ -369,7 +369,7 @@ function getJsxAttribute(context, node, initialScope) {
|
|
|
369
369
|
if (attr.type === AST_NODE_TYPES.JSXAttribute) return getJsxAttributeName(context, attr) === name;
|
|
370
370
|
switch (attr.argument.type) {
|
|
371
371
|
case AST_NODE_TYPES.Identifier: {
|
|
372
|
-
const variableNode =
|
|
372
|
+
const variableNode = getVariableInitializer(findVariable(attr.argument.name, scope), 0);
|
|
373
373
|
if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) return findProperty(name, variableNode.properties, scope) != null;
|
|
374
374
|
return false;
|
|
375
375
|
}
|
|
@@ -597,7 +597,7 @@ function isJsxLike(code, node, hint = DEFAULT_JSX_DETECTION_HINT) {
|
|
|
597
597
|
const { name } = node;
|
|
598
598
|
if (name === "undefined") return !(hint & JsxDetectionHint.DoNotIncludeJsxWithUndefinedValue);
|
|
599
599
|
if (ast.isJSXTagNameExpression(node)) return true;
|
|
600
|
-
return isJsxLike(code,
|
|
600
|
+
return isJsxLike(code, getVariableInitializer(findVariable(name, code.getScope(node)), 0), hint);
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
return false;
|
|
@@ -666,27 +666,7 @@ function findParentJsxAttribute(node, test = constTrue) {
|
|
|
666
666
|
}
|
|
667
667
|
|
|
668
668
|
//#endregion
|
|
669
|
-
//#region src/component/component-
|
|
670
|
-
/**
|
|
671
|
-
* Hints for component collector
|
|
672
|
-
*/
|
|
673
|
-
const ComponentDetectionHint = {
|
|
674
|
-
...JsxDetectionHint,
|
|
675
|
-
DoNotIncludeFunctionDefinedOnObjectMethod: 1n << 64n,
|
|
676
|
-
DoNotIncludeFunctionDefinedOnClassMethod: 1n << 65n,
|
|
677
|
-
DoNotIncludeFunctionDefinedOnClassProperty: 1n << 66n,
|
|
678
|
-
DoNotIncludeFunctionDefinedInArrayPattern: 1n << 67n,
|
|
679
|
-
DoNotIncludeFunctionDefinedInArrayExpression: 1n << 68n,
|
|
680
|
-
DoNotIncludeFunctionDefinedAsArrayMapCallback: 1n << 69n,
|
|
681
|
-
DoNotIncludeFunctionDefinedAsArrayFlatMapCallback: 1n << 70n
|
|
682
|
-
};
|
|
683
|
-
/**
|
|
684
|
-
* Default component detection hint
|
|
685
|
-
*/
|
|
686
|
-
const DEFAULT_COMPONENT_DETECTION_HINT = 0n | ComponentDetectionHint.DoNotIncludeJsxWithBigIntValue | ComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | ComponentDetectionHint.DoNotIncludeJsxWithNumberValue | ComponentDetectionHint.DoNotIncludeJsxWithStringValue | ComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayFlatMapCallback | ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback | ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression | ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern | ComponentDetectionHint.RequireAllArrayElementsToBeJsx | ComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | ComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx;
|
|
687
|
-
|
|
688
|
-
//#endregion
|
|
689
|
-
//#region src/component/component-is.ts
|
|
669
|
+
//#region src/component/component-kind.ts
|
|
690
670
|
/**
|
|
691
671
|
* Check if a node is a React class component
|
|
692
672
|
* @param node The AST node to check
|
|
@@ -814,7 +794,24 @@ function isFunctionWithLooseComponentName(context, fn, allowNone = false) {
|
|
|
814
794
|
}
|
|
815
795
|
|
|
816
796
|
//#endregion
|
|
817
|
-
//#region src/component/component-
|
|
797
|
+
//#region src/component/component-detection.ts
|
|
798
|
+
/**
|
|
799
|
+
* Hints for component collector
|
|
800
|
+
*/
|
|
801
|
+
const ComponentDetectionHint = {
|
|
802
|
+
...JsxDetectionHint,
|
|
803
|
+
DoNotIncludeFunctionDefinedAsArrayFlatMapCallback: 1n << 17n,
|
|
804
|
+
DoNotIncludeFunctionDefinedAsArrayMapCallback: 1n << 16n,
|
|
805
|
+
DoNotIncludeFunctionDefinedInArrayExpression: 1n << 15n,
|
|
806
|
+
DoNotIncludeFunctionDefinedInArrayPattern: 1n << 14n,
|
|
807
|
+
DoNotIncludeFunctionDefinedOnClassMethod: 1n << 12n,
|
|
808
|
+
DoNotIncludeFunctionDefinedOnClassProperty: 1n << 13n,
|
|
809
|
+
DoNotIncludeFunctionDefinedOnObjectMethod: 1n << 11n
|
|
810
|
+
};
|
|
811
|
+
/**
|
|
812
|
+
* Default component detection hint
|
|
813
|
+
*/
|
|
814
|
+
const DEFAULT_COMPONENT_DETECTION_HINT = 0n | ComponentDetectionHint.DoNotIncludeJsxWithBigIntValue | ComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | ComponentDetectionHint.DoNotIncludeJsxWithNumberValue | ComponentDetectionHint.DoNotIncludeJsxWithStringValue | ComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayFlatMapCallback | ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback | ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression | ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern | ComponentDetectionHint.RequireAllArrayElementsToBeJsx | ComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | ComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx;
|
|
818
815
|
/**
|
|
819
816
|
* Check whether given node is a render method of a class component
|
|
820
817
|
* @example
|
|
@@ -830,11 +827,8 @@ function isFunctionWithLooseComponentName(context, fn, allowNone = false) {
|
|
|
830
827
|
function isRenderMethodLike(node) {
|
|
831
828
|
return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name.startsWith("render") && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
|
|
832
829
|
}
|
|
833
|
-
|
|
834
|
-
//#endregion
|
|
835
|
-
//#region src/component/component-definition.ts
|
|
836
830
|
/**
|
|
837
|
-
* Check if the given node is a function within a render method of a class component
|
|
831
|
+
* Check if the given node is a function within a render method of a class component
|
|
838
832
|
*
|
|
839
833
|
* @param node The AST node to check
|
|
840
834
|
* @returns `true` if the node is a render function inside a class component
|
|
@@ -852,6 +846,77 @@ function isRenderMethodCallback(node) {
|
|
|
852
846
|
return greatGrandparent != null && isRenderMethodLike(parent) && isClassComponent(greatGrandparent);
|
|
853
847
|
}
|
|
854
848
|
/**
|
|
849
|
+
* Unsafe check whether given node is a render function
|
|
850
|
+
* ```tsx
|
|
851
|
+
* const renderRow = () => <div />
|
|
852
|
+
* ` ^^^^^^^^^^^^`
|
|
853
|
+
* _ = <Component renderRow={() => <div />} />
|
|
854
|
+
* ` ^^^^^^^^^^^^^ `
|
|
855
|
+
* ```
|
|
856
|
+
* @param context The rule context
|
|
857
|
+
* @param node The AST node to check
|
|
858
|
+
* @returns `true` if node is a render function, `false` if not
|
|
859
|
+
*/
|
|
860
|
+
function isRenderFunctionLoose(context, node) {
|
|
861
|
+
if (!ast.isFunction(node)) return false;
|
|
862
|
+
const id = ast.getFunctionId(node);
|
|
863
|
+
switch (true) {
|
|
864
|
+
case id?.type === AST_NODE_TYPES.Identifier: return id.name.startsWith("render");
|
|
865
|
+
case id?.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier: return id.property.name.startsWith("render");
|
|
866
|
+
case node.parent.type === AST_NODE_TYPES.JSXExpressionContainer && node.parent.parent.type === AST_NODE_TYPES.JSXAttribute && node.parent.parent.name.type === AST_NODE_TYPES.JSXIdentifier: return node.parent.parent.name.name.startsWith("render");
|
|
867
|
+
}
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Unsafe check whether given JSXAttribute is a render prop
|
|
872
|
+
* ```tsx
|
|
873
|
+
* _ = <Component renderRow={() => <div />} />
|
|
874
|
+
* ` ^^^^^^^^^^^^^^^^^^^^^^^^^ `
|
|
875
|
+
* ```
|
|
876
|
+
* @param context The rule context
|
|
877
|
+
* @param node The AST node to check
|
|
878
|
+
* @returns `true` if node is a render prop, `false` if not
|
|
879
|
+
*/
|
|
880
|
+
function isRenderPropLoose(context, node) {
|
|
881
|
+
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) return false;
|
|
882
|
+
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && isRenderFunctionLoose(context, node.value.expression);
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Unsafe check whether given node is declared directly inside a render property
|
|
886
|
+
* ```tsx
|
|
887
|
+
* const rows = { render: () => <div /> }
|
|
888
|
+
* ` ^^^^^^^^^^^^^ `
|
|
889
|
+
* _ = <Component rows={ [{ render: () => <div /> }] } />
|
|
890
|
+
* ` ^^^^^^^^^^^^^ `
|
|
891
|
+
* ```
|
|
892
|
+
* @internal
|
|
893
|
+
* @param node The AST node to check
|
|
894
|
+
* @returns `true` if component is declared inside a render property, `false` if not
|
|
895
|
+
*/
|
|
896
|
+
function isDirectValueOfRenderPropertyLoose(node) {
|
|
897
|
+
const matching = (node) => {
|
|
898
|
+
return node.type === AST_NODE_TYPES.Property && node.key.type === AST_NODE_TYPES.Identifier && node.key.name.startsWith("render");
|
|
899
|
+
};
|
|
900
|
+
return matching(node) || node.parent != null && matching(node.parent);
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Unsafe check whether given node is declared inside a render prop
|
|
904
|
+
* ```tsx
|
|
905
|
+
* _ = <Component renderRow={"node"} />
|
|
906
|
+
* ` ^^^^^^ `
|
|
907
|
+
* _ = <Component rows={ [{ render: "node" }] } />
|
|
908
|
+
* ` ^^^^^^ `
|
|
909
|
+
* ```
|
|
910
|
+
* @param node The AST node to check
|
|
911
|
+
* @returns `true` if component is declared inside a render prop, `false` if not
|
|
912
|
+
*/
|
|
913
|
+
function isDeclaredInRenderPropLoose(node) {
|
|
914
|
+
if (isDirectValueOfRenderPropertyLoose(node)) return true;
|
|
915
|
+
const parent = ast.findParentNode(node, ast.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
916
|
+
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) return false;
|
|
917
|
+
return parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
855
920
|
* Check if a function node should be excluded based on provided detection hints
|
|
856
921
|
*
|
|
857
922
|
* @param node The function node to check
|
|
@@ -860,13 +925,13 @@ function isRenderMethodCallback(node) {
|
|
|
860
925
|
*/
|
|
861
926
|
function shouldExcludeBasedOnHint(node, hint) {
|
|
862
927
|
switch (true) {
|
|
863
|
-
case
|
|
864
|
-
case
|
|
865
|
-
case
|
|
866
|
-
case
|
|
867
|
-
case
|
|
868
|
-
case
|
|
869
|
-
case
|
|
928
|
+
case ast.isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(node) && node.parent.type === AST_NODE_TYPES.Property && node.parent.parent.type === AST_NODE_TYPES.ObjectExpression: return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedOnObjectMethod);
|
|
929
|
+
case ast.isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(node) && node.parent.type === AST_NODE_TYPES.MethodDefinition: return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedOnClassMethod);
|
|
930
|
+
case ast.isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(node) && node.parent.type === AST_NODE_TYPES.Property: return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedOnClassProperty);
|
|
931
|
+
case node.parent.type === AST_NODE_TYPES.ArrayPattern: return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern);
|
|
932
|
+
case node.parent.type === AST_NODE_TYPES.ArrayExpression: return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression);
|
|
933
|
+
case node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee.type === AST_NODE_TYPES.MemberExpression && node.parent.callee.property.type === AST_NODE_TYPES.Identifier && node.parent.callee.property.name === "map": return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback);
|
|
934
|
+
case node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee.type === AST_NODE_TYPES.MemberExpression && node.parent.callee.property.type === AST_NODE_TYPES.Identifier && node.parent.callee.property.name === "flatMap": return !!(hint & ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayFlatMapCallback);
|
|
870
935
|
}
|
|
871
936
|
return false;
|
|
872
937
|
}
|
|
@@ -913,15 +978,12 @@ function isComponentDefinition(context, node, hint) {
|
|
|
913
978
|
* Component flag constants
|
|
914
979
|
*/
|
|
915
980
|
const ComponentFlag = {
|
|
916
|
-
None: 0n,
|
|
917
|
-
PureComponent: 1n << 0n,
|
|
918
981
|
CreateElement: 1n << 1n,
|
|
982
|
+
ForwardRef: 1n << 3n,
|
|
919
983
|
Memo: 1n << 2n,
|
|
920
|
-
|
|
984
|
+
None: 0n,
|
|
985
|
+
PureComponent: 1n << 0n
|
|
921
986
|
};
|
|
922
|
-
|
|
923
|
-
//#endregion
|
|
924
|
-
//#region src/component/component-init-path.ts
|
|
925
987
|
/**
|
|
926
988
|
* Get component flag from init path
|
|
927
989
|
* @param initPath The init path of the function component
|
|
@@ -936,7 +998,7 @@ function getComponentFlagFromInitPath(initPath) {
|
|
|
936
998
|
|
|
937
999
|
//#endregion
|
|
938
1000
|
//#region src/component/component-collector.ts
|
|
939
|
-
const idGen$1 = new IdGenerator("
|
|
1001
|
+
const idGen$1 = new IdGenerator("function-component:");
|
|
940
1002
|
/**
|
|
941
1003
|
* Get a ctx and visitor object for the rule to collect function components
|
|
942
1004
|
* @param context The ESLint rule context
|
|
@@ -1036,7 +1098,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1036
1098
|
|
|
1037
1099
|
//#endregion
|
|
1038
1100
|
//#region src/component/component-collector-legacy.ts
|
|
1039
|
-
const idGen = new IdGenerator("
|
|
1101
|
+
const idGen = new IdGenerator("class-component:");
|
|
1040
1102
|
/**
|
|
1041
1103
|
* Get a ctx and visitor object for the rule to collect class componentss
|
|
1042
1104
|
* @param context The ESLint rule context
|
|
@@ -1094,7 +1156,7 @@ function isAssignmentToThisState(node) {
|
|
|
1094
1156
|
}
|
|
1095
1157
|
|
|
1096
1158
|
//#endregion
|
|
1097
|
-
//#region src/component/component-method
|
|
1159
|
+
//#region src/component/component-method.ts
|
|
1098
1160
|
/**
|
|
1099
1161
|
* Create a lifecycle method checker function
|
|
1100
1162
|
* @param methodName The lifecycle method name
|
|
@@ -1121,9 +1183,6 @@ const isUnsafeComponentWillUpdate = createLifecycleChecker("UNSAFE_componentWill
|
|
|
1121
1183
|
const isGetDefaultProps = createLifecycleChecker("getDefaultProps", true);
|
|
1122
1184
|
const isGetDerivedStateFromProps = createLifecycleChecker("getDerivedStateFromProps", true);
|
|
1123
1185
|
const isGetDerivedStateFromError = createLifecycleChecker("getDerivedStateFromError", true);
|
|
1124
|
-
|
|
1125
|
-
//#endregion
|
|
1126
|
-
//#region src/component/component-method-callback.ts
|
|
1127
1186
|
/**
|
|
1128
1187
|
* Check if the given node is a componentDidMount callback
|
|
1129
1188
|
* @param node The node to check
|
|
@@ -1141,80 +1200,6 @@ function isComponentWillUnmountCallback(node) {
|
|
|
1141
1200
|
return ast.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
1142
1201
|
}
|
|
1143
1202
|
|
|
1144
|
-
//#endregion
|
|
1145
|
-
//#region src/component/component-render-prop.ts
|
|
1146
|
-
/**
|
|
1147
|
-
* Unsafe check whether given node is a render function
|
|
1148
|
-
* ```tsx
|
|
1149
|
-
* const renderRow = () => <div />
|
|
1150
|
-
* ` ^^^^^^^^^^^^`
|
|
1151
|
-
* _ = <Component renderRow={() => <div />} />
|
|
1152
|
-
* ` ^^^^^^^^^^^^^ `
|
|
1153
|
-
* ```
|
|
1154
|
-
* @param context The rule context
|
|
1155
|
-
* @param node The AST node to check
|
|
1156
|
-
* @returns `true` if node is a render function, `false` if not
|
|
1157
|
-
*/
|
|
1158
|
-
function isRenderFunctionLoose(context, node) {
|
|
1159
|
-
if (!ast.isFunction(node)) return false;
|
|
1160
|
-
const id = ast.getFunctionId(node);
|
|
1161
|
-
switch (true) {
|
|
1162
|
-
case id?.type === AST_NODE_TYPES.Identifier: return id.name.startsWith("render");
|
|
1163
|
-
case id?.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier: return id.property.name.startsWith("render");
|
|
1164
|
-
case node.parent.type === AST_NODE_TYPES.JSXExpressionContainer && node.parent.parent.type === AST_NODE_TYPES.JSXAttribute && node.parent.parent.name.type === AST_NODE_TYPES.JSXIdentifier: return node.parent.parent.name.name.startsWith("render");
|
|
1165
|
-
}
|
|
1166
|
-
return false;
|
|
1167
|
-
}
|
|
1168
|
-
/**
|
|
1169
|
-
* Unsafe check whether given JSXAttribute is a render prop
|
|
1170
|
-
* ```tsx
|
|
1171
|
-
* _ = <Component renderRow={() => <div />} />
|
|
1172
|
-
* ` ^^^^^^^^^^^^^^^^^^^^^^^^^ `
|
|
1173
|
-
* ```
|
|
1174
|
-
* @param context The rule context
|
|
1175
|
-
* @param node The AST node to check
|
|
1176
|
-
* @returns `true` if node is a render prop, `false` if not
|
|
1177
|
-
*/
|
|
1178
|
-
function isRenderPropLoose(context, node) {
|
|
1179
|
-
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) return false;
|
|
1180
|
-
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && isRenderFunctionLoose(context, node.value.expression);
|
|
1181
|
-
}
|
|
1182
|
-
/**
|
|
1183
|
-
* Unsafe check whether given node is declared directly inside a render property
|
|
1184
|
-
* ```tsx
|
|
1185
|
-
* const rows = { render: () => <div /> }
|
|
1186
|
-
* ` ^^^^^^^^^^^^^ `
|
|
1187
|
-
* _ = <Component rows={ [{ render: () => <div /> }] } />
|
|
1188
|
-
* ` ^^^^^^^^^^^^^ `
|
|
1189
|
-
* ```
|
|
1190
|
-
* @internal
|
|
1191
|
-
* @param node The AST node to check
|
|
1192
|
-
* @returns `true` if component is declared inside a render property, `false` if not
|
|
1193
|
-
*/
|
|
1194
|
-
function isDirectValueOfRenderPropertyLoose(node) {
|
|
1195
|
-
const matching = (node) => {
|
|
1196
|
-
return node.type === AST_NODE_TYPES.Property && node.key.type === AST_NODE_TYPES.Identifier && node.key.name.startsWith("render");
|
|
1197
|
-
};
|
|
1198
|
-
return matching(node) || node.parent != null && matching(node.parent);
|
|
1199
|
-
}
|
|
1200
|
-
/**
|
|
1201
|
-
* Unsafe check whether given node is declared inside a render prop
|
|
1202
|
-
* ```tsx
|
|
1203
|
-
* _ = <Component renderRow={"node"} />
|
|
1204
|
-
* ` ^^^^^^ `
|
|
1205
|
-
* _ = <Component rows={ [{ render: "node" }] } />
|
|
1206
|
-
* ` ^^^^^^ `
|
|
1207
|
-
* ```
|
|
1208
|
-
* @param node The AST node to check
|
|
1209
|
-
* @returns `true` if component is declared inside a render prop, `false` if not
|
|
1210
|
-
*/
|
|
1211
|
-
function isDeclaredInRenderPropLoose(node) {
|
|
1212
|
-
if (isDirectValueOfRenderPropertyLoose(node)) return true;
|
|
1213
|
-
const parent = ast.findParentNode(node, ast.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
1214
|
-
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) return false;
|
|
1215
|
-
return parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
1203
|
//#endregion
|
|
1219
1204
|
//#region src/hierarchy/find-enclosing-component-or-hook.ts
|
|
1220
1205
|
/**
|
|
@@ -1255,12 +1240,18 @@ function isInsideComponentOrHook(node) {
|
|
|
1255
1240
|
* @param name The name to check
|
|
1256
1241
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
1257
1242
|
*/
|
|
1258
|
-
function
|
|
1243
|
+
function isRefLikeName(name) {
|
|
1259
1244
|
return name === "ref" || name.endsWith("Ref");
|
|
1260
1245
|
}
|
|
1261
1246
|
|
|
1262
1247
|
//#endregion
|
|
1263
|
-
//#region src/ref/
|
|
1248
|
+
//#region src/ref/ref-id.ts
|
|
1249
|
+
function isRefId(node) {
|
|
1250
|
+
return node.type === AST_NODE_TYPES.Identifier && isRefLikeName(node.name);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
//#endregion
|
|
1254
|
+
//#region src/ref/ref-init.ts
|
|
1264
1255
|
/**
|
|
1265
1256
|
* Check if the variable with the given name is initialized or derived from a ref
|
|
1266
1257
|
* @param name The variable name
|
|
@@ -1282,7 +1273,7 @@ function getRefInit(name, initialScope) {
|
|
|
1282
1273
|
const init = node.init;
|
|
1283
1274
|
if (init == null) continue;
|
|
1284
1275
|
switch (true) {
|
|
1285
|
-
case init.type === AST_NODE_TYPES$1.MemberExpression && init.object.type === AST_NODE_TYPES$1.Identifier &&
|
|
1276
|
+
case init.type === AST_NODE_TYPES$1.MemberExpression && init.object.type === AST_NODE_TYPES$1.Identifier && isRefLikeName(init.object.name): return init;
|
|
1286
1277
|
case init.type === AST_NODE_TYPES$1.CallExpression && isUseRefCall(init): return init;
|
|
1287
1278
|
}
|
|
1288
1279
|
}
|
|
@@ -1290,4 +1281,4 @@ function getRefInit(name, initialScope) {
|
|
|
1290
1281
|
}
|
|
1291
1282
|
|
|
1292
1283
|
//#endregion
|
|
1293
|
-
export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, findEnclosingComponentOrHook, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, getRefInit, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isInsideComponentOrHook, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall,
|
|
1284
|
+
export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, findEnclosingComponentOrHook, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, getRefInit, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isInsideComponentOrHook, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefId, isRefLikeName, isRender, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStoreCall, isUseTransitionCall, resolveJsxAttributeValue, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "3.0.0-next.
|
|
3
|
+
"version": "3.0.0-next.20",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and patterns.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"./package.json"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@typescript-eslint/scope-manager": "
|
|
34
|
-
"@typescript-eslint/types": "
|
|
35
|
-
"@typescript-eslint/utils": "
|
|
33
|
+
"@typescript-eslint/scope-manager": "canary",
|
|
34
|
+
"@typescript-eslint/types": "canary",
|
|
35
|
+
"@typescript-eslint/utils": "canary",
|
|
36
36
|
"ts-pattern": "^5.9.0",
|
|
37
|
-
"@eslint-react/ast": "3.0.0-next.
|
|
38
|
-
"@eslint-react/
|
|
39
|
-
"@eslint-react/
|
|
40
|
-
"@eslint-react/var": "3.0.0-next.
|
|
37
|
+
"@eslint-react/ast": "3.0.0-next.20",
|
|
38
|
+
"@eslint-react/eff": "3.0.0-next.20",
|
|
39
|
+
"@eslint-react/shared": "3.0.0-next.20",
|
|
40
|
+
"@eslint-react/var": "3.0.0-next.20"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"tsdown": "^0.20.3",
|