react_hooksutil

package
v0.22.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2026 License: MIT, MIT Imports: 5 Imported by: 0

Documentation

Overview

Package react_hooksutil holds the AST helpers shared by every rule in the `eslint-plugin-react-hooks` port.

Both `rules-of-hooks` and `exhaustive-deps` need the same set of queries — "is this a hook callee?", "is this enclosing function a component?", "what's the display name of this function-like?", "is this a `React.<x>` member access?", etc. Putting them here keeps semantics consistent across rules and removes the second (and third) copy of every predicate.

Naming convention follows the rest of the codebase: predicates start with `Is*`, getters with `Get*`. General AST helpers stay in `internal/utils`; this package composes them where they already exist.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AccessChainRootIdentifier

func AccessChainRootIdentifier(node *ast.Node) *ast.Node

AccessChainRootIdentifier returns the identifier at the root of an access chain like `value.x.y` or `(value as T)["x"]`.

func AdditionalHooksFromSettings

func AdditionalHooksFromSettings(settings map[string]interface{}, key string) *regexp.Regexp

AdditionalHooksFromSettings reads `settings['react-hooks'].<key>` (typically `additionalHooks` for exhaustive-deps, or `additionalEffectHooks` for rules-of-hooks) and compiles it as a regex. Returns nil when the setting is absent or the pattern fails to compile — mirroring upstream's lenient behavior of silently ignoring malformed regex strings.

func CallsHooksOrCreatesJsx

func CallsHooksOrCreatesJsx(fn *ast.Node) bool

CallsHooksOrCreatesJsx reports whether `fn` directly creates JSX or directly calls a compiler hook. Nested function bodies are skipped, matching React Compiler's traversal boundary.

func ContainsNode

func ContainsNode(ancestor, descendant *ast.Node) bool

ContainsNode reports whether `descendant` is inside `ancestor` in the same source file.

func FindEnclosingFunction

func FindEnclosingFunction(node *ast.Node) *ast.Node

FindEnclosingFunction walks up from `node` and returns the nearest function-like ancestor, or nil when `node` is at top level.

func GetForwardRefOrMemoCallbackCall

func GetForwardRefOrMemoCallbackCall(fn *ast.Node, name string) *ast.Node

GetForwardRefOrMemoCallbackCall is kept for existing callers that only check React's `memo` / `forwardRef` callback shapes.

func GetFunctionBody

func GetFunctionBody(fn *ast.Node) *ast.Node

GetFunctionBody returns the body of a function-like node — Block for normal functions, the BlockOrExpression body for arrow functions, or nil for abstract/declared signatures.

func GetFunctionName

func GetFunctionName(fn *ast.Node) *ast.Node

GetFunctionName mirrors upstream's `getFunctionName(node)`. Returns:

  • For named FunctionDeclaration / FunctionExpression: the `id` Identifier.
  • For MethodDeclaration / GetAccessor / SetAccessor inside an ObjectLiteralExpression: the method's own name.
  • For ArrowFunction / anonymous FunctionExpression: the assignment target — VariableDeclaration name, BinaryExpression LHS, PropertyAssignment name, BindingElement name, or ShorthandPropertyAssignment name.
  • nil otherwise.

MethodDeclaration / GetAccessor / SetAccessor inside a class body intentionally returns nil so the class-member branch can take over.

func GetReactCallbackCall

func GetReactCallbackCall(fn *ast.Node, name string) *ast.Node

GetReactCallbackCall returns the CallExpression when `fn` is the immediate argument of a call whose callee is `<name>` or `React.<name>`. Parenthesized callback expressions are transparent: `memo((() => null))` is the same callback shape as `memo(() => null)`.

func HasAsyncModifier

func HasAsyncModifier(fn *ast.Node) bool

HasAsyncModifier reports whether the function-like node carries the `async` modifier.

func ImportSpecifierImportedName

func ImportSpecifierImportedName(spec *ast.ImportSpecifier) string

ImportSpecifierImportedName returns the module-exported name for an import specifier. For `import {foo as bar}`, this is `foo`; for `import {bar}`, this is `bar`.

func IsClassMember

func IsClassMember(fn *ast.Node) bool

IsClassMember reports whether `fn` is a member of a class — either a MethodDeclaration / GetAccessor / SetAccessor / Constructor whose direct parent is a class, or an ArrowFunction / FunctionExpression that initializes a class PropertyDeclaration (class-field arrow).

func IsCompilerFunctionKind

func IsCompilerFunctionKind(node *ast.Node) bool

IsCompilerFunctionKind reports whether `node` is one of the function syntaxes that React Compiler's Factories diagnostic traverses: FunctionDeclaration, FunctionExpression, or ArrowFunctionExpression.

func IsCompilerHookCallee

func IsCompilerHookCallee(node *ast.Node) bool

IsCompilerHookCallee is the React Compiler variant of IsHookCallee: it accepts `useFoo` / `Namespace.useFoo`, but not the bare `use`.

func IsCompilerHookName

func IsCompilerHookName(s string) bool

IsCompilerHookName reports whether `s` follows the React Compiler hook-like naming convention. Unlike rules-of-hooks, the compiler lint predicates do not treat the bare `use` identifier as a custom hook name.

func IsCompilerNonNode

func IsCompilerNonNode(node *ast.Node) bool

IsCompilerNonNode mirrors React Compiler's isNonNode helper for returns whose value is definitely not a React node.

func IsComponentNameStr

func IsComponentNameStr(s string) bool

IsComponentNameStr reports whether `s` looks like a React component name — PascalCase. Upstream's `isComponentName` is identical.

func IsComponentOrHookFn

func IsComponentOrHookFn(fn *ast.Node) bool

IsComponentOrHookFn reports whether the function-like itself is a React component or hook (named appropriately, or an anonymous arg to forwardRef / memo). Mirrors upstream's `isDirectlyInsideComponentOrHook` predicate at the function level.

func IsEffectStyleHookName

func IsEffectStyleHookName(name string) bool

IsEffectStyleHookName reports whether the bare hook name (no `React.` prefix) parses as an effect-style hook by the `Effect($|[^a-z])` rule. Used by exhaustive-deps to gate the "extra over-specified deps are okay" exception that effects get but memo / callback don't.

func IsForwardRefOrMemoCallback

func IsForwardRefOrMemoCallback(fn *ast.Node, name string) bool

IsForwardRefOrMemoCallback reports whether `fn` is the immediate argument of a CallExpression whose callee is `<name>` or `React.<name>`.

func IsFunctionLikeContainer

func IsFunctionLikeContainer(node *ast.Node) bool

IsFunctionLikeContainer keeps the react-hooks shared API while delegating to the repository-wide function-scope boundary helper.

func IsHookCallee

func IsHookCallee(node *ast.Node) bool

IsHookCallee mirrors upstream's `isHook(node)`: the callee is either an Identifier whose name is a hook, or a non-computed member expression `Namespace.useFoo` whose object is a PascalCase identifier and whose property is itself a hook name.

func IsHookName

func IsHookName(s string) bool

IsHookName reports whether `s` follows the React hook naming convention: either the bare `use` (the React `use(...)` hook) or `useFoo` / `use1` (`use` followed by uppercase letter or digit).

func IsInsideComponentOrHook

func IsInsideComponentOrHook(node *ast.Node) bool

IsInsideComponentOrHook walks up from `node` and returns true once any ancestor function-like classifies as a component or hook.

func IsManualUseMemoCallee

func IsManualUseMemoCallee(node *ast.Node, typeChecker *checker.Checker) bool

IsManualUseMemoCallee reports whether `node` is a direct `useMemo` or `React.useMemo` callee according to React Compiler's manual memoization input surface. It intentionally does not recognize import aliases or element-access forms; existing React Compiler lint ports rely on the same direct-call contract.

func IsReactCalleeNamed

func IsReactCalleeNamed(node *ast.Node, name string) bool

IsReactCalleeNamed reports whether `node` is `<name>` (bare identifier) or `React.<name>` (PropertyAccessExpression with object `React` and property `<name>`). Mirrors upstream's `isReactFunction(node, functionName)`.

func IsUseEffectEventCallee

func IsUseEffectEventCallee(node *ast.Node) bool

IsUseEffectEventCallee reports whether `node` is the bare `useEffectEvent` or `React.useEffectEvent` callee.

func IsUseIdentifier

func IsUseIdentifier(node *ast.Node) bool

IsUseIdentifier reports whether `node` is the React `use(...)` callee — either bare `use` or `React.use`.

func IsValidCompilerComponentParams

func IsValidCompilerComponentParams(fn *ast.Node) bool

IsValidCompilerComponentParams mirrors React Compiler's isValidComponentParams helper.

func ReturnsCompilerNonNode

func ReturnsCompilerNonNode(fn *ast.Node) bool

ReturnsCompilerNonNode mirrors React Compiler's returnsNonNode helper.

func StripReactNamespace

func StripReactNamespace(node *ast.Node) *ast.Node

StripReactNamespace returns the property identifier of a `React.foo` member expression, or the original node otherwise. Mirrors upstream's `getNodeWithoutReactNamespace`. Paren wrappers are peeled transparently — tsgo preserves them where ESTree flattens.

Types

type AssignmentTargetIdentifier

type AssignmentTargetIdentifier struct {
	Identifier *ast.Node
	Node       *ast.Node
	Name       string
}

AssignmentTargetIdentifier is a binding written by an assignment target. Identifier points at the actual identifier node, while Node is the broader target to report when destructuring defaults need the full assignment node.

func CollectAssignmentTargetIdentifiers

func CollectAssignmentTargetIdentifiers(node *ast.Node) []AssignmentTargetIdentifier

CollectAssignmentTargetIdentifiers returns every identifier written by an assignment target, including nested array/object destructuring targets and default values in destructuring patterns. It only peels parentheses, matching the upstream globals rule's assignment-target handling.

func CollectAssignmentTargetIdentifiersThroughAssertions

func CollectAssignmentTargetIdentifiersThroughAssertions(node *ast.Node) []AssignmentTargetIdentifier

CollectAssignmentTargetIdentifiersThroughAssertions is the same assignment target collector, but it also peels TS assertion wrappers before matching the target shape.

type CompilerReactFunctionType

type CompilerReactFunctionType string
const (
	CompilerReactFunctionComponent CompilerReactFunctionType = "Component"
	CompilerReactFunctionHook      CompilerReactFunctionType = "Hook"
)

func GetCompilerReactFunctionType

func GetCompilerReactFunctionType(fn *ast.Node) CompilerReactFunctionType

GetCompilerReactFunctionType mirrors the React Compiler classifier used by the Factories diagnostic: a PascalCase function is a component only when it directly creates JSX or calls a hook, has component-like parameters, and does not return obviously non-ReactNode values; a hook-like function must directly create JSX or call a hook; memo/forwardRef callbacks are components.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL