Class RLCCalledMethodsAnnotatedTypeFactory

All Implemented Interfaces:
CreatesMustCallForElementSupplier, AnnotationProvider

public class RLCCalledMethodsAnnotatedTypeFactory extends CalledMethodsAnnotatedTypeFactory implements CreatesMustCallForElementSupplier
The type factory for the RLCCalledMethodsChecker. The main difference between this and the Called Methods type factory from which it is derived is that this version's postAnalyze(ControlFlowGraph) method checks that must-call obligations are fulfilled.
  • Field Details

    • ensuresCalledMethodsValueElement

      public final ExecutableElement ensuresCalledMethodsValueElement
      The EnsuresCalledMethods.value element/field.
    • ensuresCalledMethodsMethodsElement

      public final ExecutableElement ensuresCalledMethodsMethodsElement
      The EnsuresCalledMethods.methods element/field.
  • Constructor Details

    • RLCCalledMethodsAnnotatedTypeFactory

      public RLCCalledMethodsAnnotatedTypeFactory(BaseTypeChecker checker)
      Creates a new RLCCalledMethodsAnnotatedTypeFactory.
      Parameters:
      checker - the checker associated with this type factory
  • Method Details

    • createSupportedTypeQualifiers

      protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers()
      Description copied from class: AnnotatedTypeFactory
      Returns a mutable set of annotation classes that are supported by a checker.

      Subclasses may override this method to return a mutable set of their supported type qualifiers through one of the 5 approaches shown below.

      Subclasses should not call this method; they should call AnnotatedTypeFactory.getSupportedTypeQualifiers() instead.

      By default, a checker supports all annotations located in a subdirectory called qual that's located in the same directory as the checker. Note that only annotations defined with the @Target({ElementType.TYPE_USE}) meta-annotation (and optionally with the additional value of ElementType.TYPE_PARAMETER, but no other ElementType values) are automatically considered as supported annotations.

      To support a different set of annotations than those in the qual subdirectory, or that have other ElementType values, see examples below.

      In total, there are 5 ways to indicate annotations that are supported by a checker:

      1. Only support annotations located in a checker's qual directory:

        This is the default behavior. Simply place those annotations within the qual directory.

      2. Support annotations located in a checker's qual directory and a list of other annotations:

        Place those annotations within the qual directory, and override AnnotatedTypeFactory.createSupportedTypeQualifiers() by calling AnnotatedTypeFactory.getBundledTypeQualifiers(Class...) with a varargs parameter list of the other annotations. Code example:

         @Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
              return getBundledTypeQualifiers(Regex.class, PartialRegex.class, RegexBottom.class, UnknownRegex.class);
          } 
         
      3. Supporting only annotations that are explicitly listed: Override AnnotatedTypeFactory.createSupportedTypeQualifiers() and return a mutable set of the supported annotations. Code example:
         @Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
              return new HashSet<Class<? extends Annotation>>(
                      Arrays.asList(A.class, B.class));
          } 
         
        The set of qualifiers returned by AnnotatedTypeFactory.createSupportedTypeQualifiers() must be a fresh, mutable set. The methods AnnotatedTypeFactory.getBundledTypeQualifiers(Class...) must return a fresh, mutable set
      Overrides:
      createSupportedTypeQualifiers in class AnnotatedTypeFactory
      Returns:
      the type qualifiers supported this processor, or an empty set if none
    • createCalledMethods

      public AnnotationMirror createCalledMethods(String... val)
      Creates a @CalledMethods annotation whose values are the given strings.
      Parameters:
      val - the methods that have been called
      Returns:
      an annotation indicating that the given methods have been called
    • postAnalyze

      public void postAnalyze(ControlFlowGraph cfg)
      Description copied from class: GenericAnnotatedTypeFactory
      Perform any additional operations on a CFG. Called once per CFG, after the CFG has been analyzed by GenericAnnotatedTypeFactory.analyze(Queue, Queue, UnderlyingAST, List, ClassTree, boolean, boolean, boolean, CFAbstractStore). This method can be used to initialize additional state or to perform any analyses that are easier to perform on the CFG instead of the AST.
      Overrides:
      postAnalyze in class GenericAnnotatedTypeFactory<AccumulationValue,AccumulationStore,AccumulationTransfer,AccumulationAnalysis>
      Parameters:
      cfg - the CFG
      See Also:
    • createFlowAnalysis

      protected RLCCalledMethodsAnalysis createFlowAnalysis()
      Description copied from class: GenericAnnotatedTypeFactory
      Returns the appropriate flow analysis class that is used for the org.checkerframework.dataflow analysis.

      This implementation uses the checker naming convention to create the appropriate analysis. If no transfer function is found, it returns an instance of CFAnalysis.

      Subclasses have to override this method to create the appropriate analysis if they do not follow the checker naming convention.

      Overrides:
      createFlowAnalysis in class CalledMethodsAnnotatedTypeFactory
      Returns:
      the appropriate flow analysis class that is used for the org.checkerframework.dataflow analysis
    • getMustCallAnnotation

      public AnnotationMirror getMustCallAnnotation(Object obj)
      Retrieves the @MustCall annotation for the given object, which can be either an Element or a Tree. This method delegates to the MustCallAnnotatedTypeFactory to get the annotated type of the input object and then extracts the primary @MustCall annotation from it.
      Parameters:
      obj - the object for which to retrieve the @MustCall annotation. Must be either an instance of Element or Tree.
      Returns:
      the @MustCall annotation if present, null otherwise
      Throws:
      IllegalArgumentException - if the input object type is not supported
    • hasEmptyMustCallValue

      public boolean hasEmptyMustCallValue(Tree tree)
      Returns whether the MustCall.value() element/argument of the @MustCall annotation on the type of tree is definitely empty.

      This method only considers the declared type: it does not consider flow-sensitive refinement.

      Parameters:
      tree - a tree
      Returns:
      true if the Must Call type is non-empty or top
    • hasEmptyMustCallValue

      public boolean hasEmptyMustCallValue(Element element)
      Returns whether the MustCall.value() element/argument of the @MustCall annotation on the type of element is definitely empty.

      This method only considers the declared type: it does not consider flow-sensitive refinement.

      Parameters:
      element - an element
      Returns:
      true if the Must Call type is non-empty or top
    • getMustCallValues

      public List<String> getMustCallValues(Element element)
      Returns the MustCall.value() element/argument of the @MustCall annotation on the class type of element. If there is no such annotation, returns the empty list.

      Do not use this method to get the MustCall values of an MustCallConsistencyAnalyzer.Obligation. Instead, use MustCallConsistencyAnalyzer.Obligation.getMustCallMethods(RLCCalledMethodsAnnotatedTypeFactory, CFStore).

      Do not call List.isEmpty() on the result of this method: prefer to call hasEmptyMustCallValue(Element), which correctly accounts for @MustCallUnknown, instead.

      Parameters:
      element - an element
      Returns:
      the strings in its must-call type
    • getMustCallValues

      public List<String> getMustCallValues(@Nullable AnnotationMirror mustCallAnnotation)
      Helper method for getting the must-call values from a must-call annotation.
      Parameters:
      mustCallAnnotation - a MustCall annotation, or null
      Returns:
      the strings in mustCallAnnotation's value element, or the empty list if mustCallAnnotation is null
    • getTempVarForNode

      public @Nullable LocalVariableNode getTempVarForNode(Node node)
      Helper method to get the temporary variable that represents the given node, if one exists.
      Parameters:
      node - a node
      Returns:
      the tempvar for node's expression, or null if one does not exist
    • isTempVar

      public boolean isTempVar(Node node)
      Is the given node a temporary variable?
      Parameters:
      node - a node
      Returns:
      true iff the given node is a temporary variable
    • getTreeForTempVar

      public Tree getTreeForTempVar(Node node)
      Gets the tree for a temporary variable
      Parameters:
      node - a node for a temporary variable
      Returns:
      the tree for node
    • addTempVar

      public void addTempVar(LocalVariableNode tmpVar, Tree tree)
      Registers a temporary variable by adding it to this type factory's tempvar map.
      Parameters:
      tmpVar - a temporary variable
      tree - the tree of the expression the tempvar represents
    • declaredTypeHasMustCall

      public boolean declaredTypeHasMustCall(Tree tree)
      Returns true if the type of the tree includes a must-call annotation. Note that this method may not consider dataflow, and is only safe to use when you need the declared, rather than inferred, type of the tree.

      Do not use this method if you are trying to get the must-call obligations of the resource aliases of an MustCallConsistencyAnalyzer.Obligation. Instead, use MustCallConsistencyAnalyzer.Obligation.getMustCallMethods(ResourceLeakAnnotatedTypeFactory, CFStore).

      Parameters:
      tree - a tree
      Returns:
      whether the tree has declared must-call obligations
    • hasMustCallAlias

      public boolean hasMustCallAlias(Tree tree)
      Returns true if the given tree has an MustCallAlias annotation and resource-alias tracking is not disabled.
      Parameters:
      tree - a tree
      Returns:
      true if the given tree has an MustCallAlias annotation
    • hasMustCallAlias

      public boolean hasMustCallAlias(Element elt)
      Returns true if the given element has an MustCallAlias annotation and resource-alias tracking is not disabled.
      Parameters:
      elt - an element
      Returns:
      true if the given element has an MustCallAlias annotation
    • hasCreatesMustCallFor

      public boolean hasCreatesMustCallFor(MethodInvocationNode node)
      Returns true if the declaration of the method being invoked has one or more CreatesMustCallFor annotations.
      Parameters:
      node - a method invocation node
      Returns:
      true iff there is one or more @CreatesMustCallFor annotations on the declaration of the invoked method
    • canCreateObligations

      public boolean canCreateObligations()
      Does this type factory support CreatesMustCallFor?
      Returns:
      true iff the -AnoCreatesMustCallFor command-line argument was not supplied to the checker
    • getTypeFactoryOfSubcheckerOrNull

      public <T extends GenericAnnotatedTypeFactory<?, ?, ?, ?>> @Nullable T getTypeFactoryOfSubcheckerOrNull(Class<? extends SourceChecker> subCheckerClass)
      Description copied from class: GenericAnnotatedTypeFactory
      Returns the type factory used by a subchecker. Returns null if no matching subchecker was found or if the type factory is null. The caller must know the exact checker class to request.

      Because the visitor path is copied, call this method each time a subfactory is needed rather than store the returned subfactory in a field.

      Overrides:
      getTypeFactoryOfSubcheckerOrNull in class GenericAnnotatedTypeFactory<AccumulationValue,AccumulationStore,AccumulationTransfer,AccumulationAnalysis>
      Type Parameters:
      T - the type of subCheckerClass's AnnotatedTypeFactory
      Parameters:
      subCheckerClass - the exact class of the subchecker
      Returns:
      the AnnotatedTypeFactory of the subchecker or null if no subchecker exists
      See Also:
    • getEnsuresCalledMethodsListValueElement

      public ExecutableElement getEnsuresCalledMethodsListValueElement()
      Returns:
      the EnsuresCalledMethods.List.value() element
    • getCreatesMustCallForValueElement

      public ExecutableElement getCreatesMustCallForValueElement()
      Returns the CreatesMustCallFor.value() element.
      Specified by:
      getCreatesMustCallForValueElement in interface CreatesMustCallForElementSupplier
      Returns:
      the CreatesMustCallFor.value() element
    • getCreatesMustCallForListValueElement

      public ExecutableElement getCreatesMustCallForListValueElement()
      Returns the CreatesMustCallFor.List.value() element.
      Specified by:
      getCreatesMustCallForListValueElement in interface CreatesMustCallForElementSupplier
      Returns:
      the CreatesMustCallFor.List.value() element
    • hasNotOwning

      public boolean hasNotOwning(Element elt)
      Does the given element have an @NotOwning annotation (including in stub files)?

      Prefer this method to calling AnnotatedTypeFactory.getDeclAnnotation(Element, Class) on the type factory directly, which won't find this annotation in stub files (it only considers stub files loaded by this checker, not subcheckers).

      Parameters:
      elt - an element
      Returns:
      whether there is a NotOwning annotation on the given element
    • hasOwning

      public boolean hasOwning(Element elt)
      Does the given element have an @Owning annotation (including in stub files)?

      Prefer this method to calling AnnotatedTypeFactory.getDeclAnnotation(Element, Class) on the type factory directly, which won't find this annotation in stub files (it only considers stub files loaded by this checker, not subcheckers).

      Parameters:
      elt - an element
      Returns:
      whether there is an Owning annotation on the given element
    • getExceptionalPostconditions

      public Set<EnsuresCalledMethodOnExceptionContract> getExceptionalPostconditions(ExecutableElement methodOrConstructor)
      Description copied from class: CalledMethodsAnnotatedTypeFactory
      Get the exceptional postconditions for the given method from the EnsuresCalledMethodsOnException annotations on it.
      Overrides:
      getExceptionalPostconditions in class CalledMethodsAnnotatedTypeFactory
      Parameters:
      methodOrConstructor - the method to examine
      Returns:
      the exceptional postconditions on the given method; the return value is newly-allocated and can be freely modified by callers
    • isIgnoredExceptionType

      public boolean isIgnoredExceptionType(TypeMirror exceptionType)
      Returns true if the checker should ignore exceptional control flow due to the given exception type.
      Overrides:
      isIgnoredExceptionType in class CalledMethodsAnnotatedTypeFactory
      Parameters:
      exceptionType - exception type
      Returns:
      true if exceptionType is a member of CalledMethodsAnalysis.ignoredExceptionTypes, false otherwise
    • getInput

      Fetches the transfer input for the given block, either from the flowResult, if the analysis is still running, or else from the analysis itself.
      Parameters:
      block - a block
      Returns:
      the appropriate TransferInput from the results of running dataflow