"""Plugin system for extending mypy.

At large scale the plugin system works as following:

* Plugins are collected from the corresponding mypy config file option
  (either via paths to Python files, or installed Python modules)
  and imported using importlib.

* Every module should get an entry point function (called 'plugin' by default,
  but may be overridden in the config file) that should accept a single string
  argument that is a full mypy version (includes git commit hash for dev
  versions) and return a subclass of mypy.plugins.Plugin.

* All plugin class constructors should match the signature of mypy.plugin.Plugin
  (i.e. should accept an mypy.options.Options object), and *must* call
  super().__init__().

* At several steps during semantic analysis and type checking mypy calls
  special `get_xxx` methods on user plugins with a single string argument that
  is a fully qualified name (full name) of a relevant definition
  (see mypy.plugin.Plugin method docstrings for details).

* The plugins are called in the order they are passed in the config option.
  Every plugin must decide whether to act on a given full name. The first
  plugin that returns non-None object will be used.

* The above decision should be made using the limited common API specified by
  mypy.plugin.CommonPluginApi.

* The callback returned by the plugin will be called with a larger context that
  includes relevant current state (e.g. a default return type, or a default
  attribute type) and a wider relevant API provider (e.g.
  SemanticAnalyzerPluginInterface or CheckerPluginInterface).

* The result of this is used for further processing. See various `XxxContext`
  named tuples for details about which information is given to each hook.

Plugin developers should ensure that their plugins work well in incremental and
daemon modes. In particular, plugins should not hold global state, and should
always call add_plugin_dependency() in plugin hooks called during semantic
analysis. See the method docstring for more details.

There is no dedicated cache storage for plugins, but plugins can store
per-TypeInfo data in a special .metadata attribute that is serialized to the
mypy caches between incremental runs. To avoid collisions between plugins, they
are encouraged to store their state under a dedicated key coinciding with
plugin name in the metadata dictionary. Every value stored there must be
JSON-serializable.

## Notes about the semantic analyzer

Mypy 0.710 introduced a new semantic analyzer that changed how plugins are
expected to work in several notable ways (from mypy 0.730 the old semantic
analyzer is no longer available):

1. The order of processing AST nodes in modules is different. The old semantic
   analyzer processed modules in textual order, one module at a time. The new
   semantic analyzer first processes the module top levels, including bodies of
   any top-level classes and classes nested within classes. ("Top-level" here
   means "not nested within a function/method".) Functions and methods are
   processed only after module top levels have been finished. If there is an
   import cycle, all module top levels in the cycle are processed before
   processing any functions or methods. Each unit of processing (a module top
   level or a function/method) is called a *target*.

   This also means that function signatures in the same module have not been
   analyzed yet when analyzing the module top level. If you need access to
   a function signature, you'll need to explicitly analyze the signature first
   using `anal_type()`.

2. Each target can be processed multiple times. This may happen if some forward
   references are not ready yet, for example. This means that semantic analyzer
   related plugin hooks can be called multiple times for the same full name.
   These plugin methods must thus be idempotent.

3. The `anal_type` API function returns None if some part of the type is not
   available yet. If this happens, the current target being analyzed will be
   *deferred*, which means that it will be processed again soon, in the hope
   that additional dependencies will be available. This may happen if there are
   forward references to types or inter-module references to types within an
   import cycle.

   Note that if there is a circular definition, mypy may decide to stop
   processing to avoid an infinite number of iterations. When this happens,
   `anal_type` will generate an error and return an `AnyType` type object
   during the final iteration (instead of None).

4. There is a new API method `defer()`. This can be used to explicitly request
   the current target to be reprocessed one more time. You don't need this
   to call this if `anal_type` returns None, however.

5. There is a new API property `final_iteration`, which is true once mypy
   detected no progress during the previous iteration or if the maximum
   semantic analysis iteration count has been reached. You must never
   defer during the final iteration, as it will cause a crash.

6. The `node` attribute of SymbolTableNode objects may contain a reference to
   a PlaceholderNode object. This object means that this definition has not
   been fully processed yet. If you encounter a PlaceholderNode, you should
   defer unless it's the final iteration. If it's the final iteration, you
   should generate an error message. It usually means that there's a cyclic
   definition that cannot be resolved by mypy. PlaceholderNodes can only refer
   to references inside an import cycle. If you are looking up things from
   another module, such as the builtins, that is outside the current module or
   import cycle, you can safely assume that you won't receive a placeholder.

When testing your plugin, you should have a test case that forces a module top
level to be processed multiple times. The easiest way to do this is to include
a forward reference to a class in a top-level annotation. Example:

    c: C  # Forward reference causes second analysis pass
    class C: pass

Note that a forward reference in a function signature won't trigger another
pass, since all functions are processed only after the top level has been fully
analyzed.

You can use `api.options.new_semantic_analyzer` to check whether the new
semantic analyzer is enabled (it's always true in mypy 0.730 and later).
"""

from __future__ import annotations

from abc import abstractmethod
from typing import Any, Callable, NamedTuple, TypeVar

from mypy_extensions import mypyc_attr, trait

from mypy.errorcodes import ErrorCode
from mypy.lookup import lookup_fully_qualified
from mypy.message_registry import ErrorMessage
from mypy.messages import MessageBuilder
from mypy.nodes import (
    ArgKind,
    CallExpr,
    ClassDef,
    Context,
    Expression,
    MypyFile,
    SymbolTableNode,
    TypeInfo,
)
from mypy.options import Options
from mypy.tvar_scope import TypeVarLikeScope
from mypy.types import (
    CallableType,
    FunctionLike,
    Instance,
    ProperType,
    Type,
    TypeList,
    UnboundType,
)


@trait
class TypeAnalyzerPluginInterface:
    """Interface for accessing semantic analyzer functionality in plugins.

    Methods docstrings contain only basic info. Look for corresponding implementation
    docstrings in typeanal.py for more details.
    """

    # An options object. Note: these are the cloned options for the current file.
    # This might be different from Plugin.options (that contains default/global options)
    # if there are per-file options in the config. This applies to all other interfaces
    # in this file.
    options: Options

    @abstractmethod
    def fail(self, msg: str, ctx: Context, *, code: ErrorCode | None = None) -> None:
        """Emit an error message at given location."""
        raise NotImplementedError

    @abstractmethod
    def named_type(self, name: str, args: list[Type]) -> Instance:
        """Construct an instance of a builtin type with given name."""
        raise NotImplementedError

    @abstractmethod
    def analyze_type(self, typ: Type) -> Type:
        """Analyze an unbound type using the default mypy logic."""
        raise NotImplementedError

    @abstractmethod
    def analyze_callable_args(
        self, arglist: TypeList
    ) -> tuple[list[Type], list[ArgKind], list[str | None]] | None:
        """Find types, kinds, and names of arguments from extended callable syntax."""
        raise NotImplementedError


# A context for a hook that semantically analyzes an unbound type.
class AnalyzeTypeContext(NamedTuple):
    type: UnboundType  # Type to analyze
    context: Context  # Relevant location context (e.g. for error messages)
    api: TypeAnalyzerPluginInterface


@mypyc_attr(allow_interpreted_subclasses=True)
class CommonPluginApi:
    """
    A common plugin API (shared between semantic analysis and type checking phases)
    that all plugin hooks get independently of the context.
    """

    # Global mypy options.
    # Per-file options can be only accessed on various
    # XxxPluginInterface classes.
    options: Options

    @abstractmethod
    def lookup_fully_qualified(self, fullname: str) -> SymbolTableNode | None:
        """Lookup a symbol by its full name (including module).

        This lookup function available for all plugins. Return None if a name
        is not found. This function doesn't support lookup from current scope.
        Use SemanticAnalyzerPluginInterface.lookup_qualified() for this."""
        raise NotImplementedError


@trait
class CheckerPluginInterface:
    """Interface for accessing type checker functionality in plugins.

    Methods docstrings contain only basic info. Look for corresponding implementation
    docstrings in checker.py for more details.
    """

    msg: MessageBuilder
    options: Options
    path: str

    # Type context for type inference
    @property
    @abstractmethod
    def type_context(self) -> list[Type | None]:
        """Return the type context of the plugin"""
        raise NotImplementedError

    @abstractmethod
    def fail(
        self, msg: str | ErrorMessage, ctx: Context, *, code: ErrorCode | None = None
    ) -> None:
        """Emit an error message at given location."""
        raise NotImplementedError

    @abstractmethod
    def named_generic_type(self, name: str, args: list[Type]) -> Instance:
        """Construct an instance of a builtin type with given type arguments."""
        raise NotImplementedError

    @abstractmethod
    def get_expression_type(self, node: Expression, type_context: Type | None = None) -> Type:
        """Checks the type of the given expression."""
        raise NotImplementedError


@trait
class SemanticAnalyzerPluginInterface:
    """Interface for accessing semantic analyzer functionality in plugins.

    Methods docstrings contain only basic info. Look for corresponding implementation
    docstrings in semanal.py for more details.

    # TODO: clean-up lookup functions.
    """

    modules: dict[str, MypyFile]
    # Options for current file.
    options: Options
    cur_mod_id: str
    msg: MessageBuilder

    @abstractmethod
    def named_type(self, fullname: str, args: list[Type] | None = None) -> Instance:
        """Construct an instance of a builtin type with given type arguments."""
        raise NotImplementedError

    @abstractmethod
    def builtin_type(self, fully_qualified_name: str) -> Instance:
        """Legacy function -- use named_type() instead."""
        # NOTE: Do not delete this since many plugins may still use it.
        raise NotImplementedError

    @abstractmethod
    def named_type_or_none(self, fullname: str, args: list[Type] | None = None) -> Instance | None:
        """Construct an instance of a type with given type arguments.

        Return None if a type could not be constructed for the qualified
        type name. This is possible when the qualified name includes a
        module name and the module has not been imported.
        """
        raise NotImplementedError

    @abstractmethod
    def basic_new_typeinfo(self, name: str, basetype_or_fallback: Instance, line: int) -> TypeInfo:
        raise NotImplementedError

    @abstractmethod
    def parse_bool(self, expr: Expression) -> bool | None:
        """Parse True/False literals."""
        raise NotImplementedError

    @abstractmethod
    def parse_str_literal(self, expr: Expression) -> str | None:
        """Parse string literals."""

    @abstractmethod
    def fail(
        self,
        msg: str,
        ctx: Context,
        serious: bool = False,
        *,
        blocker: bool = False,
        code: ErrorCode | None = None,
    ) -> None:
        """Emit an error message at given location."""
        raise NotImplementedError

    @abstractmethod
    def anal_type(
        self,
        t: Type,
        *,
        tvar_scope: TypeVarLikeScope | None = None,
        allow_tuple_literal: bool = False,
        allow_unbound_tvars: bool = False,
        report_invalid_types: bool = True,
        third_pass: bool = False,
    ) -> Type | None:
        """Analyze an unbound type.

        Return None if some part of the type is not ready yet. In this
        case the current target being analyzed will be deferred and
        analyzed again.
        """
        raise NotImplementedError

    @abstractmethod
    def class_type(self, self_type: Type) -> Type:
        """Generate type of first argument of class methods from type of self."""
        raise NotImplementedError

    @abstractmethod
    def lookup_fully_qualified(self, name: str) -> SymbolTableNode:
        """Lookup a symbol by its fully qualified name.

        Raise an error if not found.
        """
        raise NotImplementedError

    @abstractmethod
    def lookup_fully_qualified_or_none(self, name: str) -> SymbolTableNode | None:
        """Lookup a symbol by its fully qualified name.

        Return None if not found.
        """
        raise NotImplementedError

    @abstractmethod
    def lookup_qualified(
        self, name: str, ctx: Context, suppress_errors: bool = False
    ) -> SymbolTableNode | None:
        """Lookup symbol using a name in current scope.

        This follows Python local->non-local->global->builtins rules.
        """
        raise NotImplementedError

    @abstractmethod
    def add_plugin_dependency(self, trigger: str, target: str | None = None) -> None:
        """Specify semantic dependencies for generated methods/variables.

        If the symbol with full name given by trigger is found to be stale by mypy,
        then the body of node with full name given by target will be re-checked.
        By default, this is the node that is currently analyzed.

        For example, the dataclass plugin adds a generated __init__ method with
        a signature that depends on types of attributes in ancestor classes. If any
        attribute in an ancestor class gets stale (modified), we need to reprocess
        the subclasses (and thus regenerate __init__ methods).

        This is used by fine-grained incremental mode (mypy daemon). See mypy/server/deps.py
        for more details.
        """
        raise NotImplementedError

    @abstractmethod
    def add_symbol_table_node(self, name: str, stnode: SymbolTableNode) -> Any:
        """Add node to global symbol table (or to nearest class if there is one)."""
        raise NotImplementedError

    @abstractmethod
    def qualified_name(self, n: str) -> str:
        """Make qualified name using current module and enclosing class (if any)."""
        raise NotImplementedError

    @abstractmethod
    def defer(self) -> None:
        """Call this to defer the processing of the current node.

        This will request an additional iteration of semantic analysis.
        """
        raise NotImplementedError

    @property
    @abstractmethod
    def final_iteration(self) -> bool:
        """Is this the final iteration of semantic analysis?"""
        raise NotImplementedError

    @property
    @abstractmethod
    def is_stub_file(self) -> bool:
        raise NotImplementedError

    @abstractmethod
    def analyze_simple_literal_type(self, rvalue: Expression, is_final: bool) -> Type | None:
        raise NotImplementedError


# A context for querying for configuration data about a module for
# cache invalidation purposes.
class ReportConfigContext(NamedTuple):
    id: str  # Module name
    path: str  # Module file path
    is_check: bool  # Is this invocation for checking whether the config matches


# A context for a function signature hook that infers a better signature for a
# function.  Note that argument types aren't available yet.  If you need them,
# you have to use a method hook instead.
class FunctionSigContext(NamedTuple):
    args: list[list[Expression]]  # Actual expressions for each formal argument
    default_signature: CallableType  # Original signature of the method
    context: Context  # Relevant location context (e.g. for error messages)
    api: CheckerPluginInterface


# A context for a function hook that infers the return type of a function with
# a special signature.
#
# A no-op callback would just return the inferred return type, but a useful
# callback at least sometimes can infer a more precise type.
class FunctionContext(NamedTuple):
    arg_types: list[list[Type]]  # List of actual caller types for each formal argument
    arg_kinds: list[list[ArgKind]]  # Ditto for argument kinds, see nodes.ARG_* constants
    # Names of formal parameters from the callee definition,
    # these will be sufficient in most cases.
    callee_arg_names: list[str | None]
    # Names of actual arguments in the call expression. For example,
    # in a situation like this:
    #     def func(**kwargs) -> None:
    #         pass
    #     func(kw1=1, kw2=2)
    # callee_arg_names will be ['kwargs'] and arg_names will be [['kw1', 'kw2']].
    arg_names: list[list[str | None]]
    default_return_type: Type  # Return type inferred from signature
    args: list[list[Expression]]  # Actual expressions for each formal argument
    context: Context  # Relevant location context (e.g. for error messages)
    api: CheckerPluginInterface


# A context for a method signature hook that infers a better signature for a
# method.  Note that argument types aren't available yet.  If you need them,
# you have to use a method hook instead.
# TODO: document ProperType in the plugin changelog/update issue.
class MethodSigContext(NamedTuple):
    type: ProperType  # Base object type for method call
    args: list[list[Expression]]  # Actual expressions for each formal argument
    default_signature: CallableType  # Original signature of the method
    context: Context  # Relevant location context (e.g. for error messages)
    api: CheckerPluginInterface


# A context for a method hook that infers the return type of a method with a
# special signature.
#
# This is very similar to FunctionContext (only differences are documented).
class MethodContext(NamedTuple):
    type: ProperType  # Base object type for method call
    arg_types: list[list[Type]]  # List of actual caller types for each formal argument
    # see FunctionContext for details about names and kinds
    arg_kinds: list[list[ArgKind]]
    callee_arg_names: list[str | None]
    arg_names: list[list[str | None]]
    default_return_type: Type  # Return type inferred by mypy
    args: list[list[Expression]]  # Lists of actual expressions for every formal argument
    context: Context
    api: CheckerPluginInterface


# A context for an attribute type hook that infers the type of an attribute.
class AttributeContext(NamedTuple):
    type: ProperType  # Type of object with attribute
    default_attr_type: Type  # Original attribute type
    context: Context  # Relevant location context (e.g. for error messages)
    api: CheckerPluginInterface


# A context for a class hook that modifies the class definition.
class ClassDefContext(NamedTuple):
    cls: ClassDef  # The class definition
    reason: Expression  # The expression being applied (decorator, metaclass, base class)
    api: SemanticAnalyzerPluginInterface


# A context for dynamic class definitions like
# Base = declarative_base()
class DynamicClassDefContext(NamedTuple):
    call: CallExpr  # The r.h.s. of dynamic class definition
    name: str  # The name this class is being assigned to
    api: SemanticAnalyzerPluginInterface


@mypyc_attr(allow_interpreted_subclasses=True)
class Plugin(CommonPluginApi):
    """Base class of all type checker plugins.

    This defines a no-op plugin.  Subclasses can override some methods to
    provide some actual functionality.

    All get_ methods are treated as pure functions (you should assume that
    results might be cached). A plugin should return None from a get_ method
    to give way to other plugins.

    Look at the comments of various *Context objects for additional information on
    various hooks.
    """

    def __init__(self, options: Options) -> None:
        self.options = options
        self.python_version = options.python_version
        # This can't be set in __init__ because it is executed too soon in build.py.
        # Therefore, build.py *must* set it later before graph processing starts
        # by calling set_modules().
        self._modules: dict[str, MypyFile] | None = None

    def set_modules(self, modules: dict[str, MypyFile]) -> None:
        self._modules = modules

    def lookup_fully_qualified(self, fullname: str) -> SymbolTableNode | None:
        assert self._modules is not None
        return lookup_fully_qualified(fullname, self._modules)

    def report_config_data(self, ctx: ReportConfigContext) -> Any:
        """Get representation of configuration data for a module.

        The data must be encodable as JSON and will be stored in the
        cache metadata for the module. A mismatch between the cached
        values and the returned will result in that module's cache
        being invalidated and the module being rechecked.

        This can be called twice for each module, once after loading
        the cache to check if it is valid and once while writing new
        cache information.

        If is_check in the context is true, then the return of this
        call will be checked against the cached version. Otherwise the
        call is being made to determine what to put in the cache. This
        can be used to allow consulting extra cache files in certain
        complex situations.

        This can be used to incorporate external configuration information
        that might require changes to typechecking.
        """
        return None

    def get_additional_deps(self, file: MypyFile) -> list[tuple[int, str, int]]:
        """Customize dependencies for a module.

        This hook allows adding in new dependencies for a module. It
        is called after parsing a file but before analysis. This can
        be useful if a library has dependencies that are dynamic based
        on configuration information, for example.

        Returns a list of (priority, module name, line number) tuples.

        The line number can be -1 when there is not a known real line number.

        Priorities are defined in mypy.build (but maybe shouldn't be).
        10 is a good choice for priority.
        """
        return []

    def get_type_analyze_hook(self, fullname: str) -> Callable[[AnalyzeTypeContext], Type] | None:
        """Customize behaviour of the type analyzer for given full names.

        This method is called during the semantic analysis pass whenever mypy sees an
        unbound type. For example, while analysing this code:

            from lib import Special, Other

            var: Special
            def func(x: Other[int]) -> None:
                ...

        this method will be called with 'lib.Special', and then with 'lib.Other'.
        The callback returned by plugin must return an analyzed type,
        i.e. an instance of `mypy.types.Type`.
        """
        return None

    def get_function_signature_hook(
        self, fullname: str
    ) -> Callable[[FunctionSigContext], FunctionLike] | None:
        """Adjust the signature of a function.

        This method is called before type checking a function call. Plugin
        may infer a better type for the function.

            from lib import Class, do_stuff

            do_stuff(42)
            Class()

        This method will be called with 'lib.do_stuff' and then with 'lib.Class'.
        """
        return None

    def get_function_hook(self, fullname: str) -> Callable[[FunctionContext], Type] | None:
        """Adjust the return type of a function call.

        This method is called after type checking a call. Plugin may adjust the return
        type inferred by mypy, and/or emit some error messages. Note, this hook is also
        called for class instantiation calls, so that in this example:

            from lib import Class, do_stuff

            do_stuff(42)
            Class()

        This method will be called with 'lib.do_stuff' and then with 'lib.Class'.
        """
        return None

    def get_method_signature_hook(
        self, fullname: str
    ) -> Callable[[MethodSigContext], FunctionLike] | None:
        """Adjust the signature of a method.

        This method is called before type checking a method call. Plugin
        may infer a better type for the method. The hook is also called for special
        Python dunder methods except __init__ and __new__ (use get_function_hook to customize
        class instantiation). This function is called with the method full name using
        the class where it was _defined_. For example, in this code:

            from lib import Special

            class Base:
                def method(self, arg: Any) -> Any:
                    ...
            class Derived(Base):
                ...

            var: Derived
            var.method(42)

            x: Special
            y = x[0]

        this method is called with '__main__.Base.method', and then with
        'lib.Special.__getitem__'.
        """
        return None

    def get_method_hook(self, fullname: str) -> Callable[[MethodContext], Type] | None:
        """Adjust return type of a method call.

        This is the same as get_function_hook(), but is called with the
        method full name (again, using the class where the method is defined).
        """
        return None

    def get_attribute_hook(self, fullname: str) -> Callable[[AttributeContext], Type] | None:
        """Adjust type of an instance attribute.

        This method is called with attribute full name using the class of the instance where
        the attribute was defined (or Var.info.fullname for generated attributes).

        For classes without __getattr__ or __getattribute__, this hook is only called for
        names of fields/properties (but not methods) that exist in the instance MRO.

        For classes that implement __getattr__ or __getattribute__, this hook is called
        for all fields/properties, including nonexistent ones (but still not methods).

        For example:

            class Base:
                x: Any
                def __getattr__(self, attr: str) -> Any: ...

            class Derived(Base):
                ...

            var: Derived
            var.x
            var.y

        get_attribute_hook is called with '__main__.Base.x' and '__main__.Base.y'.
        However, if we had not implemented __getattr__ on Base, you would only get
        the callback for 'var.x'; 'var.y' would produce an error without calling the hook.
        """
        return None

    def get_class_attribute_hook(self, fullname: str) -> Callable[[AttributeContext], Type] | None:
        """
        Adjust type of a class attribute.

        This method is called with attribute full name using the class where the attribute was
        defined (or Var.info.fullname for generated attributes).

        For example:

            class Cls:
                x: Any

            Cls.x

        get_class_attribute_hook is called with '__main__.Cls.x' as fullname.
        """
        return None

    def get_class_decorator_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        """Update class definition for given class decorators.

        The plugin can modify a TypeInfo _in place_ (for example add some generated
        methods to the symbol table). This hook is called after the class body was
        semantically analyzed, but *there may still be placeholders* (typically
        caused by forward references).

        NOTE: Usually get_class_decorator_hook_2 is the better option, since it
              guarantees that there are no placeholders.

        The hook is called with full names of all class decorators.

        The hook can be called multiple times per class, so it must be
        idempotent.
        """
        return None

    def get_class_decorator_hook_2(
        self, fullname: str
    ) -> Callable[[ClassDefContext], bool] | None:
        """Update class definition for given class decorators.

        Similar to get_class_decorator_hook, but this runs in a later pass when
        placeholders have been resolved.

        The hook can return False if some base class hasn't been
        processed yet using class hooks. It causes all class hooks
        (that are run in this same pass) to be invoked another time for
        the file(s) currently being processed.

        The hook can be called multiple times per class, so it must be
        idempotent.
        """
        return None

    def get_metaclass_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        """Update class definition for given declared metaclasses.

        Same as get_class_decorator_hook() but for metaclasses. Note:
        this hook will be only called for explicit metaclasses, not for
        inherited ones.

        TODO: probably it should also be called on inherited metaclasses.
        """
        return None

    def get_base_class_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        """Update class definition for given base classes.

        Same as get_class_decorator_hook() but for base classes. Base classes
        don't need to refer to TypeInfos, if a base class refers to a variable with
        Any type, this hook will still be called.
        """
        return None

    def get_customize_class_mro_hook(
        self, fullname: str
    ) -> Callable[[ClassDefContext], None] | None:
        """Customize MRO for given classes.

        The plugin can modify the class MRO _in place_. This method is called
        with the class full name before its body was semantically analyzed.
        """
        return None

    def get_dynamic_class_hook(
        self, fullname: str
    ) -> Callable[[DynamicClassDefContext], None] | None:
        """Semantically analyze a dynamic class definition.

        This plugin hook allows one to semantically analyze dynamic class definitions like:

            from lib import dynamic_class

            X = dynamic_class('X', [])

        For such definition, this hook will be called with 'lib.dynamic_class'.
        The plugin should create the corresponding TypeInfo, and place it into a relevant
        symbol table, e.g. using ctx.api.add_symbol_table_node().
        """
        return None


T = TypeVar("T")


class ChainedPlugin(Plugin):
    """A plugin that represents a sequence of chained plugins.

    Each lookup method returns the hook for the first plugin that
    reports a match.

    This class should not be subclassed -- use Plugin as the base class
    for all plugins.
    """

    # TODO: Support caching of lookup results (through a LRU cache, for example).

    def __init__(self, options: Options, plugins: list[Plugin]) -> None:
        """Initialize chained plugin.

        Assume that the child plugins aren't mutated (results may be cached).
        """
        super().__init__(options)
        self._plugins = plugins

    def set_modules(self, modules: dict[str, MypyFile]) -> None:
        for plugin in self._plugins:
            plugin.set_modules(modules)

    def report_config_data(self, ctx: ReportConfigContext) -> Any:
        config_data = [plugin.report_config_data(ctx) for plugin in self._plugins]
        return config_data if any(x is not None for x in config_data) else None

    def get_additional_deps(self, file: MypyFile) -> list[tuple[int, str, int]]:
        deps = []
        for plugin in self._plugins:
            deps.extend(plugin.get_additional_deps(file))
        return deps

    def get_type_analyze_hook(self, fullname: str) -> Callable[[AnalyzeTypeContext], Type] | None:
        return self._find_hook(lambda plugin: plugin.get_type_analyze_hook(fullname))

    def get_function_signature_hook(
        self, fullname: str
    ) -> Callable[[FunctionSigContext], FunctionLike] | None:
        return self._find_hook(lambda plugin: plugin.get_function_signature_hook(fullname))

    def get_function_hook(self, fullname: str) -> Callable[[FunctionContext], Type] | None:
        return self._find_hook(lambda plugin: plugin.get_function_hook(fullname))

    def get_method_signature_hook(
        self, fullname: str
    ) -> Callable[[MethodSigContext], FunctionLike] | None:
        return self._find_hook(lambda plugin: plugin.get_method_signature_hook(fullname))

    def get_method_hook(self, fullname: str) -> Callable[[MethodContext], Type] | None:
        return self._find_hook(lambda plugin: plugin.get_method_hook(fullname))

    def get_attribute_hook(self, fullname: str) -> Callable[[AttributeContext], Type] | None:
        return self._find_hook(lambda plugin: plugin.get_attribute_hook(fullname))

    def get_class_attribute_hook(self, fullname: str) -> Callable[[AttributeContext], Type] | None:
        return self._find_hook(lambda plugin: plugin.get_class_attribute_hook(fullname))

    def get_class_decorator_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        return self._find_hook(lambda plugin: plugin.get_class_decorator_hook(fullname))

    def get_class_decorator_hook_2(
        self, fullname: str
    ) -> Callable[[ClassDefContext], bool] | None:
        return self._find_hook(lambda plugin: plugin.get_class_decorator_hook_2(fullname))

    def get_metaclass_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        return self._find_hook(lambda plugin: plugin.get_metaclass_hook(fullname))

    def get_base_class_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        return self._find_hook(lambda plugin: plugin.get_base_class_hook(fullname))

    def get_customize_class_mro_hook(
        self, fullname: str
    ) -> Callable[[ClassDefContext], None] | None:
        return self._find_hook(lambda plugin: plugin.get_customize_class_mro_hook(fullname))

    def get_dynamic_class_hook(
        self, fullname: str
    ) -> Callable[[DynamicClassDefContext], None] | None:
        return self._find_hook(lambda plugin: plugin.get_dynamic_class_hook(fullname))

    def _find_hook(self, lookup: Callable[[Plugin], T]) -> T | None:
        for plugin in self._plugins:
            hook = lookup(plugin)
            if hook:
                return hook
        return None
