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

    • 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). Rational:

      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 and 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)
      Return 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, InvocationType methodType, Java8InferenceContext context)
      If a mapping, theta, for invocation doesn't exist create it by:

      Creates inference variables for the type parameters to methodType 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
      methodType - type of generic method
      context - Java8InferenceContext
      Returns:
      a mapping of the type variables of methodType to inference variables
    • createThetaForMethodReference

      public Theta createThetaForMethodReference(MemberReferenceTree memRef, InvocationType compileTimeDecl, 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
      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 compileTimeDecl 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 InvocationType 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 InvocationType 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 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.
      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
    • 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()
      Return the proper type for object.
      Returns:
      the proper type for object
    • lub

      public ProperType lub(Set<ProperType> properTypes)
      Return the least upper bounds of properTypes.
      Parameters:
      properTypes - types to lub
      Returns:
      the least upper bounds of properTypes
    • glb

      public AbstractType glb(Set<AbstractType> abstractTypes)
      Returns the greatest lower bound of abstractTypes.
      Parameters:
      abstractTypes - types to glb
      Returns:
      the greatest upper bounds of abstractTypes
    • 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()
      Return 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(ProperType lowerBound, 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(ProperType lowerBound, Set<? extends AnnotationMirror> lowerBoundAnnos, 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
      upperBound - an abstract type or null
      upperBoundAnnos - annotations to use if upperBound is null
      Returns:
      a fresh type variable with the provided upper and lower bounds
    • getSubsTypeArgs

      public List<AbstractType> getSubsTypeArgs(List<TypeVariable> typeVar, List<AbstractType> typeArg, List<Variable> types)
      Returns the result of substituting typeArg for typeVar in types.
      Parameters:
      typeVar - type variables
      typeArg - type arguments
      types - types
      Returns:
      the result of substituting typeArg for typeVar in types