switch to spaces only..
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / TokenTuple.java
1 package Analysis.OwnershipAnalysis;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8
9 // a token touple is a pair that indicates a
10 // heap region node and an arity
11
12 // THIS CLASS IS IMMUTABLE!
13
14 public class TokenTuple extends Canonical {
15
16   private Integer token;
17   private boolean isMultiObject;
18
19   public static final int ARITY_ZEROORMORE = 0;
20   public static final int ARITY_ONE        = 1;
21   public static final int ARITY_ONEORMORE  = 2;
22   private int arity;
23
24
25   public TokenTuple(HeapRegionNode hrn) {
26     assert hrn != null;
27
28     token         = hrn.getID();
29     isMultiObject = !hrn.isSingleObject();
30     arity         = ARITY_ONE;
31     fixStuff();
32   }
33
34   public TokenTuple(Integer token,
35                     boolean isMultiObject,
36                     int arity) {
37     assert token != null;
38
39     this.token         = token;
40     this.isMultiObject = isMultiObject;
41     this.arity         = arity;
42     fixStuff();
43   }
44
45   private void fixStuff() {
46     //This is an evil hack...we should fix this stuff elsewhere...
47     if (!isMultiObject) {
48       arity=ARITY_ONE;
49     } else {
50       if (arity==ARITY_ONEORMORE)
51         arity=ARITY_ZEROORMORE;
52     }
53   }
54
55
56   public TokenTuple makeCanonical() {
57     return (TokenTuple) Canonical.makeCanonical(this);
58   }
59
60
61   public Integer getToken() {
62     return token;
63   }
64
65   public boolean isMultiObject() {
66     return isMultiObject;
67   }
68
69   public int getArity() {
70     return arity;
71   }
72
73
74   public TokenTuple unionArity(TokenTuple tt) {
75     assert tt            != null;
76     assert token         == tt.token;
77     assert isMultiObject == tt.isMultiObject;
78
79     if( isMultiObject ) {
80       // for multiple objects only zero-or-mores combined are still zero-or-more
81       // when two tokens are present (absence of a token is arity=zero and is
82       // handled outside of this method)
83       if( arity == ARITY_ZEROORMORE && tt.arity == ARITY_ZEROORMORE ) {
84         return new TokenTuple(token, true, ARITY_ZEROORMORE).makeCanonical();
85       } else {
86         return new TokenTuple(token, true, ARITY_ONEORMORE).makeCanonical();
87       }
88
89     } else {
90       // a single object region's token can only have ZEROORMORE or ONE
91       if( arity == ARITY_ZEROORMORE && tt.arity == ARITY_ZEROORMORE ) {
92         return new TokenTuple(token, false, ARITY_ZEROORMORE).makeCanonical();
93       } else {
94         return new TokenTuple(token, false, ARITY_ONE).makeCanonical();
95       }
96     }
97   }
98
99
100   public TokenTuple changeTokenTo(Integer tokenToChangeTo) {
101     assert tokenToChangeTo != null;
102
103     return new TokenTuple(tokenToChangeTo,
104                           isMultiObject,
105                           arity).makeCanonical();
106   }
107
108
109   public boolean equals(Object o) {
110     if( o == null ) {
111       return false;
112     }
113
114     if( !(o instanceof TokenTuple) ) {
115       return false;
116     }
117
118     TokenTuple tt = (TokenTuple) o;
119
120     return token.equals(tt.getToken() ) &&
121            arity ==     tt.getArity();
122   }
123
124   public int hashCode() {
125     return (token.intValue() << 2) ^ arity;
126   }
127
128
129   public String toString() {
130     String s = token.toString();
131
132     if( isMultiObject ) {
133       s += "M";
134     }
135
136     if( arity == ARITY_ZEROORMORE ) {
137       s += "*";
138     } else if( arity == ARITY_ONEORMORE ) {
139       s += "+";
140     }
141
142     return s;
143   }
144 }