1 package Analysis.Disjoint;
8 // A edge existence predicate is satisfied if the elements
9 // defining an edge are part of the given graph.
10 // The reach state may be null--if not the predicate is
11 // satisfied when the edge exists AND it has the state.
13 public class ExistPredEdge extends Canonical {
15 // the source of an edge is *either* a variable
16 // node or a heap region node
17 protected TempDescriptor tdSrc;
18 protected Integer hrnSrcID;
20 // dst is always a heap region
21 protected Integer hrnDstID;
23 // a reference has a field name and type
24 protected TypeDescriptor type;
25 protected String field;
28 protected ReachState state;
31 public ExistPredEdge( TempDescriptor tdSrc,
38 assert (vnSrc == null) || (hrnSrcID == null);
39 assert hrnDstID != null;
44 this.hrnSrcID = hrnSrcID;
45 this.hrnDstID = hrnDstID;
51 public boolean isSatisfiedBy( ReachGraph rg ) {
53 // first establish whether the source of the
54 // reference edge exists
55 VariableNode vnSrc = rg.td2vn.get( tdSrc );
56 HeapRegionNode hrnSrc = rg.id2hrn.get( hrnSrcID );
57 assert (vnSrc == null) || (hrnSrc == null);
59 // the source is not present in graph
60 if( vnSrc == null && hrnSrc == null ) {
71 // is the destination present?
72 HeapRegionNode hrnDst = rg.id2hrn.get( hrnDstID );
73 if( hrnDst == null ) {
77 // is there an edge between them with the given
79 // TODO: type OR a subtype?
80 RefEdge edge = rsn.getReferenceTo( hrnDst, type, field );
85 // when state is null it is not part of the predicate
86 // so we've satisfied the edge existence
91 // otherwise look for state too
92 // TODO: contains OR containsSuperSet OR containsWithZeroes??
93 return hrnDst.getAlpha().contains( state );
97 public boolean equals( Object o ) {
102 if( !(o instanceof ExistPredEdge) ) {
106 ExistPredEdge epn = (ExistPredEdge) o;
109 this.hrnSrcID = hrnSrcID;
110 this.hrnDstID = hrnDstID;
115 if( tdSrc == null && epn.tdSrc != null ) {
117 } else if( !tdSrc.equals( epn.tdSrc ) ) {
121 if( hrnSrcID == null && epn.hrnSrcID != null ) {
123 } else if( !hrnSrcID.equals( epn.hrnSrcID ) ) {
127 if( !hrnDstID.equals( epn.hrnDstID ) ) {
131 if( !type.equals( epn.type ) ) {
135 if( !field.equals( epn.field ) ) {
139 // ReachState objects are cannonical
140 return state == epn.state;
143 public int hashCode() {
146 hash += type.hashCode()*17;
148 if( field != null ) {
149 hash += field.hashCode()*7;
152 if( tdSrc != null ) {
153 hash += tdSrc.hashCode()*11;
155 hash += hrnSrcID.hashCode()*11;
158 hash += hrnDst.hashCode();
160 if( state != null ) {
161 hash += state.hashCode();
168 public String toString() {
171 if( tdSrc != null ) {
172 s += tdSrc.toString();
174 s += hrnSrcID.toString();
177 s += "-->"+hrnDstID+")";
179 if( state != null ) {