Class MethodResolutionLogic


  • public class MethodResolutionLogic
    extends java.lang.Object
    • Field Detail

      • JAVA_LANG_OBJECT

        private static java.lang.String JAVA_LANG_OBJECT
    • Constructor Detail

      • MethodResolutionLogic

        public MethodResolutionLogic()
    • Method Detail

      • groupVariadicParamValues

        private static java.util.List<ResolvedType> groupVariadicParamValues​(java.util.List<ResolvedType> argumentsTypes,
                                                                             int startVariadic,
                                                                             ResolvedType variadicType)
      • isApplicable

        private static boolean isApplicable​(ResolvedMethodDeclaration methodDeclaration,
                                            java.lang.String needleName,
                                            java.util.List<ResolvedType> needleArgumentTypes,
                                            TypeSolver typeSolver,
                                            boolean withWildcardTolerance)
        Note the specific naming here -- parameters are part of the method declaration, while arguments are the values passed when calling a method. Note that "needle" refers to that value being used as a search/query term to match against.
        Returns:
        true, if the given ResolvedMethodDeclaration matches the given name/types (normally obtained from a MethodUsage)
      • isArrayOfObject

        private static boolean isArrayOfObject​(ResolvedType type)
      • getLastParameterIndex

        private static int getLastParameterIndex​(int countOfMethodParametersDeclared)
        Returns the index of the last parameter in a parameter list. Helper method to safely get the last parameter index even for empty lists.
        Parameters:
        countOfMethodParametersDeclared - the total number of parameters
        Returns:
        the index of the last parameter (0-based), or 0 if there are no parameters
      • isAssignableMatchTypeParameters

        public static boolean isAssignableMatchTypeParameters​(ResolvedType expected,
                                                              ResolvedType actual,
                                                              java.util.Map<java.lang.String,​ResolvedType> matchedParameters)
      • isApplicable

        public static boolean isApplicable​(MethodUsage methodUsage,
                                           java.lang.String needleName,
                                           java.util.List<ResolvedType> needleParameterTypes,
                                           TypeSolver typeSolver)
        Checks if a method usage is applicable for a given method name and parameter types. This method performs type compatibility checking including generic type variable substitution. Note the specific naming here -- parameters are part of the method declaration, while arguments are the values passed when calling a method. Note that "needle" refers to that value being used as a search/query term to match against.
        Returns:
        true, if the given MethodUsage matches the given name/types (normally obtained from a ResolvedMethodDeclaration)
      • isBoxingCompatibleWithTypeSolver

        private static boolean isBoxingCompatibleWithTypeSolver​(ResolvedType expectedType,
                                                                ResolvedType actualType,
                                                                TypeSolver typeSolver)
        Checks if a primitive type can be boxed to a reference type (or vice versa). Also handles array types for variadic parameters and wildcards.
      • substituteDeclaringTypeParameters

        private static MethodUsage substituteDeclaringTypeParameters​(MethodUsage methodUsage,
                                                                     TypeSolver typeSolver)
        Substitutes type variables from the declaring type into the method signature. This method handles the case where a method is inherited from a generic ancestor, and the method signature contains type variables from that ancestor that need to be replaced with the type variables (or concrete types) of the current declaring type. Example scenario: - Iterable declares: forEach(Consumer action) - Collection extends Iterable - List extends Collection When we call List.forEach(...): 1. The method signature initially references Iterable's type variable 'T' 2. This needs to be substituted through the inheritance chain: - In Collection: T -> E (Iterable becomes Iterable) - In List: E remains E - In List: E -> String 3. Final result: forEach(Consumer action) Without this substitution, we would be comparing incompatible type variables and the method resolution would fail.
        Parameters:
        methodUsage - the method usage whose signature needs type variable substitution
        typeSolver - the type solver for resolving types during substitution
        Returns:
        a new MethodUsage with type variables properly substituted
      • substituteTypeVariables

        private static ResolvedType substituteTypeVariables​(ResolvedType type,
                                                            java.util.List<ResolvedTypeParameterDeclaration> typeParams,
                                                            java.util.List<ResolvedType> typeArgs)
        Recursively substitutes type variables within a type structure. This method performs deep substitution of type variables, handling various type structures including: - Simple type variables (T, E, K, V, etc.) - Wildcards with type variable bounds (? super T, ? extends E) - Parameterized types with type variables (List, Map) - Nested combinations of the above (Consumer, List>) The substitution is based on a mapping between type parameter declarations (the formal parameters as declared, e.g., in class Foo) and their actual type arguments (the concrete types used, e.g., String in Foo). Example transformations: - T -> String (when typeParams contains T and typeArgs contains String) - ? super T -> ? super String - Consumer -> Consumer - List -> List - Map -> Map (with appropriate mappings)
        Parameters:
        type - the type in which to substitute type variables
        typeParams - the list of type parameter declarations (formal parameters)
        typeArgs - the list of actual type arguments to substitute in
        Returns:
        a new type with all matching type variables substituted
      • distinctByKey

        private static <T> java.util.function.Predicate<T> distinctByKey​(java.util.function.Function<? super T,​?> keyExtractor)
        Filters by given function {@param keyExtractor} using a stateful filter mechanism.
              persons.stream().filter(distinctByKey(Person::getName))
         

        The example above would return a distinct list of persons containing only one person per name.

      • getMethodUsageExplicitAndVariadicParameterType

        public static ResolvedType getMethodUsageExplicitAndVariadicParameterType​(MethodUsage method,
                                                                                  int i)
      • isJavaLangObject

        private static boolean isJavaLangObject​(ResolvedType paramType)
      • findMostApplicableUsage

        public static java.util.Optional<MethodUsage> findMostApplicableUsage​(java.util.List<MethodUsage> methods,
                                                                              java.lang.String name,
                                                                              java.util.List<ResolvedType> argumentsTypes,
                                                                              TypeSolver typeSolver)