/**
 * 
 */
package accrue.analysis.notnulldataflow;

import accrue.analysis.interprocvarcontext.AbstractValue;

public class NotNullAbsVal implements AbstractValue<NotNullAbsVal> {
    static NotNullAbsVal NOT_NULL = new NotNullAbsVal(true);
    static NotNullAbsVal MAYBE_NULL = new NotNullAbsVal(false);

    private final boolean notnull;

    private NotNullAbsVal(boolean notnull) {
        this.notnull = notnull;
    }

    @Override
    public boolean leq(NotNullAbsVal that) {
        return this.notnull || !that.notnull;
    }

    @Override
    public boolean isBottom() {
        return notnull;
    }

    @Override
    public NotNullAbsVal upperBound(NotNullAbsVal that) {
        if (this.notnull) return that;
        return this;
    }

    @Override
    public NotNullAbsVal widen(NotNullAbsVal that) {
        return upperBound(that);
    }

    public boolean isNotNull() {
        return notnull;
    }

    public boolean isMaybeNull() {
        return !notnull;
    }

    public static NotNullAbsVal valueOf(boolean isNotNull) {
        return isNotNull ? NOT_NULL : MAYBE_NULL;
    }

    @Override
    public String toString() {
        return this.notnull ? "NOT_NULL" : "MAYBE_NULL";
    }

    @Override
    public int hashCode() {
        return notnull ? 34634 : 9098;
    }
}
