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

org.checkerframework.checker.nullness.NullnessValue 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.48.2
Show newest version
package org.checkerframework.checker.nullness;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.PolyNull;
import org.checkerframework.dataflow.qual.Pure;
import org.checkerframework.dataflow.qual.SideEffectFree;
import org.checkerframework.framework.flow.CFAbstractAnalysis;
import org.checkerframework.framework.flow.CFAbstractValue;
import org.checkerframework.framework.flow.CFValue;
import org.checkerframework.javacutil.AnnotationMirrorSet;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.TypesUtils;

/**
 * Behaves just like {@link CFValue}, but additionally tracks whether at this point {@link PolyNull}
 * is known to be {@link NonNull} or {@link Nullable} (or not known to be either)
 */
public class NullnessValue extends CFAbstractValue {

  /** True if, at this point, {@link PolyNull} is known to be {@link NonNull}. */
  protected boolean isPolyNullNonNull;

  /** True if, at this point, {@link PolyNull} is known to be {@link Nullable}. */
  protected boolean isPolyNullNull;

  /**
   * Creates a new NullnessValue.
   *
   * @param analysis the analysis
   * @param annotations the annotations
   * @param underlyingType the underlying type
   */
  public NullnessValue(
      CFAbstractAnalysis analysis,
      AnnotationMirrorSet annotations,
      TypeMirror underlyingType) {
    super(analysis, annotations, underlyingType);
  }

  @Override
  protected NullnessValue upperBound(
      @Nullable NullnessValue other, TypeMirror upperBoundTypeMirror, boolean shouldWiden) {
    NullnessValue result = super.upperBound(other, upperBoundTypeMirror, shouldWiden);

    AnnotationMirror resultNullableAnno =
        analysis.getTypeFactory().getAnnotationByClass(result.annotations, Nullable.class);

    if (resultNullableAnno != null && other != null) {
      if ((this.isPolyNullNonNull
              && this.containsNonNullOrPolyNull()
              && other.isPolyNullNull
              && other.containsNullableOrPolyNull())
          || (other.isPolyNullNonNull
              && other.containsNonNullOrPolyNull()
              && this.isPolyNullNull
              && this.containsNullableOrPolyNull())) {
        result.annotations.remove(resultNullableAnno);
        result.annotations.add(((NullnessAnnotatedTypeFactory) analysis.getTypeFactory()).POLYNULL);
      }
    }
    return result;
  }

  /**
   * Returns true if this value contans {@code @NonNull} or {@code @PolyNull}.
   *
   * @return true if this value contans {@code @NonNull} or {@code @PolyNull}
   */
  @Pure
  private boolean containsNonNullOrPolyNull() {
    return analysis.getTypeFactory().containsSameByClass(annotations, NonNull.class)
        || analysis.getTypeFactory().containsSameByClass(annotations, PolyNull.class);
  }

  /**
   * Returns true if this value contans {@code @Nullable} or {@code @PolyNull}.
   *
   * @return true if this value contans {@code @Nullable} or {@code @PolyNull}
   */
  @Pure
  private boolean containsNullableOrPolyNull() {
    return analysis.getTypeFactory().containsSameByClass(annotations, Nullable.class)
        || analysis.getTypeFactory().containsSameByClass(annotations, PolyNull.class);
  }

  @SideEffectFree
  @Override
  public String toStringSimple() {
    return "NV{"
        + AnnotationUtils.toStringSimple(annotations)
        + ", "
        + TypesUtils.simpleTypeName(underlyingType)
        + ", poly nn/n="
        + (isPolyNullNonNull ? 't' : 'f')
        + '/'
        + (isPolyNullNull ? 't' : 'f')
        + '}';
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy