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

Checker Qual is the set of annotations (qualifiers) and supporting classes used by the Checker Framework to type check Java source code. Please see artifact: org.checkerframework:checker

There is a newer version: 3.45.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