java.lang.Object
org.checkerframework.framework.util.typeinference8.types.InferenceFactory

public class InferenceFactory extends Object
Factory that creates AbstractTypes.
  • Constructor Details

    • InferenceFactory

      public InferenceFactory(Java8InferenceContext context)
      Creates an inference factory.
      Parameters:
      context - the context
  • Method Details

    • getCapturedSupertype

      public @Nullable AnnotatedTypeMirror getCapturedSupertype(MemberReferenceTree memRef, @Nullable AbstractType p1)
      Returns the capture-converted parameterization capture(G<...>) of the qualifier type of memRef that is a supertype of P1, as specified by the second search in JLS 15.13.1. This is used to fix the class's type arguments for a method reference of the form ReferenceType :: Identifier where ReferenceType is raw.

      Returns null if no parameterization G<...> of the raw ReferenceType is a supertype of P1, in which case the class's type arguments are inferred after all.

      Parameters:
      memRef - a method reference
      p1 - the first parameter type of the function type of the target type of memRef, which acts as the target reference of the invocation
      Returns:
      the capture-converted supertype of the qualifier type, or null if no parameterization G<...> exists
    • getTargetType

      public @Nullable ProperType getTargetType()
      Gets the target type for the expression for which type arguments are being inferred.
      Returns:
      target type for the expression for which type arguments are being inferred
    • assignedToVariable

      public static AnnotatedTypeMirror assignedToVariable(AnnotatedTypeFactory atypeFactory, Tree assignmentContext)
      If the variable's type is a type variable, return getAnnotatedTypeLhsNoTypeVarDefault(tree). Rationale:

      For example:

      
       <S> S bar () {...}
      
       <T> T foo(T p) {
           T local = bar();
           return local;
         }
       
      During type argument inference of bar, the assignment context is local. If the local variable default is used, then the type of assignment context type is @Nullable T and the type argument inferred for bar() is @Nullable T. And an incompatible types in return error is issued.

      If instead, the local variable default is not applied, then the assignment context type is T (with lower bound @NonNull Void and upper bound @Nullable Object) and the type argument inferred for bar() is T. During dataflow, the type of local is refined to T and the return is legal.

      If the assignment context type was a declared type, for example:

      
       <S> S bar () {...}
       Object foo() {
           Object local = bar();
           return local;
       }
       
      The local variable default must be used or else the assignment context type is missing an annotation. So, an incompatible types in return error is issued in the above code. We could improve type argument inference in this case by using the lower bound of S instead of the local variable default.
      Parameters:
      atypeFactory - AnnotatedTypeFactory
      assignmentContext - VariableTree
      Returns:
      AnnotatedTypeMirror of Assignment context
    • getTypeOfMethodAdaptedToUse

      public static ExecutableType getTypeOfMethodAdaptedToUse(ExpressionTree expressionTree, Java8InferenceContext context)
      Returns ExecutableType of the method invocation or new class tree adapted to the call site.
      Parameters:
      expressionTree - a method invocation or new class tree
      context - the context
      Returns:
      ExecutableType of the method invocation or new class tree adapted to the call site
    • lub

      public static TypeMirror lub(ProcessingEnvironment processingEnv, TypeMirror tm1, TypeMirror tm2)
      Returns the least upper bound of tm1 and tm2.
      Parameters:
      processingEnv - the processing environment
      tm1 - a type
      tm2 - a type
      Returns:
      the least upper bound of tm1 and tm2
    • glb

      public static TypeMirror glb(ProcessingEnvironment processingEnv, TypeMirror tm1, TypeMirror tm2)
      Returns the greatest lower bound of tm1 and tm2.
      Parameters:
      processingEnv - the processing environment
      tm1 - a type
      tm2 - a type
      Returns:
      the greatest lower bound of tm1 and tm2
    • createThetaForInvocation

      public Theta createThetaForInvocation(ExpressionTree invocation, AbstractExecutableType executableType, Java8InferenceContext context)
      If a mapping, theta, for invocation doesn't exist create it by:

      Creates inference variables for the type parameters to executableType for a particular invocation. Initializes the bounds of the variables. Returns a mapping from type variables to newly created variables.

      Otherwise, returns the previously created mapping.

      Parameters:
      invocation - method or constructor invocation
      executableType - type of generic method
      context - Java8InferenceContext
      Returns:
      a mapping of the type variables of executableType to inference variables
    • createThetaForMethodReference

      public Theta createThetaForMethodReference(MemberReferenceTree memRef, CompileTimeDeclarationType compileTimeDecl, @Nullable AbstractType p1, Java8InferenceContext context)
      If a mapping, theta, for memRef doesn't exist create it by:

      Creates inference variables for the type parameters to compileTimeDecl for a particular method reference. Initializes the bounds of the variables. Returns a mapping from type variables to newly created variables.

      Otherwise, returns the previously created mapping.

      Parameters:
      memRef - method reference tree
      compileTimeDecl - type of generic method
      p1 - the first parameter type of the function type of the target type of memRef, which acts as the target reference of the invocation; or null if it is not known. It is used only to determine the type to search when ReferenceType is raw.
      context - Java8InferenceContext
      Returns:
      a mapping of the type variables of compileTimeDecl to inference variables
    • createThetaForLambda

      public Theta createThetaForLambda(LambdaExpressionTree lambda, AbstractType functionalInterface)
      If a mapping, theta, for lambda doesn't exist create it by:

      Creates inference variables for the type parameters to the functional inference of the lambda. Initializes the bounds of the variables. Returns a mapping from type variables to newly created variables.

      Otherwise, returns the previously created mapping.

      Parameters:
      lambda - lambda expression tree
      functionalInterface - functional interface of the lambda
      Returns:
      a mapping of the type variables of functionalInterface to inference variables
    • createThetaForCapture

      public Theta createThetaForCapture(ExpressionTree tree, AbstractType capturedType)
      Creates capture variables for variables introduced by a capture bounds. The new variables correspond to the type parameters of capturedType.
      Parameters:
      tree - invocation tree that created the capture bound
      capturedType - type that should be captured
      Returns:
      a mapping of the type variables of capturedType to capture inference variables
    • getTypeOfMethodAdaptedToUse

      public AbstractExecutableType getTypeOfMethodAdaptedToUse(ExpressionTree invocation)
      Returns the type of the method or constructor invocation adapted to its arguments. This type may include inference variables.
      Parameters:
      invocation - method or constructor invocation
      Returns:
      the type of the method or constructor invocation adapted to its arguments
    • compileTimeDeclarationType

      public CompileTimeDeclarationType compileTimeDeclarationType(MemberReferenceTree memRef)
      Returns the compile-time declaration of the method reference that is the method to which the expression refers. See JLS section 15.13.1 for a complete definition.

      The type of a member reference is a functional interface. The function type of a member reference is the type of the single abstract method declared by the functional interface. The compile-time declaration type is the type of the actual method referenced by the method reference, i.e. the method that is actually being referenced.

      For example,

      
       static class MyClass {
         String field;
         public static int compareByField(MyClass a, MyClass b) { ... }
       }
       Comparator<MyClass> func = MyClass::compareByField;
       

      The function type is compare(Comparator<MyClass> this, MyClass o1, MyClass o2) where as the compile-time declaration type is compareByField(MyClass a, MyClass b).

      Parameters:
      memRef - method reference tree
      Returns:
      the compile-time declaration of the method reference
    • getParameterizedSupers

      public @Nullable org.plumelib.util.IPair<AbstractType,AbstractType> getParameterizedSupers(AbstractType a, AbstractType b)
      Returns the pair of a as the least upper bound of a and b and b as the least upper bound of a and b. Returns null if that least upper bound is not a parameterized type or if either a or b has no supertype that is the same class as that least upper bound.
      Parameters:
      a - type
      b - type
      Returns:
      the pair of a as the least upper bound of a and b and b as the least upper bound of a and b, or null
    • getTypeOfElement

      public AbstractType getTypeOfElement(Element element, Theta map)
      Returns the type of element using the type variable to inference variable mapping, map.
      Parameters:
      element - some element
      map - type parameter to inference variables to use
      Returns:
      the type of element
    • getTypeOfBound

      public AbstractType getTypeOfBound(TypeParameterElement pEle, Theta map)
      Returns the type of pEle using the type variable to inference variable mapping, map.
      Parameters:
      pEle - some element
      map - type parameter to inference variables to use
      Returns:
      the type of pEle
    • getObject

      public ProperType getObject()
      Returns the proper type for object.
      Returns:
      the proper type for object
    • lub

      public @Nullable ProperType lub(Set<ProperType> properTypes)
      Returns the least upper bounds of properTypes, or null if properTypes is empty.
      Parameters:
      properTypes - types to lub
      Returns:
      the least upper bounds of properTypes, or null
    • glb

      public @Nullable AbstractType glb(Set<AbstractType> abstractTypes)
      Returns the greatest lower bound of abstractTypes, or null if abstractTypes is empty.
      Parameters:
      abstractTypes - types to glb
      Returns:
      the greatest lower bound of abstractTypes, or null
    • glb

      Returns the greatest lower bound of a and b.
      Parameters:
      a - type to glb
      b - type to glb
      Returns:
      the greatest lower bound of a and b
    • getRuntimeException

      public ProperType getRuntimeException()
      Returns the proper type for RuntimeException.
      Returns:
      the proper type for RuntimeException
    • getCheckedExceptionConstraints

      public ConstraintSet getCheckedExceptionConstraints(ExpressionTree expression, AbstractType targetType, Theta map)
      Creates and returns the set of checked exception constraints for the given lambda or method reference.
      Parameters:
      expression - a lambda or method reference expression
      targetType - the target type of expression
      map - theta
      Returns:
      the set of checked exception constraints for the given lambda or method reference
    • createWildcard

      public ProperType createWildcard(@Nullable ProperType lowerBound, @Nullable AbstractType upperBound)
      Creates a wildcard using the upper and lower bounds provided.
      Parameters:
      lowerBound - a proper type or null
      upperBound - an abstract type or null
      Returns:
      a wildcard with the provided upper and lower bounds
    • createFreshTypeVariable

      public AbstractType createFreshTypeVariable(@Nullable ProperType lowerBound, Set<? extends AnnotationMirror> lowerBoundAnnos, @Nullable AbstractType upperBound, Set<? extends AnnotationMirror> upperBoundAnnos)
      Creates a fresh type variable using the upper and lower bounds provided.
      Parameters:
      lowerBound - a proper type or null
      lowerBoundAnnos - annotations to use if lowerBound is null; a hierarchy that it does not mention gets the default qualifier for an implicit lower bound
      upperBound - an abstract type or null
      upperBoundAnnos - annotations to use if upperBound is null; a hierarchy that it does not mention gets the default qualifier for an implicit upper bound
      Returns:
      a fresh type variable with the provided upper and lower bounds
    • getSubsTypeArgs

      public List<AbstractType> getSubsTypeArgs(List<AbstractType> typeArgs, List<Variable> variables)
      Returns typeArgs, in which every use of a variable in variables has been replaced by the corresponding element of typeArgs. An instantiation may mention another variable that is being resolved at the same time, so the instantiations are not final until this substitution has been performed.

      typeArgs and variables are parallel lists: typeArgs.get(i) is the instantiation of variables.get(i).

      Parameters:
      typeArgs - the instantiations of variables
      variables - the variables that typeArgs instantiates
      Returns:
      typeArgs, with uses of variables replaced by their instantiations