All Downloads are FREE. Search and download functionalities are using the official Maven repository.

checker.src.org.checkerframework.checker.lock.LockTreeAnnotator Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java’s type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.42.0
Show newest version
package org.checkerframework.checker.lock;

import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.javacutil.TypesUtils;

import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.Tree.Kind;

public class LockTreeAnnotator extends TreeAnnotator {

    public LockTreeAnnotator(AnnotatedTypeFactory atypeFactory) {
        super(atypeFactory);
    }

    @Override
    public Void visitBinary(BinaryTree node, AnnotatedTypeMirror type) {
        // For any binary operation whose LHS or RHS can be a non-boolean type,
        // and whose resulting type is necessarily boolean, the resulting annotation
        // on the boolean type must be @GuardedBy({}).

        // There is no need to enforce that the annotation on the result of &&, ||, etc.
        // is @GuardedBy({}) since for such operators, both operands are of type
        // @GuardedBy({}) boolean to begin with.

        if (isBinaryComparisonOrInstanceOfOperator(node.getKind()) ||
            TypesUtils.isString(type.getUnderlyingType())) {
            // A boolean or String is always @GuardedBy({}). LockVisitor determines whether
            // the LHS and RHS of this operation can be legally dereferenced.
            type.replaceAnnotation(((LockAnnotatedTypeFactory) atypeFactory).GUARDEDBY);

            return null;
        }

        return super.visitBinary(node, type);
    }

    /** Indicates that the result of the operation is a boolean value. */
    private static boolean isBinaryComparisonOrInstanceOfOperator(Kind opKind) {
        switch(opKind) {
            case EQUAL_TO:
            case NOT_EQUAL_TO:
            // Technically, <=, <, > and >= are irrelevant for visitBinary, since currently boxed primitives
            // cannot be annotated with @GuardedBy(...), but they are left here in case that rule changes.
            case LESS_THAN:
            case LESS_THAN_EQUAL:
            case GREATER_THAN:
            case GREATER_THAN_EQUAL:
            case INSTANCE_OF:
                return true;
            default:
        }

        return false;
    }

    @Override
    public Void visitCompoundAssignment(CompoundAssignmentTree node,
            AnnotatedTypeMirror type) {
        if (TypesUtils.isString(type.getUnderlyingType())) {
            type.replaceAnnotation(((LockAnnotatedTypeFactory) atypeFactory).GUARDEDBY);
        }

        return super.visitCompoundAssignment(node, type);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy