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

framework.src.org.checkerframework.common.value.ValueVisitor 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.common.value;

import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.common.value.qual.ArrayLen;
import org.checkerframework.common.value.qual.BoolVal;
import org.checkerframework.common.value.qual.DoubleVal;
import org.checkerframework.common.value.qual.IntVal;
import org.checkerframework.common.value.qual.StringVal;
import org.checkerframework.framework.source.Result;

import java.util.List;

import javax.lang.model.element.Element;

import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.tree.TypeCastTree;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeInfo;

/**
 * @author plvines
 *
 *         Visitor for the Constant Value type-system.
 *
 */
public class ValueVisitor extends BaseTypeVisitor {

    public ValueVisitor(BaseTypeChecker checker) {
        super(checker);
    }

    @Override
    protected ValueAnnotatedTypeFactory createTypeFactory() {
        return new ValueAnnotatedTypeFactory(checker);
    }

    /**
     * Issues a warning if any constant-value annotation has > MAX_VALUES number of values provided.
     * Works together with ValueAnnotatedTypeFactory.ValueTypeAnnotator.replaceWithUnknownValIfTooManyValues
     * which treats the value as @UnknownVal in this case.
     */
    @Override
    public Void visitAnnotation(AnnotationTree node, Void p) {
        List args = node.getArguments();

        if (args.isEmpty()) {
            // Nothing to do if there are no annotation arguments.
            return super.visitAnnotation(node, p);
        }

        Element element = TreeInfo.symbol((JCTree) node.getAnnotationType());
        if (!(element.toString().equals(ArrayLen.class.getName())
                || element.toString().equals(BoolVal.class.getName())
                || element.toString().equals(DoubleVal.class.getName())
                || element.toString().equals(IntVal.class.getName()) || element
                .toString().equals(StringVal.class.getName()))) {
            return super.visitAnnotation(node, p);
        }

        if (node.getArguments().size() > 0
                && node.getArguments().get(0).getKind() == Kind.ASSIGNMENT) {
            AssignmentTree argument = (AssignmentTree) node.getArguments().get(
                    0);
            if (argument.getExpression().getKind() == Tree.Kind.NEW_ARRAY) {
                int numArgs = ((NewArrayTree) argument.getExpression())
                        .getInitializers().size();

                if (numArgs > ValueAnnotatedTypeFactory.MAX_VALUES) {
                    checker.report(Result.warning("too.many.values.given",
                            ValueAnnotatedTypeFactory.MAX_VALUES), node);
                    return null;
                }
            }

        }
        return super.visitAnnotation(node, p);
    }

    @Override
    public Void visitTypeCast(TypeCastTree node, Void p) {
        if (node.getExpression().getKind() == Kind.NULL_LITERAL) {
            return null;
        }
        return super.visitTypeCast(node, p);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy