start implementing basic approach
authoryeom <yeom>
Tue, 10 Apr 2012 22:48:07 +0000 (22:48 +0000)
committeryeom <yeom>
Tue, 10 Apr 2012 22:48:07 +0000 (22:48 +0000)
Robust/src/Analysis/SSJava/FlowGraph.java [new file with mode: 0644]
Robust/src/Analysis/SSJava/FlowNode.java [new file with mode: 0644]
Robust/src/Analysis/SSJava/InferGraph.java [deleted file]
Robust/src/Analysis/SSJava/InferNode.java [deleted file]
Robust/src/Analysis/SSJava/LocationInference.java

diff --git a/Robust/src/Analysis/SSJava/FlowGraph.java b/Robust/src/Analysis/SSJava/FlowGraph.java
new file mode 100644 (file)
index 0000000..f979096
--- /dev/null
@@ -0,0 +1,96 @@
+package Analysis.SSJava;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import IR.Descriptor;
+import IR.MethodDescriptor;
+
+public class FlowGraph {
+
+  MethodDescriptor md;
+
+  Set<FlowNode> nodeSet;
+  FlowNode thisVarNode;
+
+  // maps the composite representation of field/var descriptors to infer nodes
+  Map<NTuple<Descriptor>, FlowNode> mapDescTupleToInferNode;
+
+  // maps an infer node to the set of neighbors which is pointed by the node
+  Map<NTuple<Descriptor>, Set<FlowNode>> mapNodeToNeighborSet;
+
+  boolean debug = true;
+
+  public FlowGraph(MethodDescriptor md) {
+    this.md = md;
+    nodeSet = new HashSet<FlowNode>();
+    mapDescTupleToInferNode = new HashMap<NTuple<Descriptor>, FlowNode>();
+    mapNodeToNeighborSet = new HashMap<NTuple<Descriptor>, Set<FlowNode>>();
+
+    // create a node for 'this' varialbe
+    FlowNode thisNode = new FlowNode(null, md.getThis());
+    NTuple<Descriptor> thisVarTuple = new NTuple<Descriptor>();
+    thisVarTuple.add(md.getThis());
+    mapDescTupleToInferNode.put(thisVarTuple, thisNode);
+    thisVarNode = thisNode;
+
+  }
+
+  public void addNeighbor(FlowNode node, FlowNode neighbor) {
+    Set<FlowNode> set = mapNodeToNeighborSet.get(node);
+    if (set == null) {
+      set = new HashSet<FlowNode>();
+    }
+    set.add(neighbor);
+
+    System.out.println("add a new neighbor " + neighbor + " to " + node);
+  }
+
+  public void addValueFlowEdge(NTuple<Descriptor> fromDescTuple, NTuple<Descriptor> toDescTuple) {
+
+    FlowNode fromNode = mapDescTupleToInferNode.get(fromDescTuple);
+    FlowNode toNode = mapDescTupleToInferNode.get(toDescTuple);
+
+    System.out.println("create an edge from " + fromNode + " to " + toNode);
+
+    int fromTupleSize = fromDescTuple.size();
+    NTuple<Descriptor> curTuple = new NTuple<Descriptor>();
+    for (int i = 0; i < fromTupleSize; i++) {
+      Descriptor desc = fromDescTuple.get(i);
+      curTuple.add(desc);
+      addNeighbor(getInferNode(curTuple), toNode);
+    }
+
+    int toTupleSize = toDescTuple.size();
+    curTuple = new NTuple<Descriptor>();
+    for (int i = 0; i < toTupleSize; i++) {
+      Descriptor desc = toDescTuple.get(i);
+      curTuple.add(desc);
+      addNeighbor(fromNode, getInferNode(curTuple));
+    }
+
+  }
+
+  public FlowNode getInferNode(NTuple<Descriptor> descTuple) {
+    if (mapDescTupleToInferNode.containsKey(descTuple)) {
+      return mapDescTupleToInferNode.get(descTuple);
+    }
+    return null;
+  }
+
+  public FlowNode getThisVarNode() {
+    return thisVarNode;
+  }
+
+  public void createNewFlowNode(NTuple<Descriptor> base) {
+
+    FlowNode node = new FlowNode(base);
+    mapDescTupleToInferNode.put(base, node);
+
+    System.out.println("Creating new node=" + node);
+
+  }
+
+}
diff --git a/Robust/src/Analysis/SSJava/FlowNode.java b/Robust/src/Analysis/SSJava/FlowNode.java
new file mode 100644 (file)
index 0000000..cc7d4ee
--- /dev/null
@@ -0,0 +1,46 @@
+package Analysis.SSJava;
+
+import java.util.Set;
+
+import IR.Descriptor;
+
+public class FlowNode {
+
+  // descriptor tuple is a unique identifier of the flow node
+  private NTuple<Descriptor> descTuple;
+
+  // if the infer node represents the base type of field access,
+  // this set contains fields of the base type
+  private Set<FlowNode> fieldNodeSet;
+
+  public FlowNode(Descriptor desc) {
+    this(null, desc);
+  }
+
+  public FlowNode(NTuple<Descriptor> base) {
+    this(base, null);
+  }
+
+  public FlowNode(NTuple<Descriptor> base, Descriptor desc) {
+    descTuple = new NTuple<Descriptor>();
+    if (base != null) {
+      descTuple.addAll(base);
+    }
+    if (desc != null) {
+      descTuple.add(desc);
+    }
+  }
+
+  public NTuple<Descriptor> getDescTuple() {
+    return descTuple;
+  }
+
+  public Descriptor getOwnDescriptor() {
+    return descTuple.get(descTuple.size() - 1);
+  }
+
+  public String toString() {
+    return "[FlowNode]::" + descTuple;
+  }
+
+}
diff --git a/Robust/src/Analysis/SSJava/InferGraph.java b/Robust/src/Analysis/SSJava/InferGraph.java
deleted file mode 100644 (file)
index e49b62d..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-package Analysis.SSJava;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import IR.Descriptor;
-
-public class InferGraph {
-
-  Set<InferNode> nodeSet;
-
-  // having one location for the top location
-  private static final int topLocationID = 1;
-
-  // unique ID seed
-  private static int uniqueID = 10000;
-
-  // maps descriptors (field and local var descriptors) to its unique integer id
-  Map<Descriptor, Integer> mapDescriptorToUniqueID;
-
-  // maps field/var descriptros to infer nodes
-  Map<Descriptor, InferNode> mapDescToInferNode;
-
-  boolean debug = true;
-
-  public InferGraph() {
-    nodeSet = new HashSet<InferNode>();
-    mapDescToInferNode = new HashMap<Descriptor, InferNode>();
-    mapDescriptorToUniqueID = new HashMap<Descriptor, Integer>();
-  }
-
-  public void addValueFlowEdge(Descriptor fromDesc, Descriptor toDesc) {
-
-  }
-
-  public InferNode getInferNode(Descriptor desc) {
-    if (mapDescToInferNode.containsKey(desc)) {
-
-    }
-    return null;
-  }
-
-  public void assignTopLocationToDescriptor(Descriptor desc) {
-    mapDescriptorToUniqueID.put(desc, Integer.valueOf((topLocationID)));
-    debug_uniqueid_print(desc);
-  }
-
-  public void assignUniqueIDtoDescriptor(Descriptor desc) {
-    mapDescriptorToUniqueID.put(desc, getUniqueID());
-    debug_uniqueid_print(desc);
-  }
-
-  private int getUniqueID() {
-    return uniqueID++;
-  }
-
-  private void debug_uniqueid_print(Descriptor d) {
-    if (debug) {
-      int id = mapDescriptorToUniqueID.get(d).intValue();
-      System.out.print(d + " -> ");
-      if (id == topLocationID) {
-        System.out.println("TOP");
-      } else {
-        System.out.println(id);
-      }
-
-    }
-  }
-}
diff --git a/Robust/src/Analysis/SSJava/InferNode.java b/Robust/src/Analysis/SSJava/InferNode.java
deleted file mode 100644 (file)
index b00b4e0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package Analysis.SSJava;
-
-import IR.Descriptor;
-
-public class InferNode {
-
-  private Descriptor desc;
-  private int id;
-
-  public Descriptor getDesc() {
-    return desc;
-  }
-
-  public void setDesc(Descriptor desc) {
-    this.desc = desc;
-  }
-
-  public int getId() {
-    return id;
-  }
-
-  public void setId(int id) {
-    this.id = id;
-  }
-
-}
index 2bb1330bdd5d46ea3a58227c8ec2384c737e12fe..275b5293f1d6d1005f75f0bb96ec5bfa4f45f009 100644 (file)
@@ -4,14 +4,17 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import IR.ClassDescriptor;
 import IR.Descriptor;
 import IR.FieldDescriptor;
 import IR.MethodDescriptor;
+import IR.NameDescriptor;
+import IR.Operation;
 import IR.State;
 import IR.SymbolTable;
 import IR.VarDescriptor;
@@ -34,7 +37,6 @@ import IR.Tree.NameNode;
 import IR.Tree.OpNode;
 import IR.Tree.ReturnNode;
 import IR.Tree.SubBlockNode;
-import IR.Tree.SwitchBlockNode;
 import IR.Tree.SwitchStatementNode;
 import IR.Tree.TertiaryNode;
 
@@ -45,17 +47,16 @@ public class LocationInference {
 
   List<ClassDescriptor> toanalyzeList;
   List<MethodDescriptor> toanalyzeMethodList;
+  Map<MethodDescriptor, FlowGraph> mapMethodDescriptorToFlowGraph;
 
   boolean debug = true;
 
-  InferGraph graph;
-
   public LocationInference(SSJavaAnalysis ssjava, State state) {
     this.ssjava = ssjava;
     this.state = state;
     this.toanalyzeList = new ArrayList<ClassDescriptor>();
     this.toanalyzeMethodList = new ArrayList<MethodDescriptor>();
-    this.graph = new InferGraph();
+    this.mapMethodDescriptorToFlowGraph = new HashMap<MethodDescriptor, FlowGraph>();
   }
 
   public void setupToAnalyze() {
@@ -97,51 +98,8 @@ public class LocationInference {
     return toanalyzeMethodList.remove(0);
   }
 
-  private void checkDeclarationInClass(ClassDescriptor cd) {
-    // Check to see that fields are okay
-    for (Iterator field_it = cd.getFields(); field_it.hasNext();) {
-      FieldDescriptor fd = (FieldDescriptor) field_it.next();
-
-      if (!(fd.isFinal() && fd.isStatic())) {
-        analyzeFieldDeclaration(cd, fd);
-      } else {
-        // for static final, assign top location by default
-        graph.assignTopLocationToDescriptor(fd);
-      }
-    }
-  }
-
-  private void analyzeFieldDeclaration(ClassDescriptor cd, FieldDescriptor fd) {
-    graph.assignUniqueIDtoDescriptor(fd);
-  }
-
   public void inference() {
 
-    // 1) assign a unique id to every field & variable
-    setupToAnalyze();
-
-    while (!toAnalyzeIsEmpty()) {
-      ClassDescriptor cd = toAnalyzeNext();
-
-      System.out.println("SSJAVA: Location Inference on the class: " + cd);
-      checkDeclarationInClass(cd);
-
-      setupToAnalazeMethod(cd);
-      while (!toAnalyzeMethodIsEmpty()) {
-        MethodDescriptor md = toAnalyzeMethodNext();
-
-        if (ssjava.needTobeAnnotated(md)) {
-          // assigns unique id to the method parameters
-          assignUniqueIDMethodParamteres(cd, md);
-
-          if (state.SSJAVADEBUG) {
-            System.out.println("SSJAVA: Location Inference on the method: " + md);
-          }
-          assignUniqueIDMethodBody(cd, md);
-        }
-      }
-    }
-
     // 2) construct value flow graph
 
     setupToAnalyze();
@@ -156,6 +114,8 @@ public class LocationInference {
           if (state.SSJAVADEBUG) {
             System.out.println("SSJAVA: Constructing a flow graph: " + md);
           }
+          FlowGraph fg = new FlowGraph(md);
+          mapMethodDescriptorToFlowGraph.put(md, fg);
           analyzeMethodBody(cd, md);
         }
       }
@@ -165,109 +125,395 @@ public class LocationInference {
 
   private void analyzeMethodBody(ClassDescriptor cd, MethodDescriptor md) {
     BlockNode bn = state.getMethodBody(md);
-    // checkLocationFromBlockNode(md, md.getParameterTable(), bn, constraints);
+    analyzeBlockNode(md, md.getParameterTable(), bn);
   }
 
-  private void assignUniqueIDMethodParamteres(ClassDescriptor cd, MethodDescriptor md) {
-
-    List<CompositeLocation> paramList = new ArrayList<CompositeLocation>();
-    for (int i = 0; i < md.numParameters(); i++) {
-      // process annotations on method parameters
-      VarDescriptor vd = (VarDescriptor) md.getParameter(i);
-      graph.assignUniqueIDtoDescriptor(vd);
-    }
-
-  }
-
-  private void assignUniqueIDMethodBody(ClassDescriptor cd, MethodDescriptor md) {
-    BlockNode bn = state.getMethodBody(md);
-    assignUniqueIDBlockNode(md, md.getParameterTable(), bn);
-  }
-
-  private void assignUniqueIDBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) {
+  private void analyzeBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) {
 
     bn.getVarTable().setParent(nametable);
     for (int i = 0; i < bn.size(); i++) {
       BlockStatementNode bsn = bn.get(i);
-      assignUniqueIDBlockStatementNode(md, bn.getVarTable(), bsn);
+      analyzeBlockStatementNode(md, bn.getVarTable(), bsn);
     }
 
   }
 
-  private void assignUniqueIDBlockStatementNode(MethodDescriptor md, SymbolTable nametable,
+  private void analyzeBlockStatementNode(MethodDescriptor md, SymbolTable nametable,
       BlockStatementNode bsn) {
 
     switch (bsn.kind()) {
+    case Kind.BlockExpressionNode:
+      analyzeBlockExpressionNode(md, nametable, (BlockExpressionNode) bsn);
+      break;
 
     case Kind.DeclarationNode:
-      assignUniqueIDDeclarationNode(md, nametable, (DeclarationNode) bsn);
+      analyzeFlowDeclarationNode(md, nametable, (DeclarationNode) bsn, new NTuple<Descriptor>());
       break;
 
     case Kind.IfStatementNode:
-      assignUniqueIDIfStatementNode(md, nametable, (IfStatementNode) bsn);
+      analyzeIfStatementNode(md, nametable, (IfStatementNode) bsn);
       break;
 
     case Kind.LoopNode:
-      assignUniqueIDLoopNode(md, nametable, (LoopNode) bsn);
+      analyzeLoopNode(md, nametable, (LoopNode) bsn);
+      break;
+
+    case Kind.ReturnNode:
+      analyzeReturnNode(md, nametable, (ReturnNode) bsn);
       break;
 
     case Kind.SubBlockNode:
-      assignUniqueIDSubBlockNode(md, nametable, (SubBlockNode) bsn);
+      analyzeSubBlockNode(md, nametable, (SubBlockNode) bsn);
       break;
 
     case Kind.ContinueBreakNode:
       break;
 
     case Kind.SwitchStatementNode:
-      assignUniqueIDSwitchStatementNode(md, nametable, (SwitchStatementNode) bsn);
+      analyzeSwitchStatementNode(md, nametable, (SwitchStatementNode) bsn);
+      break;
+
     }
 
   }
 
-  private void assignUniqueIDSwitchStatementNode(MethodDescriptor md, SymbolTable nametable,
-      SwitchStatementNode ssn) {
-    BlockNode sbn = ssn.getSwitchBody();
-    for (int i = 0; i < sbn.size(); i++) {
-      SwitchBlockNode node = (SwitchBlockNode) sbn.get(i);
-      assignUniqueIDBlockNode(md, nametable, node.getSwitchBlockStatement());
+  private void analyzeSwitchStatementNode(MethodDescriptor md, SymbolTable nametable,
+      SwitchStatementNode bsn) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeSubBlockNode(MethodDescriptor md, SymbolTable nametable, SubBlockNode bsn) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeReturnNode(MethodDescriptor md, SymbolTable nametable, ReturnNode bsn) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode bsn) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeIfStatementNode(MethodDescriptor md, SymbolTable nametable,
+      IfStatementNode bsn) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private NTuple<Descriptor> analyzeFlowDeclarationNode(MethodDescriptor md, SymbolTable nametable,
+      DeclarationNode dn, NTuple<Descriptor> base) {
+
+    VarDescriptor vd = dn.getVarDescriptor();
+    base.add(vd);
+    getFlowGraph(md).createNewFlowNode(base);
+
+    if (dn.getExpression() != null) {
+
+      NTuple<Descriptor> rhsDescTuple =
+          analyzeFlowExpressionNode(md, nametable, dn.getExpression(), new NTuple<Descriptor>());
+
+      // add a new flow edge from rhs to lhs
+      if (rhsDescTuple != null) { // rhs is null when values come from the top
+                                  // location
+        getFlowGraph(md).addValueFlowEdge(rhsDescTuple, base);
+      }
+
     }
+
+    return null;
+
   }
 
-  private void assignUniqueIDSubBlockNode(MethodDescriptor md, SymbolTable nametable,
-      SubBlockNode sbn) {
-    assignUniqueIDBlockNode(md, nametable, sbn.getBlockNode());
+  private void analyzeBlockExpressionNode(MethodDescriptor md, SymbolTable nametable,
+      BlockExpressionNode ben) {
+    analyzeFlowExpressionNode(md, nametable, ben.getExpression(), null);
   }
 
-  private void assignUniqueIDLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln) {
+  private NTuple<Descriptor> analyzeFlowExpressionNode(MethodDescriptor md, SymbolTable nametable,
+      ExpressionNode en, NTuple<Descriptor> base) {
 
-    if (ln.getType() == LoopNode.WHILELOOP || ln.getType() == LoopNode.DOWHILELOOP) {
-      assignUniqueIDBlockNode(md, nametable, ln.getBody());
-    } else {
-      // check 'for loop' case
-      BlockNode bn = ln.getInitializer();
-      bn.getVarTable().setParent(nametable);
-      assignUniqueIDBlockNode(md, bn.getVarTable(), ln.getUpdate());
-      assignUniqueIDBlockNode(md, bn.getVarTable(), ln.getBody());
+    switch (en.kind()) {
+
+    case Kind.AssignmentNode:
+      analyzeFlowAssignmentNode(md, nametable, (AssignmentNode) en, base);
+      break;
+
+    case Kind.FieldAccessNode:
+      analyzeFieldAccessNode(md, nametable, (FieldAccessNode) en);
+      break;
+
+    case Kind.NameNode:
+      return analyzeFlowNameNode(md, nametable, (NameNode) en, base);
+
+    case Kind.OpNode:
+      // return analyzeOpNode(md, nametable, (OpNode) en, new
+      // HashSet<FlowNode>());
+      break;
+
+    case Kind.CreateObjectNode:
+      analyzeCreateObjectNode(md, nametable, (CreateObjectNode) en);
+      break;
+
+    case Kind.ArrayAccessNode:
+      analyzeArrayAccessNode(md, nametable, (ArrayAccessNode) en);
+      break;
+
+    case Kind.LiteralNode:
+      analyzeLiteralNode(md, nametable, (LiteralNode) en);
+      break;
+
+    case Kind.MethodInvokeNode:
+      analyzeMethodInvokeNode(md, nametable, (MethodInvokeNode) en);
+      break;
+
+    case Kind.TertiaryNode:
+      analyzeTertiaryNode(md, nametable, (TertiaryNode) en);
+      break;
+
+    case Kind.CastNode:
+      analyzeCastNode(md, nametable, (CastNode) en);
+      break;
+
+    // case Kind.InstanceOfNode:
+    // checkInstanceOfNode(md, nametable, (InstanceOfNode) en, td);
+    // return null;
+
+    // case Kind.ArrayInitializerNode:
+    // checkArrayInitializerNode(md, nametable, (ArrayInitializerNode) en,
+    // td);
+    // return null;
+
+    // case Kind.ClassTypeNode:
+    // checkClassTypeNode(md, nametable, (ClassTypeNode) en, td);
+    // return null;
+
+    // case Kind.OffsetNode:
+    // checkOffsetNode(md, nametable, (OffsetNode)en, td);
+    // return null;
+
+    }
+    return null;
+
+  }
+
+  private void analyzeCastNode(MethodDescriptor md, SymbolTable nametable, CastNode en) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeTertiaryNode(MethodDescriptor md, SymbolTable nametable, TertiaryNode en) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeMethodInvokeNode(MethodDescriptor md, SymbolTable nametable,
+      MethodInvokeNode en) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeLiteralNode(MethodDescriptor md, SymbolTable nametable, LiteralNode en) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeArrayAccessNode(MethodDescriptor md, SymbolTable nametable, ArrayAccessNode en) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private void analyzeCreateObjectNode(MethodDescriptor md, SymbolTable nametable,
+      CreateObjectNode en) {
+    // TODO Auto-generated method stub
+
+  }
+
+  private Set<FlowNode> analyzeOpNode(MethodDescriptor md, SymbolTable nametable, OpNode on,
+      Set<FlowNode> nodeSet) {
+
+    ClassDescriptor cd = md.getClassDesc();
+
+    // left operand
+    NTuple<Descriptor> leftOpTuple =
+        analyzeFlowExpressionNode(md, nametable, on.getLeft(), new NTuple<Descriptor>());
+
+    if (on.getRight() != null) {
+      // right operand
+      NTuple<Descriptor> rightOpTuple =
+          analyzeFlowExpressionNode(md, nametable, on.getRight(), new NTuple<Descriptor>());
     }
 
+    Operation op = on.getOp();
+
+    switch (op.getOp()) {
+
+    case Operation.UNARYPLUS:
+    case Operation.UNARYMINUS:
+    case Operation.LOGIC_NOT:
+      // single operand
+      // return leftLoc;
+
+    case Operation.LOGIC_OR:
+    case Operation.LOGIC_AND:
+    case Operation.COMP:
+    case Operation.BIT_OR:
+    case Operation.BIT_XOR:
+    case Operation.BIT_AND:
+    case Operation.ISAVAILABLE:
+    case Operation.EQUAL:
+    case Operation.NOTEQUAL:
+    case Operation.LT:
+    case Operation.GT:
+    case Operation.LTE:
+    case Operation.GTE:
+    case Operation.ADD:
+    case Operation.SUB:
+    case Operation.MULT:
+    case Operation.DIV:
+    case Operation.MOD:
+    case Operation.LEFTSHIFT:
+    case Operation.RIGHTSHIFT:
+    case Operation.URIGHTSHIFT:
+
+      Set<CompositeLocation> inputSet = new HashSet<CompositeLocation>();
+      // inputSet.add(leftLoc);
+      // inputSet.add(rightLoc);
+      // CompositeLocation glbCompLoc =
+      // CompositeLattice.calculateGLB(inputSet, generateErrorMessage(cd, on));
+      // return glbCompLoc;
+
+    default:
+      throw new Error(op.toString());
+    }
   }
 
-  private void assignUniqueIDIfStatementNode(MethodDescriptor md, SymbolTable nametable,
-      IfStatementNode isn) {
+  private NTuple<Descriptor> analyzeFlowNameNode(MethodDescriptor md, SymbolTable nametable,
+      NameNode nn, NTuple<Descriptor> base) {
 
-    assignUniqueIDBlockNode(md, nametable, isn.getTrueBlock());
+    NameDescriptor nd = nn.getName();
+    if (nd.getBase() != null) {
+      analyzeFlowExpressionNode(md, nametable, nn.getExpression(), base);
+    } else {
+      String varname = nd.toString();
+      if (varname.equals("this")) {
+        // 'this' itself!
+        base.add(md.getThis());
+        return base;
+      }
+
+      Descriptor d = (Descriptor) nametable.get(varname);
+
+      // CompositeLocation localLoc = null;
+      if (d instanceof VarDescriptor) {
+        VarDescriptor vd = (VarDescriptor) d;
+        // localLoc = d2loc.get(vd);
+        // the type of var descriptor has a composite location!
+        // loc = ((SSJavaType)
+        // vd.getType().getExtension()).getCompLoc().clone();
+        base.add(vd);
+      } else if (d instanceof FieldDescriptor) {
+        // the type of field descriptor has a location!
+        FieldDescriptor fd = (FieldDescriptor) d;
+        if (fd.isStatic()) {
+          if (fd.isFinal()) {
+            // if it is 'static final', the location has TOP since no one can
+            // change its value
+            // loc.addLocation(Location.createTopLocation(md));
+            // return loc;
+          } else {
+            // if 'static', the location has pre-assigned global loc
+            // MethodLattice<String> localLattice = ssjava.getMethodLattice(md);
+            // String globalLocId = localLattice.getGlobalLoc();
+            // if (globalLocId == null) {
+            // throw new
+            // Error("Global location element is not defined in the method " +
+            // md);
+            // }
+            // Location globalLoc = new Location(md, globalLocId);
+            //
+            // loc.addLocation(globalLoc);
+          }
+        } else {
+          // the location of field access starts from this, followed by field
+          // location
+          base.add(md.getThis());
+        }
 
-    if (isn.getFalseBlock() != null) {
-      assignUniqueIDBlockNode(md, nametable, isn.getFalseBlock());
+        // Location fieldLoc = (Location) fd.getType().getExtension();
+        // loc.addLocation(fieldLoc);
+        base.add(fd);
+      } else if (d == null) {
+        // access static field
+        // FieldDescriptor fd = nn.getField();
+        //
+        // MethodLattice<String> localLattice = ssjava.getMethodLattice(md);
+        // String globalLocId = localLattice.getGlobalLoc();
+        // if (globalLocId == null) {
+        // throw new
+        // Error("Method lattice does not define global variable location at "
+        // + generateErrorMessage(md.getClassDesc(), nn));
+        // }
+        // loc.addLocation(new Location(md, globalLocId));
+        //
+        // Location fieldLoc = (Location) fd.getType().getExtension();
+        // loc.addLocation(fieldLoc);
+        //
+        // return loc;
+
+      }
     }
 
+    getFlowGraph(md).createNewFlowNode(base);
+
+    return base;
+
   }
 
-  private void assignUniqueIDDeclarationNode(MethodDescriptor md, SymbolTable nametable,
-      DeclarationNode dn) {
+  private void analyzeFieldAccessNode(MethodDescriptor md, SymbolTable nametable, FieldAccessNode en) {
+    // TODO Auto-generated method stub
 
-    VarDescriptor vd = dn.getVarDescriptor();
-    graph.assignUniqueIDtoDescriptor(vd);
+  }
+
+  private void analyzeFlowAssignmentNode(MethodDescriptor md, SymbolTable nametable,
+      AssignmentNode an, NTuple<Descriptor> base) {
+
+    System.out.println("analyzeFlowAssignmentNode=" + an);
+
+    ClassDescriptor cd = md.getClassDesc();
+
+    boolean postinc = true;
+    if (an.getOperation().getBaseOp() == null
+        || (an.getOperation().getBaseOp().getOp() != Operation.POSTINC && an.getOperation()
+            .getBaseOp().getOp() != Operation.POSTDEC)) {
+      postinc = false;
+    }
+
+    // if LHS is array access node, need to capture value flows between an array
+    // and its index value
+    analyzeFlowExpressionNode(md, nametable, an.getDest(), base);
+    // NTuple<Descriptor> lhsDescTuple = analyzeFlowExpressionNode(md,
+    // nametable, an.getDest(), base);
+
+    if (!postinc) {
+      // analyze value flows of rhs expression
+      NTuple<Descriptor> rhsDescTuple =
+          analyzeFlowExpressionNode(md, nametable, an.getSrc(), new NTuple<Descriptor>());
+
+    } else {
+
+      // postinc case
+      // src & dest are same
+
+    }
+
+  }
+
+  public FlowGraph getFlowGraph(MethodDescriptor md) {
+    return mapMethodDescriptorToFlowGraph.get(md);
   }
 
 }