aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/Constant.java
blob: a95af7fa435111d42440eeef9b27c37e767aaaef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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 "???";
    }
}