376
return false;
377
}
378
case "infer": {
379
+ const hookPattern = pass.opts.environment?.hookPattern ?? null;
380
return (
381
// Component declarations are known components
382
(fn.isFunctionDeclaration() && isComponentDeclaration(fn.node)) ||
383
// Otherwise check if this is a component or hook-like function
383
- isComponentOrHookLike(fn)
384
+ isComponentOrHookLike(fn, hookPattern)
385
);
386
}
387
case "all": {
415
return hasUseMemoCache;
416
}
417
417
-function isHookName(s: string): boolean {
418
+function isHookName(s: string, hookPattern: string | null): boolean {
419
+ if (hookPattern !== null) {
420
+ return new RegExp(hookPattern).test(s);
421
+ }
422
return /^use[A-Z0-9]/.test(s);
423
}
424
427
* containing a hook name.
428
*/
429
426
-function isHook(path: NodePath<t.Expression | t.PrivateName>): boolean {
430
+function isHook(
431
+ path: NodePath<t.Expression | t.PrivateName>,
432
+ hookPattern: string | null
433
+): boolean {
434
if (path.isIdentifier()) {
428
- return isHookName(path.node.name);
435
+ return isHookName(path.node.name, hookPattern);
436
} else if (
437
path.isMemberExpression() &&
438
!path.node.computed &&
432
- isHook(path.get("property"))
439
+ isHook(path.get("property"), hookPattern)
440
) {
441
const obj = path.get("object").node;
442
const isPascalCaseNameSpace = /^[A-Z].*/;
525
function isComponentOrHookLike(
526
node: NodePath<
527
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
521
- >
528
+ >,
529
+ hookPattern: string | null
530
): boolean {
531
const functionName = getFunctionName(node);
532
// Check if the name is component or hook like:
533
if (functionName !== null && isComponentName(functionName)) {
534
return (
535
// As an added check we also look for hook invocations or JSX
528
- callsHooksOrCreatesJsx(node) && isValidComponentParams(node.get("params"))
536
+ callsHooksOrCreatesJsx(node, hookPattern) &&
537
+ isValidComponentParams(node.get("params"))
538
);
530
- } else if (functionName !== null && isHook(functionName)) {
539
+ } else if (functionName !== null && isHook(functionName, hookPattern)) {
540
// Hooks have hook invocations or JSX, but can take any # of arguments
532
- return callsHooksOrCreatesJsx(node);
541
+ return callsHooksOrCreatesJsx(node, hookPattern);
542
}
543
544
/*
548
if (node.isFunctionExpression() || node.isArrowFunctionExpression()) {
549
if (isForwardRefCallback(node) || isMemoCallback(node)) {
550
// As an added check we also look for hook invocations or JSX
542
- return callsHooksOrCreatesJsx(node);
551
+ return callsHooksOrCreatesJsx(node, hookPattern);
552
} else {
553
return false;
554
}
556
return false;
557
}
558
550
-function callsHooksOrCreatesJsx(node: NodePath<t.Node>): boolean {
559
+function callsHooksOrCreatesJsx(
560
+ node: NodePath<t.Node>,
561
+ hookPattern: string | null
562
+): boolean {
563
let invokesHooks = false;
564
let createsJsx = false;
565
node.traverse({
568
},
569
CallExpression(call) {
570
const callee = call.get("callee");
559
- if (callee.isExpression() && isHook(callee)) {
571
+ if (callee.isExpression() && isHook(callee, hookPattern)) {
572
invokesHooks = true;
573
}
574
},