+ private void assignCompositeLocation(FlowGraph globalFlowGraph) {
+ Set<FlowNode> nodeSet = globalFlowGraph.getNodeSet();
+
+ for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
+ FlowNode flowNode = (FlowNode) iterator.next();
+ Set<FlowNode> inNodeSet = globalFlowGraph.getIncomingFlowNodeSet(flowNode);
+ Set<FlowNode> reachableNodeSet = globalFlowGraph.getReachFlowNodeSetFrom(flowNode);
+
+ // System.out.println("flowNode=" + flowNode + " incoming=" + inNodeSet);
+ // System.out.println("reachableNodeSet=" + reachableNodeSet);
+
+ Map<NTuple<Location>, Set<NTuple<Descriptor>>> mapPrefixToIncomingLocTupleSet =
+ new HashMap<NTuple<Location>, Set<NTuple<Descriptor>>>();
+
+ List<NTuple<Descriptor>> prefixList = new ArrayList<NTuple<Descriptor>>();
+
+ for (Iterator iterator2 = inNodeSet.iterator(); iterator2.hasNext();) {
+ FlowNode inNode = (FlowNode) iterator2.next();
+
+ NTuple<Descriptor> inNodeTuple = inNode.getCurrentDescTuple();
+
+ // CompositeLocation inNodeInferredLoc =
+ // generateInferredCompositeLocation(methodInfo, inNodeTuple);
+ // NTuple<Location> inNodeInferredLocTuple = inNodeInferredLoc.getTuple();
+
+ for (int i = 1; i < inNodeTuple.size(); i++) {
+ NTuple<Descriptor> prefix = inNodeTuple.subList(0, i);
+ if (!prefixList.contains(prefix)) {
+ prefixList.add(prefix);
+ }
+ }
+ }
+
+ Collections.sort(prefixList, new Comparator<NTuple<Descriptor>>() {
+ public int compare(NTuple<Descriptor> arg0, NTuple<Descriptor> arg1) {
+ int s0 = arg0.size();
+ int s1 = arg1.size();
+ if (s0 > s1) {
+ return -1;
+ } else if (s0 == s1) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+ });
+
+ // find out reachable nodes that have the longest common prefix
+ for (int i = 0; i < prefixList.size(); i++) {
+ NTuple<Descriptor> curPrefix = prefixList.get(i);
+ Set<NTuple<Descriptor>> reachableCommonPrefixSet = new HashSet<NTuple<Descriptor>>();
+
+ for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
+ FlowNode reachableNode = (FlowNode) iterator2.next();
+ NTuple<Descriptor> reachLocTuple = reachableNode.getCurrentDescTuple();
+ if (reachLocTuple.startsWith(curPrefix)) {
+ reachableCommonPrefixSet.add(reachLocTuple);
+ }
+ }
+
+ if (!reachableCommonPrefixSet.isEmpty()) {
+ // found reachable nodes that start with the prefix curPrefix
+ // need to assign a composite location
+ // System.out.println("-prefixList=" + prefixList);
+ // System.out.println("-reachableCommonPrefixSet=" + reachableCommonPrefixSet);
+ // System.out.println("-curPrefix=" + curPrefix);
+
+ // first, check if there are more than one the set of locations that has
+ // the same length of the longest reachable prefix, no way to assign
+ // a composite location to the input local var
+ prefixSanityCheck(prefixList, i, globalFlowGraph, reachableNodeSet);
+
+ MethodDescriptor topMethodDesc = globalFlowGraph.getMethodDescriptor();
+ CompositeLocation newCompLoc = generateCompositeLocation(curPrefix, topMethodDesc);
+
+ System.out.println("SET COMPOSITE LOCATION=" + newCompLoc + " to " + flowNode);
+ flowNode.setCompositeLocation(newCompLoc);
+ }
+ }
+
+ }
+
+ }
+
+ private CompositeLocation generateCompositeLocation(NTuple<Descriptor> curPrefix,
+ MethodDescriptor md) {
+ CompositeLocation newCompLoc = new CompositeLocation();
+
+ Descriptor enclosingDesc = md;
+ for (int i = 0; i < curPrefix.size(); i++) {
+ Descriptor curDesc = curPrefix.get(i);
+ Location loc = new Location(enclosingDesc, curDesc.getSymbol());
+ newCompLoc.addLocation(loc);
+ if (i == 0) {
+ VarDescriptor varDesc = (VarDescriptor) curDesc;
+ enclosingDesc = varDesc.getType().getClassDesc();
+ } else {
+ FieldDescriptor fieldDesc = (FieldDescriptor) curDesc;
+ enclosingDesc = fieldDesc.getType().getClassDesc();
+ }
+ }
+
+ LocationDescriptor newLocDescriptor = generateNewLocationDescriptor();
+ newLocDescriptor.setEnclosingClassDesc((ClassDescriptor) enclosingDesc);
+
+ Location newLoc = new Location(enclosingDesc, newLocDescriptor.getSymbol());
+ newLoc.setLocDescriptor(newLocDescriptor);
+ newCompLoc.addLocation(newLoc);
+
+ return newCompLoc;
+ }
+
+ private void prefixSanityCheck(List<NTuple<Descriptor>> prefixList, int curIdx,
+ FlowGraph globalFlowGraph, Set<FlowNode> reachableNodeSet) {
+
+ NTuple<Descriptor> curPrefix = prefixList.get(curIdx);
+
+ for (int i = curIdx + 1; i < prefixList.size(); i++) {
+ NTuple<Descriptor> prefixTuple = prefixList.get(i);
+
+ if (curPrefix.startsWith(prefixTuple)) {
+ continue;
+ }
+
+ for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
+ FlowNode reachableNode = (FlowNode) iterator2.next();
+ NTuple<Descriptor> reachLocTuple = reachableNode.getCurrentDescTuple();
+ if (reachLocTuple.startsWith(prefixTuple)) {
+ throw new Error(
+ "Failed to generate a composite location because there is more than one prefix which is reach to the current node.");
+ }
+ }
+ }
+
+ }
+