- private boolean calculateCompositeLocation(FlowGraph flowGraph,
- SSJavaLattice<String> methodLattice, MethodLocationInfo methodInfo, FlowNode flowNode,
- FlowNode srcNode) throws CyclicFlowException {
-
- Descriptor localVarDesc = flowNode.getDescTuple().get(0);
- NTuple<Location> flowNodelocTuple = flowGraph.getLocationTuple(flowNode);
-
- if (localVarDesc.equals(methodInfo.getMethodDesc())) {
- return false;
- }
-
- Set<FlowNode> inNodeSet = flowGraph.getIncomingFlowNodeSet(flowNode);
- Set<FlowNode> reachableNodeSet = flowGraph.getReachFlowNodeSetFrom(flowNode);
-
- Map<NTuple<Location>, Set<NTuple<Location>>> mapPrefixToIncomingLocTupleSet =
- new HashMap<NTuple<Location>, Set<NTuple<Location>>>();
-
- List<NTuple<Location>> prefixList = new ArrayList<NTuple<Location>>();
-
- for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) {
- FlowNode inNode = (FlowNode) iterator.next();
- NTuple<Location> inNodeTuple = flowGraph.getLocationTuple(inNode);
-
- CompositeLocation inNodeInferredLoc =
- generateInferredCompositeLocation(methodInfo, inNodeTuple);
-
- NTuple<Location> inNodeInferredLocTuple = inNodeInferredLoc.getTuple();
-
- for (int i = 1; i < inNodeInferredLocTuple.size(); i++) {
- NTuple<Location> prefix = inNodeInferredLocTuple.subList(0, i);
- if (!prefixList.contains(prefix)) {
- prefixList.add(prefix);
- }
- addPrefixMapping(mapPrefixToIncomingLocTupleSet, prefix, inNodeInferredLocTuple);
- }
- }
-
- Collections.sort(prefixList, new Comparator<NTuple<Location>>() {
- public int compare(NTuple<Location> arg0, NTuple<Location> arg1) {
- int s0 = arg0.size();
- int s1 = arg1.size();
- if (s0 > s1) {
- return -1;
- } else if (s0 == s1) {
- return 0;
- } else {
- return 1;
- }
- }
- });
-
- // System.out.println("prefixList=" + prefixList);
- // System.out.println("reachableNodeSet=" + reachableNodeSet);
-
- // find out reachable nodes that have the longest common prefix
- for (int i = 0; i < prefixList.size(); i++) {
- NTuple<Location> curPrefix = prefixList.get(i);
- Set<NTuple<Location>> reachableCommonPrefixSet = new HashSet<NTuple<Location>>();
-
- for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
- FlowNode reachableNode = (FlowNode) iterator2.next();
- NTuple<Location> reachLocTuple = flowGraph.getLocationTuple(reachableNode);
- CompositeLocation reachLocInferLoc =
- generateInferredCompositeLocation(methodInfo, reachLocTuple);
- if (reachLocInferLoc.getTuple().startsWith(curPrefix)) {
- reachableCommonPrefixSet.add(reachLocTuple);
- }
- }
-
- if (!reachableCommonPrefixSet.isEmpty()) {
- // found reachable nodes that start with the prefix curPrefix
- // need to assign a composite location
-
- // 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, flowGraph, reachableNodeSet);
-
- Set<NTuple<Location>> incomingCommonPrefixSet =
- mapPrefixToIncomingLocTupleSet.get(curPrefix);
-
- int idx = curPrefix.size();
- NTuple<Location> element = incomingCommonPrefixSet.iterator().next();
- Descriptor desc = element.get(idx).getDescriptor();
-
- SSJavaLattice<String> lattice = getLattice(desc);
- LocationInfo locInfo = getLocationInfo(desc);
-
- CompositeLocation inferLocation =
- generateInferredCompositeLocation(methodInfo, flowNodelocTuple);
-
- // methodInfo.getInferLocation(localVarDesc);
- CompositeLocation newInferLocation = new CompositeLocation();
-
- if (inferLocation.getTuple().startsWith(curPrefix)) {
- // the same infer location is already existed. no need to do
- // anything
- System.out.println("NO ATTEMPT TO MAKE A COMPOSITE LOCATION curPrefix=" + curPrefix);
-
- // TODO: refactoring!
- if (srcNode != null) {
- CompositeLocation newLoc = new CompositeLocation();
- String newLocSymbol = "Loc" + (SSJavaLattice.seed++);
- for (int locIdx = 0; locIdx < curPrefix.size(); locIdx++) {
- newLoc.addLocation(curPrefix.get(locIdx));
- }
- Location newLocationElement = new Location(desc, newLocSymbol);
- newLoc.addLocation(newLocationElement);
-
- Descriptor srcLocalVar = srcNode.getDescTuple().get(0);
- methodInfo.mapDescriptorToLocation(srcLocalVar, newLoc.clone());
- addMapLocSymbolToInferredLocation(methodInfo.getMethodDesc(), srcLocalVar, newLoc);
- methodInfo.removeMaplocalVarToLocSet(srcLocalVar);
-
- // add the field/var descriptor to the set of the location symbol
- int lastIdx = srcNode.getLocTuple().size() - 1;
- Descriptor lastFlowNodeDesc = srcNode.getDescTuple().get(lastIdx);
- NTuple<Location> srcNodelocTuple = flowGraph.getLocationTuple(srcNode);
- Descriptor enclosinglastLastFlowNodeDesc = srcNodelocTuple.get(lastIdx).getDescriptor();
-
- CompositeLocation newlyInferredLocForFlowNode =
- generateInferredCompositeLocation(methodInfo, srcNodelocTuple);
- Location lastInferLocElement =
- newlyInferredLocForFlowNode.get(newlyInferredLocForFlowNode.getSize() - 1);
- Descriptor enclosingLastInferLocElement = lastInferLocElement.getDescriptor();
-
- // getLocationInfo(enclosingLastInferLocElement).addMapLocSymbolToDescSet(
- // lastInferLocElement.getLocIdentifier(), lastFlowNodeDesc);
- getLocationInfo(enclosingLastInferLocElement).addMapLocSymbolToRelatedInferLoc(
- lastInferLocElement.getLocIdentifier(), enclosinglastLastFlowNodeDesc,
- lastFlowNodeDesc);
-
- System.out.println("@@@@@@@ ASSIGN " + newLoc + " to SRC=" + srcNode);
- }
-
- return true;
- } else {
- // assign a new composite location
-
- // String oldMethodLocationSymbol =
- // inferLocation.get(0).getLocIdentifier();
- String newLocSymbol = "Loc" + (SSJavaLattice.seed++);
- for (int locIdx = 0; locIdx < curPrefix.size(); locIdx++) {
- newInferLocation.addLocation(curPrefix.get(locIdx));
- }
- Location newLocationElement = new Location(desc, newLocSymbol);
- newInferLocation.addLocation(newLocationElement);
-
- // maps local variable to location types of the common prefix
- methodInfo.mapDescriptorToLocation(localVarDesc, newInferLocation.clone());
-
- // methodInfo.mapDescriptorToLocation(localVarDesc, newInferLocation);
- addMapLocSymbolToInferredLocation(methodInfo.getMethodDesc(), localVarDesc,
- newInferLocation);
- methodInfo.removeMaplocalVarToLocSet(localVarDesc);
-
- // add the field/var descriptor to the set of the location symbol
- int lastIdx = flowNode.getLocTuple().size() - 1;
- Descriptor lastFlowNodeDesc = flowNode.getDescTuple().get(lastIdx);
- Descriptor enclosinglastLastFlowNodeDesc = flowNodelocTuple.get(lastIdx).getDescriptor();
-
- CompositeLocation newlyInferredLocForFlowNode =
- generateInferredCompositeLocation(methodInfo, flowNodelocTuple);
- Location lastInferLocElement =
- newlyInferredLocForFlowNode.get(newlyInferredLocForFlowNode.getSize() - 1);
- Descriptor enclosingLastInferLocElement = lastInferLocElement.getDescriptor();
-
- // getLocationInfo(enclosingLastInferLocElement).addMapLocSymbolToDescSet(
- // lastInferLocElement.getLocIdentifier(), lastFlowNodeDesc);
- getLocationInfo(enclosingLastInferLocElement).addMapLocSymbolToRelatedInferLoc(
- lastInferLocElement.getLocIdentifier(), enclosinglastLastFlowNodeDesc,
- lastFlowNodeDesc);
-
- // clean up the previous location
- // Location prevInferLocElement =
- // inferLocation.get(inferLocation.getSize() - 1);
- // Descriptor prevEnclosingDesc = prevInferLocElement.getDescriptor();
- //
- // SSJavaLattice<String> targetLattice;
- // LocationInfo targetInfo;
- // if (prevEnclosingDesc.equals(methodInfo.getMethodDesc())) {
- // targetLattice = methodLattice;
- // targetInfo = methodInfo;
- // } else {
- // targetLattice = getLattice(prevInferLocElement.getDescriptor());
- // targetInfo = getLocationInfo(prevInferLocElement.getDescriptor());
- // }
- //
- // Set<Pair<Descriptor, Descriptor>> associstedDescSet =
- // targetInfo.getRelatedInferLocSet(prevInferLocElement.getLocIdentifier());
- //
- // if (associstedDescSet.size() == 1) {
- // targetLattice.remove(prevInferLocElement.getLocIdentifier());
- // } else {
- // associstedDescSet.remove(lastFlowNodeDesc);
- // }
-
- }
-
- System.out.println("curPrefix=" + curPrefix);
- System.out.println("ASSIGN NEW COMPOSITE LOCATION =" + newInferLocation + " to "
- + flowNode);
-
- String newlyInsertedLocName =
- newInferLocation.get(newInferLocation.getSize() - 1).getLocIdentifier();
-
- System.out.println("-- add in-flow");
- for (Iterator iterator = incomingCommonPrefixSet.iterator(); iterator.hasNext();) {
- NTuple<Location> tuple = (NTuple<Location>) iterator.next();
- Location loc = tuple.get(idx);
- String higher = loc.getLocIdentifier();
- addRelationHigherToLower(lattice, locInfo, higher, newlyInsertedLocName);
- }
-
- System.out.println("-- add out flow");
- for (Iterator iterator = reachableCommonPrefixSet.iterator(); iterator.hasNext();) {
- NTuple<Location> tuple = (NTuple<Location>) iterator.next();
- if (tuple.size() > idx) {
- Location loc = tuple.get(idx);
- String lower = loc.getLocIdentifier();
- // String lower =
- // locInfo.getFieldInferLocation(loc.getLocDescriptor()).getLocIdentifier();
- addRelationHigherToLower(lattice, locInfo, newlyInsertedLocName, lower);
- }
- }
-
- return true;
- }
-
- }
-
- return false;
-
- }
-
- private void addMapLocSymbolToInferredLocation(MethodDescriptor md, Descriptor localVar,
- CompositeLocation inferLoc) {
-
- Location locElement = inferLoc.get((inferLoc.getSize() - 1));
- Descriptor enclosingDesc = locElement.getDescriptor();
- LocationInfo locInfo = getLocationInfo(enclosingDesc);
- locInfo.addMapLocSymbolToRelatedInferLoc(locElement.getLocIdentifier(), md, localVar);
- }
-
- private boolean isCompositeLocation(CompositeLocation cl) {
- return cl.getSize() > 1;
- }
-