blob: a95af7fa435111d42440eeef9b27c37e767aaaef [file] [log] [blame]
package org.checkerframework.dataflow.constantpropagation;
/*>>>
import org.checkerframework.checker.nullness.qual.Nullable;
*/
import java.util.Objects;
import org.checkerframework.dataflow.analysis.AbstractValue;
public class Constant implements AbstractValue<Constant> {
/** What kind of abstract value is this? */
protected Type type;
/** The value of this abstract value (or null) */
protected /*@Nullable*/ Integer value;
public enum Type {
CONSTANT,
TOP,
BOTTOM,
}
public Constant(Type type) {
assert !type.equals(Type.CONSTANT);
this.type = type;
}
public Constant(Integer value) {
this.type = Type.CONSTANT;
this.value = value;
}
public boolean isTop() {
return type.equals(Type.TOP);
}
public boolean isBottom() {
return type.equals(Type.BOTTOM);
}
public boolean isConstant() {
return type.equals(Type.CONSTANT);
}
public Integer getValue() {
assert isConstant();
return value;
}
public Constant copy() {
if (isConstant()) {
return new Constant(value);
}
return new Constant(type);
}
@Override
public Constant leastUpperBound(Constant other) {
if (other.isBottom()) {
return this.copy();
}
if (this.isBottom()) {
return other.copy();
}
if (other.isTop() || this.isTop()) {
return new Constant(Type.TOP);
}
if (other.getValue().equals(getValue())) {
return this.copy();
}
return new Constant(Type.TOP);
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Constant)) {
return false;
}
Constant other = (Constant) obj;
return type == other.type && Objects.equals(value, other.value);
}
@Override
public int hashCode() {
return type.hashCode() + (value != null ? value.hashCode() : 0);
}
@Override
public String toString() {
switch (type) {
case TOP:
return "T";
case BOTTOM:
return "-";
case CONSTANT:
return value.toString();
}
assert false;
return "???";
}
}