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

framework.src.org.checkerframework.qualframework.poly.QualifierParameterTreeAnnotator 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.qualframework.poly;

import java.util.*;

import javax.lang.model.element.Element;
import javax.lang.model.type.TypeKind;
import com.sun.source.tree.*;

import org.checkerframework.qualframework.base.TreeAnnotator;
import org.checkerframework.qualframework.base.SetQualifierVisitor;
import org.checkerframework.qualframework.base.QualifiedTypeMirror;
import org.checkerframework.qualframework.base.QualifiedTypeMirror.QualifiedDeclaredType;
import org.checkerframework.qualframework.util.ExtendedTypeMirror;

/** {@code TreeAnnotator} instance for qualifier parameter checkers. */
public class QualifierParameterTreeAnnotator extends TreeAnnotator> {
    private QualifierParameterTypeFactory factory;

    public QualifierParameterTreeAnnotator(QualifierParameterTypeFactory factory) {
        super();
        this.factory = factory;
    }

    // These overrides are intended to avoid adding invalid qualifier
    // parameters due to the Checker Framework's default annotation handling.
    // In particular, we want to prevent the framework from adding more
    // qualifier parameters than the type actually declares, such as producing
    // the type "C<>" when C only declares "C<>".

    @Override
    public QualifiedTypeMirror> visitCompoundAssignment(CompoundAssignmentTree node, ExtendedTypeMirror type) {
        QualifiedTypeMirror> result = super.visitCompoundAssignment(node, type);
        return filterParams(result);
    }

    @Override
    public QualifiedTypeMirror> visitBinary(BinaryTree node, ExtendedTypeMirror type) {
        QualifiedTypeMirror> result = super.visitBinary(node, type);
        return filterParams(result);
    }

    @Override
    public QualifiedTypeMirror> visitUnary(UnaryTree node, ExtendedTypeMirror type) {
        QualifiedTypeMirror> result = super.visitUnary(node, type);
        return filterParams(result);
    }

    @Override
    public QualifiedTypeMirror> visitConditionalExpression(ConditionalExpressionTree node, ExtendedTypeMirror type) {
        QualifiedTypeMirror> result = super.visitConditionalExpression(node, type);
        return filterParams(result);
    }

    @Override
    public QualifiedTypeMirror> visitTypeCast(TypeCastTree node, ExtendedTypeMirror type) {
        QualifiedTypeMirror> result = super.visitTypeCast(node, type);
        return filterParams(result);
    }

    /** Filter the {@link QualParams} on a {@link QualifiedTypeMirror} to
     * ensure that only the type's declared parameters are present.
     */
    private QualifiedTypeMirror> filterParams(QualifiedTypeMirror> type) {
        if (type.getKind() != TypeKind.DECLARED) {
            return type;
        }

        QualifiedDeclaredType> declType = (QualifiedDeclaredType>)type;

        Element elt = declType.getUnderlyingType().asElement();
        Set validParams = factory.getAnnotationConverter().getDeclaredParameters(
                elt, factory.getDeclAnnotations(elt), factory.getDecoratedElement(elt));

        if (validParams.equals(type.getQualifier().keySet())) {
            return type;
        }

        Map> params = new HashMap<>(type.getQualifier());
        params.keySet().retainAll(validParams);
        return SetQualifierVisitor.apply(type, new QualParams<>(params, type.getQualifier().getPrimary()));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy