Class LockVisitor

  • All Implemented Interfaces:
    com.sun.source.tree.TreeVisitor<java.lang.Void,​java.lang.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 Detail

      • SELF_RECEIVER_PATTERN

        protected static final java.util.regex.Pattern SELF_RECEIVER_PATTERN
        A pattern for spotting self receiver
    • Constructor Detail

      • LockVisitor

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

      • visitVariable

        public java.lang.Void visitVariable​(com.sun.source.tree.VariableTree tree,
                                            java.lang.Void p)
        Specified by:
        visitVariable in interface com.sun.source.tree.TreeVisitor<java.lang.Void,​java.lang.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 java.lang.Void visitMethod​(com.sun.source.tree.MethodTree tree,
                                          java.lang.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<java.lang.Void,​java.lang.Void>
        Overrides:
        visitMethod in class BaseTypeVisitor<LockAnnotatedTypeFactory>
        Parameters:
        tree - 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
      • commonAssignmentCheck

        protected boolean commonAssignmentCheck​(AnnotatedTypeMirror varType,
                                                AnnotatedTypeMirror valueType,
                                                com.sun.source.tree.Tree valueTree,
                                                @CompilerMessageKey java.lang.String errorKey,
                                                java.lang.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
        Returns:
        true if the check succeeds, false if an error message was issued
      • visitMemberSelect

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

        public java.lang.Void visitArrayAccess​(com.sun.source.tree.ArrayAccessTree tree,
                                               java.lang.Void p)
        Specified by:
        visitArrayAccess in interface com.sun.source.tree.TreeVisitor<java.lang.Void,​java.lang.Void>
        Overrides:
        visitArrayAccess in class com.sun.source.util.TreeScanner<java.lang.Void,​java.lang.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 java.lang.Void visitMethodInvocation​(com.sun.source.tree.MethodInvocationTree methodInvocationTree,
                                                    java.lang.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<java.lang.Void,​java.lang.Void>
        Overrides:
        visitMethodInvocation in class BaseTypeVisitor<LockAnnotatedTypeFactory>
        Parameters:
        methodInvocationTree - the MethodInvocationTree of the method call being visited
      • visitSynchronized

        public java.lang.Void visitSynchronized​(com.sun.source.tree.SynchronizedTree tree,
                                                java.lang.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<java.lang.Void,​java.lang.Void>
        Overrides:
        visitSynchronized in class com.sun.source.util.TreeScanner<java.lang.Void,​java.lang.Void>
        Parameters:
        tree - the SynchronizedTree for the synchronized block being visited
      • visitAnnotation

        public java.lang.Void visitAnnotation​(com.sun.source.tree.AnnotationTree tree,
                                              java.lang.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<java.lang.Void,​java.lang.Void>
        Overrides:
        visitAnnotation in class BaseTypeVisitor<LockAnnotatedTypeFactory>
      • visitIdentifier

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

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

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