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

org.checkerframework.framework.util.element.VariableApplier 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-eisop4
Show newest version
package org.checkerframework.framework.util.element;

import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.TargetType;

import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.util.element.ElementAnnotationUtil.UnexpectedAnnotationLocationException;
import org.checkerframework.javacutil.BugInCF;

import java.util.List;

import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.type.TypeKind;

/**
 * Applies annotations to variable declaration (providing they are not the use of a TYPE_PARAMETER).
 */
public class VariableApplier extends TargetedElementAnnotationApplier {

    /**
     * Apply annotations from {@code element} to {@code type}.
     *
     * @param type the type to annotate
     * @param element the corresponding element
     * @throws UnexpectedAnnotationLocationException if there is trouble
     */
    public static void apply(AnnotatedTypeMirror type, Element element)
            throws UnexpectedAnnotationLocationException {
        new VariableApplier(type, element).extractAndApply();
    }

    /** The accepted element kinds. */
    private static final ElementKind[] acceptedKinds = {
        ElementKind.LOCAL_VARIABLE, ElementKind.RESOURCE_VARIABLE, ElementKind.EXCEPTION_PARAMETER
    };

    /**
     * Returns true if this is a variable declaration including fields an enum constants.
     *
     * @param typeMirror ignored
     * @return true if this is a variable declaration including fields an enum constants
     */
    public static boolean accepts(AnnotatedTypeMirror typeMirror, Element element) {
        return ElementAnnotationUtil.contains(element.getKind(), acceptedKinds)
                || element.getKind().isField();
    }

    /** The variable symbol. */
    private final Symbol.VarSymbol varSymbol;

    /**
     * Constructor.
     *
     * @param type the type to annotate
     * @param element the corresponding element
     */
    /*package-private*/ VariableApplier(AnnotatedTypeMirror type, Element element) {
        super(type, element);
        varSymbol = (Symbol.VarSymbol) element;

        if (type.getKind() == TypeKind.UNION
                && element.getKind() != ElementKind.EXCEPTION_PARAMETER) {
            throw new BugInCF(
                    "Union types only allowed for exception parameters. "
                            + "Type: "
                            + type
                            + " for element: "
                            + element);
        }
        // TODO: need a way to split the union types into the right alternative
        // to use for the annotation. The exception_index is probably what we
        // need to look at, but it might not be set at this point.
    }

    /** The annotated targets. */
    private static final TargetType[] annotatedTargets =
            new TargetType[] {
                TargetType.LOCAL_VARIABLE,
                TargetType.RESOURCE_VARIABLE,
                TargetType.EXCEPTION_PARAMETER,
                TargetType.FIELD
            };

    @Override
    protected TargetType[] annotatedTargets() {
        return annotatedTargets;
    }

    /** The valid targets. */
    private static final TargetType[] validTargets =
            new TargetType[] {
                TargetType.NEW,
                TargetType.CAST,
                TargetType.INSTANCEOF,
                TargetType.METHOD_INVOCATION_TYPE_ARGUMENT,
                TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
                TargetType.METHOD_REFERENCE,
                TargetType.CONSTRUCTOR_REFERENCE,
                TargetType.METHOD_REFERENCE_TYPE_ARGUMENT,
                TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
                TargetType.METHOD_FORMAL_PARAMETER,
                TargetType.CLASS_EXTENDS
            };

    @Override
    protected TargetType[] validTargets() {
        return validTargets;
    }

    @Override
    protected Iterable getRawTypeAttributes() {
        return varSymbol.getRawTypeAttributes();
    }

    @Override
    protected boolean isAccepted() {
        return accepts(type, element);
    }

    @Override
    protected void handleTargeted(List targeted)
            throws UnexpectedAnnotationLocationException {
        ElementAnnotationUtil.annotateViaTypeAnnoPosition(type, targeted);
    }

    @Override
    public void extractAndApply() throws UnexpectedAnnotationLocationException {
        // Add declaration annotations to the local variable type
        ElementAnnotationUtil.addDeclarationAnnotationsFromElement(
                type, varSymbol.getAnnotationMirrors());
        super.extractAndApply();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy