changes on the composite location generation (but still it doesn't work) & found...
[IRC.git] / Robust / src / Analysis / SSJava / GlobalFlowGraph.java
index 490ab5853be7baff49658065ef718bd1446772b4..a9ef90af670271b032e3b6b86fdd81814699e528 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Set;
 
 import IR.Descriptor;
 import IR.MethodDescriptor;
+import IR.Tree.MethodInvokeNode;
 
 public class GlobalFlowGraph {
 
@@ -18,18 +19,25 @@ public class GlobalFlowGraph {
 
   Map<NTuple<Location>, GlobalFlowNode> mapLocTupleToNode;
   Map<GlobalFlowNode, Set<GlobalFlowNode>> mapFlowNodeToOutNodeSet;
+  Map<GlobalFlowNode, Set<GlobalFlowNode>> mapFlowNodeToInNodeSet;
 
   Map<Location, CompositeLocation> mapLocationToInferCompositeLocation;
 
-  Map<MethodDescriptor, Map<NTuple<Location>, NTuple<Location>>> mapCalleeToMapCallerArgToCalleeArg;
-
   public GlobalFlowGraph(MethodDescriptor md) {
     this.md = md;
     this.mapLocTupleToNode = new HashMap<NTuple<Location>, GlobalFlowNode>();
     this.mapFlowNodeToOutNodeSet = new HashMap<GlobalFlowNode, Set<GlobalFlowNode>>();
+    this.mapFlowNodeToInNodeSet = new HashMap<GlobalFlowNode, Set<GlobalFlowNode>>();
+
     this.mapLocationToInferCompositeLocation = new HashMap<Location, CompositeLocation>();
-    this.mapCalleeToMapCallerArgToCalleeArg =
-        new HashMap<MethodDescriptor, Map<NTuple<Location>, NTuple<Location>>>();
+  }
+
+  public MethodDescriptor getMethodDescriptor() {
+    return md;
+  }
+
+  public Map<Location, CompositeLocation> getMapLocationToInferCompositeLocation() {
+    return mapLocationToInferCompositeLocation;
   }
 
   public GlobalFlowNode getFlowNode(NTuple<Location> locTuple) {
@@ -39,7 +47,7 @@ public class GlobalFlowGraph {
     }
     return mapLocTupleToNode.get(locTuple);
   }
-  
+
   private GlobalFlowNode createNewGlobalFlowNode(NTuple<Location> locTuple) {
     GlobalFlowNode node = new GlobalFlowNode(locTuple);
     return node;
@@ -53,15 +61,17 @@ public class GlobalFlowGraph {
       // if both old and new do not share the prefix, throw error
       CompositeLocation oldCompLoc = mapLocationToInferCompositeLocation.get(loc);
 
-      if (newCompLoc.getSize() > oldCompLoc.getSize()) {
-        for (int i = 0; i < oldCompLoc.getSize(); i++) {
+      if (newCompLoc.getSize() == oldCompLoc.getSize()) {
+        for (int i = 0; i < oldCompLoc.getSize() - 1; i++) {
           Location oldLocElement = oldCompLoc.get(i);
           Location newLocElement = newCompLoc.get(i);
 
           if (!oldLocElement.equals(newLocElement)) {
-            throw new Error("Failed to generate a composite location");
+            throw new Error("Failed to generate a composite location. The old composite location="
+                + oldCompLoc + " and the new composite location=" + newCompLoc);
           }
         }
+      } else if (newCompLoc.getSize() > oldCompLoc.getSize()) {
         mapLocationToInferCompositeLocation.put(loc, newCompLoc);
       }
 
@@ -81,6 +91,11 @@ public class GlobalFlowGraph {
 
   public void addValueFlowEdge(NTuple<Location> fromLocTuple, NTuple<Location> toLocTuple) {
 
+    Location lastElementfromLocTuple = fromLocTuple.get(fromLocTuple.size() - 1);
+    if (lastElementfromLocTuple.getLocDescriptor().equals(LocationInference.LITERALDESC)) {
+      return;
+    }
+
     GlobalFlowNode fromNode = getFlowNode(fromLocTuple);
     GlobalFlowNode toNode = getFlowNode(toLocTuple);
 
@@ -89,8 +104,20 @@ public class GlobalFlowGraph {
     }
     mapFlowNodeToOutNodeSet.get(fromNode).add(toNode);
 
-    System.out.println("create a global edge from " + fromNode + " to " + toNode);
+    if (!mapFlowNodeToInNodeSet.containsKey(toNode)) {
+      mapFlowNodeToInNodeSet.put(toNode, new HashSet<GlobalFlowNode>());
+    }
+    mapFlowNodeToInNodeSet.get(toNode).add(fromNode);
+
+    // System.out.println("create a global edge from " + fromNode + " to " + toNode);
+
+  }
 
+  public Set<GlobalFlowNode> getInNodeSet(GlobalFlowNode node) {
+    if (!mapFlowNodeToInNodeSet.containsKey(node)) {
+      mapFlowNodeToInNodeSet.put(node, new HashSet<GlobalFlowNode>());
+    }
+    return mapFlowNodeToInNodeSet.get(node);
   }
 
   public Set<GlobalFlowNode> getNodeSet() {
@@ -195,6 +222,80 @@ public class GlobalFlowGraph {
 
   }
 
+  public Set<GlobalFlowNode> getIncomingNodeSetByPrefix(Location prefix) {
+
+    Set<GlobalFlowNode> incomingNodeSet = new HashSet<GlobalFlowNode>();
+
+    for (Iterator iterator = getNodeSet().iterator(); iterator.hasNext();) {
+      GlobalFlowNode curNode = (GlobalFlowNode) iterator.next();
+      Set<GlobalFlowNode> outNodeSet = getOutNodeSet(curNode);
+
+      for (Iterator iterator2 = outNodeSet.iterator(); iterator2.hasNext();) {
+        GlobalFlowNode outNode = (GlobalFlowNode) iterator2.next();
+
+        if (outNode.getLocTuple().startsWith(prefix)) {
+          incomingNodeSet.add(curNode);
+          recurIncomingNodeSetByPrefix(prefix, curNode, incomingNodeSet);
+        }
+
+      }
+    }
+
+    return incomingNodeSet;
+
+  }
+
+  private void recurIncomingNodeSetByPrefix(Location prefix, GlobalFlowNode node,
+      Set<GlobalFlowNode> visited) {
+
+    Set<GlobalFlowNode> inNodeSet = getInNodeSet(node);
+
+    for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) {
+      GlobalFlowNode curNode = (GlobalFlowNode) iterator.next();
+
+      if (!curNode.getLocTuple().startsWith(prefix) && !visited.contains(curNode)) {
+        visited.add(curNode);
+        recurIncomingNodeSetByPrefix(prefix, curNode, visited);
+      }
+    }
+
+  }
+
+  public Set<GlobalFlowNode> getReachableNodeSetByPrefix(Location prefix) {
+
+    Set<GlobalFlowNode> reachableNodeSet = new HashSet<GlobalFlowNode>();
+
+    for (Iterator iterator = getNodeSet().iterator(); iterator.hasNext();) {
+      GlobalFlowNode curNode = (GlobalFlowNode) iterator.next();
+
+      if (curNode.getLocTuple().startsWith(prefix)) {
+        Set<GlobalFlowNode> outNodeSet = getOutNodeSet(curNode);
+        for (Iterator iterator2 = outNodeSet.iterator(); iterator2.hasNext();) {
+          GlobalFlowNode outNode = (GlobalFlowNode) iterator2.next();
+          if (!outNode.getLocTuple().startsWith(prefix) && !reachableNodeSet.contains(outNode)) {
+            reachableNodeSet.add(outNode);
+            recurReachableNodeSetByPrefix(prefix, outNode, reachableNodeSet);
+          }
+
+        }
+      }
+    }
+
+    return reachableNodeSet;
+  }
+
+  private void recurReachableNodeSetByPrefix(Location prefix, GlobalFlowNode node,
+      Set<GlobalFlowNode> reachableNodeSet) {
+    Set<GlobalFlowNode> outNodeSet = getOutNodeSet(node);
+    for (Iterator iterator = outNodeSet.iterator(); iterator.hasNext();) {
+      GlobalFlowNode outNode = (GlobalFlowNode) iterator.next();
+      if (!outNode.getLocTuple().startsWith(prefix) && !reachableNodeSet.contains(outNode)) {
+        reachableNodeSet.add(outNode);
+        recurReachableNodeSetByPrefix(prefix, outNode, reachableNodeSet);
+      }
+    }
+  }
+
   public Set<GlobalFlowNode> getReachableNodeSetFrom(GlobalFlowNode node) {
 
     Set<GlobalFlowNode> reachableNodeSet = new HashSet<GlobalFlowNode>();