Class LockVisitor

java.lang.Object
com.sun.source.util.TreeScanner<R,P>
com.sun.source.util.TreePathScanner<R,P>
All Implemented Interfaces:
com.sun.source.tree.TreeVisitor<Void,Void>

public class LockVisitor extends BaseTypeVisitor<LockAnnotatedTypeFactory>
The LockVisitor enforces the special type-checking rules described in the Lock Checker manual chapter.
See the Checker Framework Manual:
Lock Checker
  • Field Details

    • SELF_RECEIVER_PATTERN

      protected static final Pattern SELF_RECEIVER_PATTERN
      A pattern for spotting self receiver
  • Constructor Details

    • LockVisitor

      public LockVisitor(BaseTypeChecker checker)
      Constructs a LockVisitor.
      Parameters:
      checker - the type checker to use
  • Method Details

    • visitVariable

      public Void visitVariable(com.sun.source.tree.VariableTree node, Void p)
      Specified by:
      visitVariable in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitVariable in class BaseTypeVisitor<LockAnnotatedTypeFactory>
    • createTypeFactory

      public LockAnnotatedTypeFactory createTypeFactory()
      Description copied from class: BaseTypeVisitor
      Constructs an instance of the appropriate type factory for the implemented type system.

      The default implementation uses the checker naming convention to create the appropriate type factory. If no factory is found, it returns BaseAnnotatedTypeFactory. It reflectively invokes the constructor that accepts this checker and compilation unit tree (in that order) as arguments.

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

      Overrides:
      createTypeFactory in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Returns:
      the appropriate type factory
    • visitMethod

      public Void visitMethod(com.sun.source.tree.MethodTree node, Void p)
      Issues an error if a method (explicitly or implicitly) annotated with @MayReleaseLocks has a formal parameter or receiver (explicitly or implicitly) annotated with @GuardSatisfied. Also issues an error if a synchronized method has a @LockingFree, @SideEffectFree, or @Pure annotation.
      Specified by:
      visitMethod in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitMethod in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      node - the MethodTree of the method definition to visit
    • skipReceiverSubtypeCheck

      protected boolean skipReceiverSubtypeCheck(com.sun.source.tree.MethodInvocationTree methodInvocationTree, AnnotatedTypeMirror methodDefinitionReceiver, AnnotatedTypeMirror methodCallReceiver)
      When visiting a method call, if the receiver formal parameter has type @GuardSatisfied and the receiver actual parameter has type @GuardedBy(...), this method verifies that the guard is satisfied, and it returns true, indicating that the receiver subtype check should be skipped. If the receiver actual parameter has type @GuardSatisfied, this method simply returns true without performing any other actions. The method returns false otherwise.
      Overrides:
      skipReceiverSubtypeCheck in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      methodInvocationTree - the MethodInvocationTree of the method being called
      methodDefinitionReceiver - the ATM of the formal receiver parameter of the method being called
      methodCallReceiver - the ATM of the receiver argument of the method call
      Returns:
      whether the caller can skip the receiver subtype check
    • getExceptionParameterLowerBoundAnnotations

      protected Set<? extends AnnotationMirror> getExceptionParameterLowerBoundAnnotations()
      Description copied from class: BaseTypeVisitor
      Returns a set of AnnotationMirrors that is a lower bound for exception parameters.

      This implementation returns top; subclasses can change this behavior.

      Note: by default this method is called by BaseTypeVisitor.getThrowUpperBoundAnnotations(), so that this annotation is enforced.

      Overrides:
      getExceptionParameterLowerBoundAnnotations in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Returns:
      set of annotation mirrors, one per hierarchy, that form a lower bound of annotations that can be written on an exception parameter
    • checkConstructorResult

      protected void checkConstructorResult(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, ExecutableElement constructorElement)
      Description copied from class: BaseTypeVisitor
      Issue a warning if the result type of the constructor is not top. If it is a supertype of the class, then a conflicting.annos error will also be issued by BaseTypeVisitor.isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType,AnnotatedTypeMirror.AnnotatedDeclaredType,Tree).
      Overrides:
      checkConstructorResult in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      constructorType - AnnotatedExecutableType for the constructor
      constructorElement - element that declares the constructor
    • commonAssignmentCheck

      protected void commonAssignmentCheck(AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, com.sun.source.tree.Tree valueTree, @CompilerMessageKey String errorKey, Object... extraArgs)
      Description copied from class: BaseTypeVisitor
      Checks the validity of an assignment (or pseudo-assignment) from a value to a variable and emits an error message (through the compiler's messaging interface) if it is not valid.
      Overrides:
      commonAssignmentCheck in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      varType - the annotated type of the variable
      valueType - the annotated type of the value
      valueTree - the location to use when reporting the error message
      errorKey - the error message key to use if the check fails
      extraArgs - arguments to the error message key, before "found" and "expected" types
    • visitMemberSelect

      public Void visitMemberSelect(com.sun.source.tree.MemberSelectTree tree, Void p)
      Specified by:
      visitMemberSelect in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitMemberSelect in class com.sun.source.util.TreeScanner<Void,Void>
    • checkOverride

      protected boolean checkOverride(com.sun.source.tree.MethodTree overriderTree, AnnotatedTypeMirror.AnnotatedDeclaredType enclosingType, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethodType, AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType)
      Ensures that subclass methods are annotated with a stronger or equally strong side effect annotation than the parent class method.
      Overrides:
      checkOverride in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      overriderTree - declaration tree of overriding method
      enclosingType - type of overriding class
      overriddenMethodType - type of overridden method
      overriddenType - type of overridden class
      Returns:
      true if the override is allowed
      See Also:
    • visitArrayAccess

      public Void visitArrayAccess(com.sun.source.tree.ArrayAccessTree tree, Void p)
      Specified by:
      visitArrayAccess in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitArrayAccess in class com.sun.source.util.TreeScanner<Void,Void>
    • isValidUse

      public boolean isValidUse(AnnotatedTypeMirror.AnnotatedDeclaredType declarationType, AnnotatedTypeMirror.AnnotatedDeclaredType useType, com.sun.source.tree.Tree tree)
      Skips the call to super and returns true.

      GuardedBy({}) is the default type on class declarations, which is a subtype of the top annotation @GuardedByUnknown. However, it is valid to declare an instance of a class with any annotation from the @GuardedBy hierarchy. Hence, this method returns true for annotations in the @GuardedBy hierarchy.

      Also returns true for annotations in the @LockPossiblyHeld hierarchy since the default for that hierarchy is the top type and annotations from that hierarchy cannot be explicitly written in code.

      Overrides:
      isValidUse in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      declarationType - the type of the class (TypeElement)
      useType - the use of the class (instance type)
      tree - the tree where the type is used
      Returns:
      true if the useType is a valid use of elemType
    • visitMethodInvocation

      public Void visitMethodInvocation(com.sun.source.tree.MethodInvocationTree node, Void p)
      When visiting a method invocation, issue an error if the side effect annotation on the called method causes the side effect guarantee of the enclosing method to be violated. For example, a method annotated with @ReleasesNoLocks may not call a method annotated with @MayReleaseLocks. Also check that matching @GuardSatisfied(index) on a method's formal receiver/parameters matches those in corresponding locations on the method call site.
      Specified by:
      visitMethodInvocation in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitMethodInvocation in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      Parameters:
      node - the MethodInvocationTree of the method call being visited
    • visitSynchronized

      public Void visitSynchronized(com.sun.source.tree.SynchronizedTree node, Void p)
      When visiting a synchronized block, issue an error if the expression has a type that implements the java.util.concurrent.locks.Lock interface. This prevents explicit locks from being accidentally used as built-in (monitor) locks. This is important because the Lock Checker does not have a mechanism to separately keep track of the explicit lock and the monitor lock of an expression that implements the Lock interface (i.e. there is a @LockHeld annotation used in dataflow, but there are not distinct @MonitorLockHeld and @ExplicitLockHeld annotations). It is assumed that both kinds of locks will never be held for any expression that implements Lock.

      Additionally, a synchronized block may not be present in a method that has a @LockingFree guarantee or stronger. An error is issued in this case.

      Specified by:
      visitSynchronized in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitSynchronized in class com.sun.source.util.TreeScanner<Void,Void>
      Parameters:
      node - the SynchronizedTree for the synchronized block being visited
    • visitAnnotation

      public Void visitAnnotation(com.sun.source.tree.AnnotationTree tree, Void p)
      Description copied from class: BaseTypeVisitor
      Ensure that the annotation arguments comply to their declarations. This needs some special casing, as annotation arguments form special trees.
      Specified by:
      visitAnnotation in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitAnnotation in class BaseTypeVisitor<LockAnnotatedTypeFactory>
    • visitIdentifier

      public Void visitIdentifier(com.sun.source.tree.IdentifierTree tree, Void p)
      Specified by:
      visitIdentifier in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitIdentifier in class BaseTypeVisitor<LockAnnotatedTypeFactory>
    • visitBinary

      public Void visitBinary(com.sun.source.tree.BinaryTree binaryTree, Void p)
      Specified by:
      visitBinary in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitBinary in class com.sun.source.util.TreeScanner<Void,Void>
    • visitCompoundAssignment

      public Void visitCompoundAssignment(com.sun.source.tree.CompoundAssignmentTree node, Void p)
      Description copied from class: BaseTypeVisitor
      Performs assignability check.
      Specified by:
      visitCompoundAssignment in interface com.sun.source.tree.TreeVisitor<Void,Void>
      Overrides:
      visitCompoundAssignment in class BaseTypeVisitor<LockAnnotatedTypeFactory>