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

framework.src.org.checkerframework.common.aliasing.AliasingAnnotatedTypeFactory 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.aliasing;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Set;

import javax.lang.model.element.AnnotationMirror;

import org.checkerframework.common.aliasing.qual.LeakedToResult;
import org.checkerframework.common.aliasing.qual.MaybeAliased;
import org.checkerframework.common.aliasing.qual.MaybeLeaked;
import org.checkerframework.common.aliasing.qual.NonLeaked;
import org.checkerframework.common.aliasing.qual.Unique;
import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.framework.flow.CFAbstractAnalysis;
import org.checkerframework.framework.flow.CFStore;
import org.checkerframework.framework.flow.CFTransfer;
import org.checkerframework.framework.flow.CFValue;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.framework.type.treeannotator.ImplicitsTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.PropagationTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.framework.util.MultiGraphQualifierHierarchy;
import org.checkerframework.framework.util.MultiGraphQualifierHierarchy.MultiGraphFactory;
import org.checkerframework.javacutil.AnnotationUtils;

import com.sun.source.tree.NewClassTree;

public class AliasingAnnotatedTypeFactory extends BaseAnnotatedTypeFactory {

    private final AnnotationMirror MAYBE_ALIASED, NON_LEAKED, UNIQUE, MAYBE_LEAKED;

    public AliasingAnnotatedTypeFactory(BaseTypeChecker checker) {
        super(checker);
        MAYBE_ALIASED = AnnotationUtils.fromClass(elements, MaybeAliased.class);
        NON_LEAKED = AnnotationUtils.fromClass(elements, NonLeaked.class);
        UNIQUE = AnnotationUtils.fromClass(elements, Unique.class);
        MAYBE_LEAKED = AnnotationUtils.fromClass(elements, MaybeLeaked.class);
        if (this.getClass().equals(AliasingAnnotatedTypeFactory.class)) {
            this.postInit();
        }
    }

    // @NonLeaked and @LeakedToResult are type qualifiers because of a checker
    // framework limitation (Issue 383). Once the stub parser gets updated to read
    // non-type-qualifers annotations on stub files, this annotation won't be a
    // type qualifier anymore.
    @Override
    protected Set> createSupportedTypeQualifiers() {
        return getBundledTypeQualifiersWithoutPolyAll(
                MaybeLeaked.class);
    }

    @Override
    public CFTransfer createFlowTransferFunction(
            CFAbstractAnalysis analysis) {
        CFTransfer ret = new AliasingTransfer(analysis);
        return ret;
    }

    protected class AliasingTreeAnnotator extends TreeAnnotator {

        public AliasingTreeAnnotator(AliasingAnnotatedTypeFactory atypeFactory) {
            super(atypeFactory);
        }

        @Override
        public Void visitNewClass(NewClassTree node, AnnotatedTypeMirror p) {
            // Copied hack below from SPARTA:
            // This is a horrible hack around the implementation of constructor
            // results (CF treats annotations on constructor results in stub
            // files as if it were a default and therefore ignores it.)
            // This hack ignores any annotation written in the following location:
            // new @A SomeClass();
            AnnotatedTypeMirror defaulted = atypeFactory
                    .constructorFromUse(node).first.getReturnType();
            Set defaultedSet = defaulted.getAnnotations();
            p.replaceAnnotations(defaultedSet);
            return null;
        }
    }

    @Override
    protected ListTreeAnnotator createTreeAnnotator() {
        return new ListTreeAnnotator(new AliasingTreeAnnotator(this),
                new PropagationTreeAnnotator(this), new ImplicitsTreeAnnotator(
                        this));
    }

    @Override
    protected MultiGraphQualifierHierarchy.MultiGraphFactory createQualifierHierarchyFactory() {
        return new MultiGraphQualifierHierarchy.MultiGraphFactory(this);
    }

    @Override
    public QualifierHierarchy createQualifierHierarchy(MultiGraphFactory factory) {
        return new AliasingQualifierHierarchy(factory);
    }

    protected class AliasingQualifierHierarchy extends
            MultiGraphQualifierHierarchy {

        protected AliasingQualifierHierarchy(MultiGraphFactory f) {
            super(f);
        }

        @Override
        protected Set findBottoms(
                Map> supertypes) {
            Set newbottoms = AnnotationUtils
                    .createAnnotationSet();
            newbottoms.add(UNIQUE);
            newbottoms.add(MAYBE_LEAKED);
            return newbottoms;
        }

        @Override
        protected Set findTops(
                Map> supertypes) {
            Set newtops = AnnotationUtils
                    .createAnnotationSet();
            newtops.add(MAYBE_ALIASED);
            newtops.add(NON_LEAKED);
            return newtops;
        }

        private boolean isLeakedQualifier(AnnotationMirror anno) {
            return AnnotationUtils.areSameByClass(anno, MaybeLeaked.class)
                    || AnnotationUtils.areSameByClass(anno, NonLeaked.class)
                    || AnnotationUtils.areSameByClass(anno, LeakedToResult.class);
        }

        @Override
        public boolean isSubtype(AnnotationMirror rhs, AnnotationMirror lhs) {
            if (isLeakedQualifier(lhs) && isLeakedQualifier(rhs)) {
                // @LeakedToResult and @NonLeaked were supposed to be
                // non-type-qualifiers annotations.
                // Currently the stub parser does not support non-type-qualifier
                // annotations on receiver parameters (Issue 383), therefore these
                // annotations are implemented as type qualifiers but the
                // warnings related to the hierarchy are ignored.
                return true;
            }
            return super.isSubtype(rhs, lhs);
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy