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

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.44.0
Show newest version
package org.checkerframework.common.aliasing;

import com.sun.source.tree.NewArrayTree;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.util.Elements;
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.NoElementQualifierHierarchy;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.javacutil.AnnotationBuilder;

/** Annotated type factory for the Aliasing Checker. */
public class AliasingAnnotatedTypeFactory extends BaseAnnotatedTypeFactory {

  /** Aliasing annotations. */
  /** The @{@link MaybeAliased} annotation. */
  protected final AnnotationMirror MAYBE_ALIASED =
      AnnotationBuilder.fromClass(elements, MaybeAliased.class);
  /** The @{@link NonLeaked} annotation. */
  protected final AnnotationMirror NON_LEAKED =
      AnnotationBuilder.fromClass(elements, NonLeaked.class);
  /** The @{@link Unique} annotation. */
  protected final AnnotationMirror UNIQUE = AnnotationBuilder.fromClass(elements, Unique.class);
  /** The @{@link MaybeLeaked} annotation. */
  protected final AnnotationMirror MAYBE_LEAKED =
      AnnotationBuilder.fromClass(elements, MaybeLeaked.class);

  /** Create the type factory. */
  public AliasingAnnotatedTypeFactory(BaseTypeChecker checker) {
    super(checker);
    if (this.getClass() == 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-qualifiers annotations on stub
  // files, this annotation won't be a type qualifier anymore.
  @Override
  protected Set> createSupportedTypeQualifiers() {
    return getBundledTypeQualifiers(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 visitNewArray(NewArrayTree node, AnnotatedTypeMirror type) {
      type.replaceAnnotation(UNIQUE);
      return super.visitNewArray(node, type);
    }
  }

  @Override
  protected ListTreeAnnotator createTreeAnnotator() {
    return new ListTreeAnnotator(new AliasingTreeAnnotator(this), super.createTreeAnnotator());
  }

  @Override
  protected QualifierHierarchy createQualifierHierarchy() {
    return new AliasingQualifierHierarchy(this.getSupportedTypeQualifiers(), elements);
  }

  /** AliasingQualifierHierarchy. */
  protected class AliasingQualifierHierarchy extends NoElementQualifierHierarchy {

    /**
     * Create AliasingQualifierHierarchy.
     *
     * @param qualifierClasses classes of annotations that are the qualifiers
     * @param elements element utils
     */
    protected AliasingQualifierHierarchy(
        Collection> qualifierClasses, Elements elements) {
      super(qualifierClasses, elements);
    }

    /**
     * Returns true is {@code anno} is annotation in the Leaked hierarchy.
     *
     * @param anno an annotation
     * @return true is {@code anno} is annotation in the Leaked hierarchy
     */
    private boolean isLeakedQualifier(AnnotationMirror anno) {
      return areSameByClass(anno, MaybeLeaked.class)
          || areSameByClass(anno, NonLeaked.class)
          || areSameByClass(anno, LeakedToResult.class);
    }

    @Override
    public boolean isSubtype(AnnotationMirror subAnno, AnnotationMirror superAnno) {
      if (isLeakedQualifier(superAnno) && isLeakedQualifier(subAnno)) {
        // @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(subAnno, superAnno);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy