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

import java.util.Set;
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.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;

  public NullnessValue(
      CFAbstractAnalysis analysis,
      Set annotations,
      TypeMirror underlyingType) {
    super(analysis, annotations, underlyingType);
  }

  @Override
  public NullnessValue leastUpperBound(NullnessValue other) {
    NullnessValue result = super.leastUpperBound(other);

    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)
        + ", "
        + (isPolyNullNonNull ? 't' : 'f')
        + ' '
        + (isPolyNullNull ? 't' : 'f')
        + '}';
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy