• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package annotations.el;
2 
3 import annotations.util.Hasher;
4 
5 /*>>>
6 import org.checkerframework.checker.nullness.qual.*;
7 */
8 
9 /**
10  * A {@link RelativeLocation} holds location information for a
11  * instanceof, cast, or new: either the bytecode offset or the source code index.
12  * I call instanceof, cast, or new "the construct".
13  */
14 public final class RelativeLocation implements Comparable<RelativeLocation> {
15     /**
16      * The bytecode offset of the construct.
17      */
18     public final int offset;
19 
20     /**
21      * The source code index of the construct.
22      */
23     public final int index;
24 
25     /**
26      * The type index used for intersection types in casts.
27      */
28     public final int type_index;
29 
30     /**
31      * Constructs a new {@link RelativeLocation}; the arguments are assigned to
32      * the fields of the same names.
33      * Use -1 for the relative location that you're not using
34      */
RelativeLocation(int offset, int index, int type_index)35     private RelativeLocation(int offset, int index, int type_index) {
36         this.offset = offset;
37         this.index = index;
38         this.type_index = type_index;
39     }
40 
createOffset(int offset, int type_index)41     public static RelativeLocation createOffset(int offset, int type_index) {
42         return new RelativeLocation(offset, -1, type_index);
43     }
44 
createIndex(int index, int type_index)45     public static RelativeLocation createIndex(int index, int type_index) {
46         return new RelativeLocation(-1, index, type_index);
47     }
48 
isBytecodeOffset()49     public boolean isBytecodeOffset() {
50         return offset>-1;
51     }
52 
getLocationString()53     public String getLocationString() {
54         if (isBytecodeOffset()) {
55             return "#" + offset;
56         } else {
57             return "*" + index;
58         }
59     }
60 
61     @Override
compareTo(RelativeLocation l)62     public int compareTo(RelativeLocation l) {
63         int c = Integer.compare(offset,  l.offset);
64         if (c == 0) {
65             c = Integer.compare(index, l.index);
66             if (c == 0) {
67                 c = Integer.compare(type_index, l.type_index);
68             }
69         }
70         return c;
71     }
72 
73     /**
74      * Returns whether this {@link RelativeLocation} equals <code>o</code>; a
75      * slightly faster variant of {@link #equals(Object)} for when the argument
76      * is statically known to be another nonnull {@link RelativeLocation}.
77      */
equals(RelativeLocation l)78     public boolean equals(RelativeLocation l) {
79         return compareTo(l) == 0;
80     }
81 
82     /**
83      * This {@link RelativeLocation} equals <code>o</code> if and only if
84      * <code>o</code> is another nonnull {@link RelativeLocation} and
85      * <code>this</code> and <code>o</code> have equal {@link #offset} and {@link #index}.
86      */
87     @Override
equals(Object o)88     public boolean equals(Object o) {
89         return o instanceof RelativeLocation
90                 && equals((RelativeLocation) o);
91     }
92 
93     /**
94      * {@inheritDoc}
95      */
96     @Override
hashCode()97     public int hashCode() {
98         Hasher h = new Hasher();
99         h.mash(offset);
100         h.mash(index);
101         h.mash(type_index);
102         return h.hash;
103     }
104 
105     @Override
toString()106     public String toString() {
107         return "RelativeLocation(" + getLocationString() + ")";
108     }
109 }
110