+ private void calculateReturnPCLocInheritance() {
+ calculateHighestPCLocInheritance();
+ calculateLowestReturnLocInheritance();
+ updateFlowGraphPCReturnLocInheritance();
+ }
+
+ private void updateFlowGraphPCReturnLocInheritance() {
+
+ Set<MethodDescriptor> keySet = mapHighestOverriddenMethodDescToMethodDescSet.keySet();
+ for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+ MethodDescriptor highestMethodDesc = (MethodDescriptor) iterator.next();
+
+ if (mapHighestOverriddenMethodDescToMethodDescSet.get(highestMethodDesc).size() == 1) {
+ continue;
+ }
+
+ Set<MethodDescriptor> methodDescSet =
+ mapHighestOverriddenMethodDescToMethodDescSet.get(highestMethodDesc);
+
+ NTuple<Descriptor> highestPCLocDescTuple =
+ mapHighestOverriddenMethodDescToPCLocTuple.get(highestMethodDesc);
+
+ NTuple<Descriptor> highestRETURNLocDescTuple =
+ mapHighestOverriddenMethodDescToReturnLocTuple.get(highestMethodDesc);
+
+ // System.out.println("\n$$$$$$$$$$$$$$$$updateFlowGraphPCReturnLocInheritance="
+ // + highestMethodDesc);
+ // System.out.println("-----highestPCLoc=" + highestPCLocDescTuple);
+ // System.out.println("-----highestRETURNLoc=" + highestRETURNLocDescTuple);
+
+ for (Iterator iterator2 = methodDescSet.iterator(); iterator2.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator2.next();
+ // System.out.println("\n --------MD=" + md);
+ FlowGraph flowGraph = getFlowGraph(md);
+
+ MethodSummary summary = getMethodSummary(md);
+ CompositeLocation curPCLoc = summary.getPCLoc();
+ NTuple<Descriptor> curPCDescTuple = translateToDescTuple(curPCLoc.getTuple());
+ // System.out.println("md=" + md + " curPCLoc=" + curPCLoc);
+ // System.out.println("highestPCLoc=" + highestPCLocDescTuple);
+
+ if (highestPCLocDescTuple == null) {
+ // this case: PCLOC is top
+ // System.out.println("###SET PCLOC AS TOP");
+ if (curPCDescTuple != null && !curPCLoc.get(0).isTop()) {
+ FlowNode pcFlowNode = flowGraph.getFlowNode(curPCDescTuple);
+ flowGraph.removeNode(pcFlowNode);
+ }
+ summary.setPCLoc(new CompositeLocation(new Location(md, Location.TOP)));
+ } else {
+ NTuple<Descriptor> newPCDescTuple = new NTuple<Descriptor>();
+ if (highestPCLocDescTuple.size() == 1) {
+ newPCDescTuple.add(highestPCLocDescTuple.get(0));
+ } else {
+ newPCDescTuple.add(md.getThis());
+ newPCDescTuple.add(highestPCLocDescTuple.get(1));
+ }
+ if (!curPCDescTuple.equals(newPCDescTuple)) {
+ FlowNode pcFlowNode = flowGraph.getFlowNode(curPCDescTuple);
+ flowGraph.updateTuple(pcFlowNode, newPCDescTuple);
+ // flowGraph.removeNode(pcFlowNode);
+ Set<NTuple<Descriptor>> descSetLowerThanPCLoc =
+ mapHighestOverriddenMethodDescToSetLowerThanPCLoc.get(highestMethodDesc);
+ for (Iterator iterator3 = descSetLowerThanPCLoc.iterator(); iterator3.hasNext();) {
+ NTuple<Descriptor> lowerNTuple = (NTuple<Descriptor>) iterator3.next();
+ flowGraph.addValueFlowEdge(newPCDescTuple, lowerNTuple);
+ }
+ CompositeLocation newPCCompLoc =
+ new CompositeLocation(translateToLocTuple(md, newPCDescTuple));
+ summary.setPCLoc(newPCCompLoc);
+ }
+
+ }
+
+ // update return loc
+ if (highestRETURNLocDescTuple != null) {
+ CompositeLocation curRETURNLoc = summary.getRETURNLoc();
+ NTuple<Descriptor> curReturnDescTuple = translateToDescTuple(curRETURNLoc.getTuple());
+
+ if (!curReturnDescTuple.equals(highestRETURNLocDescTuple)) {
+ // handle the case that RETURNLOC is started with 'this'...
+ NTuple<Descriptor> newRETURNLocDescTuple = new NTuple<Descriptor>();
+ if (highestRETURNLocDescTuple.size() == 1) {
+ newRETURNLocDescTuple.add(highestRETURNLocDescTuple.get(0));
+ } else {
+ newRETURNLocDescTuple.add(md.getThis());
+ newRETURNLocDescTuple.add(highestRETURNLocDescTuple.get(1));
+ }
+
+ FlowNode returnFlowNode = flowGraph.getFlowNode(curReturnDescTuple);
+ flowGraph.updateTuple(returnFlowNode, newRETURNLocDescTuple);
+
+ Set<NTuple<Descriptor>> descSetHigherThanRETURNLoc =
+ mapHighestOverriddenMethodDescToSetHigherThanRETURNLoc.get(highestMethodDesc);
+ for (Iterator iterator3 = descSetHigherThanRETURNLoc.iterator(); iterator3.hasNext();) {
+ NTuple<Descriptor> higherNTuple = (NTuple<Descriptor>) iterator3.next();
+ flowGraph.addValueFlowEdge(higherNTuple, newRETURNLocDescTuple);
+ }
+
+ CompositeLocation newRETURNLocCompLoc =
+ new CompositeLocation(translateToLocTuple(md, newRETURNLocDescTuple));
+ summary.setRETURNLoc(newRETURNLocCompLoc);
+ }
+ }
+ }
+ }
+ }
+
+ private void calculateHighestPCLocInheritance() {
+
+ Set<MethodDescriptor> keySet = mapHighestOverriddenMethodDescToMethodDescSet.keySet();
+
+ Map<MethodDescriptor, Integer> mapMethodDescToParamCount =
+ new HashMap<MethodDescriptor, Integer>();
+
+ next: for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+ MethodDescriptor highestMethodDesc = (MethodDescriptor) iterator.next();
+
+ NTuple<Descriptor> tempTuple = null;
+
+ if (getMethodSummary(highestMethodDesc).getPCLoc() != null) {
+
+ Set<MethodDescriptor> methodDescSet =
+ mapHighestOverriddenMethodDescToMethodDescSet.get(highestMethodDesc);
+
+ if (methodDescSet.size() > 1) {
+ // System.out.println("---method desc set=" + methodDescSet + " from=" +
+ // highestMethodDesc);
+ } else {
+ continue next;
+ }
+
+ for (Iterator iterator2 = methodDescSet.iterator(); iterator2.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator2.next();
+
+ FlowGraph flowGraph = getFlowGraph(md);
+ if (flowGraph == null) {
+ continue;
+ }
+ Set<FlowNode> paramNodeSet = flowGraph.getParamFlowNodeSet();
+ // System.out.println("###md=" + md + " paramNodeSet=" + paramNodeSet);
+
+ CompositeLocation pcLOC = getMethodSummary(md).getPCLoc();
+ // System.out.println("---pcLOC=" + pcLOC);
+
+ if (md.equals(highestMethodDesc)) {
+ mapHighestOverriddenMethodDescToPCLocTuple.put(highestMethodDesc,
+ translateToDescTuple(pcLOC.getTuple()));
+ }
+
+ if (!pcLOC.get(0).isTop()) {
+
+ FlowNode pcFlowNode = flowGraph.getFlowNode(translateToDescTuple(pcLOC.getTuple()));
+
+ int count = 0;
+ for (Iterator iterator3 = paramNodeSet.iterator(); iterator3.hasNext();) {
+ FlowNode paramNode = (FlowNode) iterator3.next();
+ if (flowGraph.getReachableSetFrom(pcFlowNode.getCurrentDescTuple().subList(0, 1))
+ .contains(paramNode)) {
+ count++;
+ }
+ }
+ mapMethodDescToParamCount.put(md, count);
+
+ } else {
+
+ // the PC location is top
+ // if one of pcloc among the method inheritance chain has the TOP,
+ // all methods in the same chain should have the TOP.
+ mapHighestOverriddenMethodDescToPCLocTuple.remove(highestMethodDesc);
+ // System.out.println("highest=" + highestMethodDesc + " HIGHEST PCLOC="
+ // + mapHighestOverriddenMethodDescToPCLocTuple.get(highestMethodDesc));
+
+ Set<NTuple<Descriptor>> descTupleSetLowerThanPC = new HashSet<NTuple<Descriptor>>();
+ for (Iterator iterator3 = paramNodeSet.iterator(); iterator3.hasNext();) {
+ FlowNode flowNode = (FlowNode) iterator3.next();
+ descTupleSetLowerThanPC.add(flowNode.getCurrentDescTuple());
+ }
+ mapHighestOverriddenMethodDescToSetLowerThanPCLoc.put(highestMethodDesc,
+ descTupleSetLowerThanPC);
+
+ continue next;
+ }
+ }
+
+ // identify which method in the inheritance chain has the highest PCLOC
+ // basically, finds a method that has the highest count or TOP location
+ int highestCount = -1;
+ MethodDescriptor methodDescHighestCount = null;
+ for (Iterator iterator2 = methodDescSet.iterator(); iterator2.hasNext();) {
+ MethodDescriptor methodDesc = (MethodDescriptor) iterator2.next();
+ if (mapMethodDescToParamCount.containsKey(methodDesc)) {
+ int curCount = mapMethodDescToParamCount.get(methodDesc).intValue();
+ if (highestCount < curCount) {
+ highestCount = curCount;
+ methodDescHighestCount = methodDesc;
+ }
+ }
+ }
+
+ if (methodDescHighestCount != null) {
+ FlowGraph flowGraph = getFlowGraph(methodDescHighestCount);
+ CompositeLocation pcLOC = getMethodSummary(methodDescHighestCount).getPCLoc();
+ FlowNode pcFlowNode = flowGraph.getFlowNode(translateToDescTuple(pcLOC.getTuple()));
+ Set<FlowNode> reachableSet =
+ flowGraph.getReachableSetFrom(pcFlowNode.getCurrentDescTuple().subList(0, 1));
+
+ Set<FlowNode> reachableParamNodeSet = new HashSet<FlowNode>();
+ for (Iterator iterator3 = reachableSet.iterator(); iterator3.hasNext();) {
+ FlowNode flowNode = (FlowNode) iterator3.next();
+ if (flowGraph.isParameter(flowNode.getCurrentDescTuple())) {
+ reachableParamNodeSet.add(flowNode);
+ }
+
+ }
+
+ Set<NTuple<Descriptor>> descTupleSetLowerThanPC = new HashSet<NTuple<Descriptor>>();
+ for (Iterator iterator2 = reachableParamNodeSet.iterator(); iterator2.hasNext();) {
+ FlowNode flowNode = (FlowNode) iterator2.next();
+ descTupleSetLowerThanPC.add(flowNode.getCurrentDescTuple());
+ }
+
+ // mapHighestOverriddenMethodDescToPCLocTuple.remove(highestMethodDesc);
+ mapHighestOverriddenMethodDescToSetLowerThanPCLoc.put(highestMethodDesc,
+ descTupleSetLowerThanPC);
+ }
+
+ }
+
+ // System.out.println("####################################");
+ // System.out.println(" highest=" + highestMethodDesc + " HIGHEST PCLOC="
+ // + mapHighestOverriddenMethodDescToPCLocTuple.get(highestMethodDesc));
+ // System.out.println(" setLowerThanPCLoc="
+ // + mapHighestOverriddenMethodDescToSetLowerThanPCLoc.get(highestMethodDesc));
+ }
+
+ }
+
+ private void calculateLowestReturnLocInheritance() {
+
+ Set<MethodDescriptor> keySet = mapHighestOverriddenMethodDescToMethodDescSet.keySet();
+
+ Map<MethodDescriptor, Integer> mapMethodDescToParamCount =
+ new HashMap<MethodDescriptor, Integer>();
+
+ next: for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+ MethodDescriptor highestMethodDesc = (MethodDescriptor) iterator.next();
+
+ Set<MethodDescriptor> methodDescSet =
+ mapHighestOverriddenMethodDescToMethodDescSet.get(highestMethodDesc);
+
+ if (methodDescSet.size() > 1 && getMethodSummary(highestMethodDesc).getRETURNLoc() != null) {
+ } else {
+ continue next;
+ }
+
+ for (Iterator iterator2 = methodDescSet.iterator(); iterator2.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator2.next();
+
+ FlowGraph flowGraph = getFlowGraph(md);
+ Set<FlowNode> paramNodeSet = flowGraph.getParamFlowNodeSet();
+
+ CompositeLocation returnLoc = getMethodSummary(md).getRETURNLoc();
+
+ FlowNode returnFlowNode = flowGraph.getFlowNode(translateToDescTuple(returnLoc.getTuple()));
+
+ int count = 0;
+ for (Iterator iterator3 = paramNodeSet.iterator(); iterator3.hasNext();) {
+ FlowNode paramNode = (FlowNode) iterator3.next();
+ if (flowGraph.getReachableSetFrom(paramNode.getCurrentDescTuple().subList(0, 1))
+ .contains(returnFlowNode)) {
+ count++;
+ }
+ }
+ mapMethodDescToParamCount.put(md, count);
+ // System.out.println("###returnLoc=" + returnLoc + " count higher=" + count);
+ }
+
+ // identify which method in the inheritance chain has the highest PCLOC
+ // basically, finds a method that has the highest count or TOP location
+ int highestCount = -1;
+ MethodDescriptor methodDescHighestCount = null;
+ for (Iterator iterator2 = methodDescSet.iterator(); iterator2.hasNext();) {
+ MethodDescriptor methodDesc = (MethodDescriptor) iterator2.next();
+ int curCount = mapMethodDescToParamCount.get(methodDesc).intValue();
+ if (highestCount < curCount) {
+ highestCount = curCount;
+ methodDescHighestCount = methodDesc;
+ }
+ }
+
+ if (methodDescHighestCount != null) {
+ FlowGraph flowGraph = getFlowGraph(methodDescHighestCount);
+ CompositeLocation returnLOC = getMethodSummary(methodDescHighestCount).getRETURNLoc();
+ NTuple<Descriptor> returnLocTuple = translateToDescTuple(returnLOC.getTuple());
+ FlowNode returnFlowNode = flowGraph.getFlowNode(returnLocTuple);
+
+ Set<FlowNode> curMethodParamNodeSet = flowGraph.getParamFlowNodeSet();
+ Set<NTuple<Descriptor>> descTupleSetHigherThanPC = new HashSet<NTuple<Descriptor>>();
+ for (Iterator iterator3 = curMethodParamNodeSet.iterator(); iterator3.hasNext();) {
+ FlowNode paramNode = (FlowNode) iterator3.next();
+ if (flowGraph.getReachableSetFrom(paramNode.getCurrentDescTuple().subList(0, 1))
+ .contains(returnFlowNode)) {
+ descTupleSetHigherThanPC.add(paramNode.getCurrentDescTuple());
+ }
+ }
+
+ mapHighestOverriddenMethodDescToReturnLocTuple.put(highestMethodDesc, returnLocTuple);
+ mapHighestOverriddenMethodDescToSetHigherThanRETURNLoc.put(highestMethodDesc,
+ descTupleSetHigherThanPC);
+
+ }
+
+ // System.out.println("####################################");
+ // System.out.println(" highest=" + highestMethodDesc + " LOWEST RETURNLOC="
+ // + mapHighestOverriddenMethodDescToReturnLocTuple.get(highestMethodDesc));
+ // System.out.println(" setHigherThanReturnLoc="
+ // + mapHighestOverriddenMethodDescToSetHigherThanRETURNLoc.get(highestMethodDesc));
+
+ }
+
+ }
+
+ private void addMapHighestMethodDescToMethodDesc(MethodDescriptor highest, MethodDescriptor md) {
+ if (!mapHighestOverriddenMethodDescToMethodDescSet.containsKey(highest)) {
+ mapHighestOverriddenMethodDescToMethodDescSet.put(highest, new HashSet<MethodDescriptor>());
+ }
+ mapHighestOverriddenMethodDescToMethodDescSet.get(highest).add(md);
+ }
+
+ private void DFSInheritanceTreeCalculatingHighestOverriddenMethod(ClassDescriptor cd) {
+
+ // ClassDescriptor cd = node.getData();
+
+ for (Iterator iterator = cd.getMethods(); iterator.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+ MethodDescriptor highestMethodDesc = getHighestOverriddenMethod(md.getClassDesc(), md);
+ mapMethodDescToHighestOverriddenMethodDesc.put(md, highestMethodDesc);
+ addMapHighestMethodDescToMethodDesc(highestMethodDesc, md);
+
+ }
+
+ // traverse children
+ Set<ClassDescriptor> children = getDirectSubClasses(cd);
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ ClassDescriptor child = (ClassDescriptor) iterator.next();
+ DFSInheritanceTreeCalculatingHighestOverriddenMethod(child);
+ }
+
+ }
+
+ private MethodDescriptor getHighestOverriddenMethod(ClassDescriptor curClassDesc,
+ MethodDescriptor curMethodDesc) {
+
+ // Node<ClassDescriptor> curNode = inheritanceTree.getTreeNode(curClassDesc);
+ // Node<ClassDescriptor> parentNode = curNode.getParent();
+ ClassDescriptor parentClassDesc = curClassDesc.getSuperDesc();
+
+ if (parentClassDesc != null) {
+ if (parentClassDesc.getMethodTable().contains(curMethodDesc.getSymbol())) {
+ Set<MethodDescriptor> methodDescSet =
+ parentClassDesc.getMethodTable().getSet(curMethodDesc.getSymbol());
+ for (Iterator iterator = methodDescSet.iterator(); iterator.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+ if (md.matches(curMethodDesc)) {
+ return getHighestOverriddenMethod(parentClassDesc, md);
+ }
+ }
+ }
+ // traverse to the parent!
+ return getHighestOverriddenMethod(parentClassDesc, curMethodDesc);
+ }
+ return curMethodDesc;
+ }
+
+ private void buildInheritanceTree() {
+
+ DFSInheritanceTreeCalculatingHighestOverriddenMethod(rootClassDescriptor);
+
+ }
+
+ private void addInheritanceConstraintsToHierarchyGraph() {
+
+ // DFS the inheritance tree and propagates nodes/edges of parent to child
+
+ // Node<ClassDescriptor> rootNode = inheritanceTree.getRootNode();
+ DFSInheritanceTree(rootClassDescriptor);
+
+ }
+
+ private void DFSInheritanceTree(ClassDescriptor parentClassDescriptor) {
+
+ // ClassDescriptor parentClassDescriptor = parentNode.getData();
+
+ Set<ClassDescriptor> children = getDirectSubClasses(parentClassDescriptor);
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ ClassDescriptor childClassDescriptor = (ClassDescriptor) iterator.next();
+
+ HierarchyGraph parentGraph = getHierarchyGraph(parentClassDescriptor);
+ HierarchyGraph childGraph = getHierarchyGraph(childClassDescriptor);
+
+ Set<HNode> parentNodeSet = parentGraph.getNodeSet();
+ for (Iterator iterator2 = parentNodeSet.iterator(); iterator2.hasNext();) {
+ HNode hNode = (HNode) iterator2.next();
+ childGraph.addNode(hNode);
+ }
+
+ // copies extra information from the parent hierarchy graph
+ Map<HNode, Set<HNode>> parentMergeNodeMap = parentGraph.getMapHNodetoMergeSet();
+ Map<HNode, Set<HNode>> childMergeNodeMap = childGraph.getMapHNodetoMergeSet();
+
+ Set<HNode> keySet = parentMergeNodeMap.keySet();
+ for (Iterator iterator2 = keySet.iterator(); iterator2.hasNext();) {
+ HNode parentKey = (HNode) iterator2.next();
+ if (!childMergeNodeMap.containsKey(parentKey)) {
+ childMergeNodeMap.put(parentKey, new HashSet<HNode>());
+ }
+ childMergeNodeMap.get(parentKey).addAll(parentMergeNodeMap.get(parentKey));
+ }
+
+ // copies nodes/edges from the parent class...
+ for (Iterator iterator2 = parentNodeSet.iterator(); iterator2.hasNext();) {
+ HNode parentHNode = (HNode) iterator2.next();
+
+ Set<HNode> parentIncomingHNode = parentGraph.getIncomingNodeSet(parentHNode);
+ Set<HNode> parentOutgoingHNode = parentGraph.getOutgoingNodeSet(parentHNode);
+
+ for (Iterator iterator3 = parentIncomingHNode.iterator(); iterator3.hasNext();) {
+ HNode inHNode = (HNode) iterator3.next();
+ childGraph.addEdge(inHNode.getDescriptor(), parentHNode.getDescriptor());
+ }
+
+ for (Iterator iterator3 = parentOutgoingHNode.iterator(); iterator3.hasNext();) {
+ HNode outHNode = (HNode) iterator3.next();
+ childGraph.addEdge(parentHNode.getDescriptor(), outHNode.getDescriptor());
+ }
+
+ }
+
+ // copies nodes/edges from parent methods to overridden methods
+
+ for (Iterator iterator3 = childClassDescriptor.getMethods(); iterator3.hasNext();) {
+ MethodDescriptor childMethodDescriptor = (MethodDescriptor) iterator3.next();
+
+ MethodDescriptor parentMethodDesc =
+ getParentMethodDesc(childMethodDescriptor.getClassDesc(), childMethodDescriptor);
+
+ if (parentMethodDesc != null) {
+
+ HierarchyGraph parentMethodGraph = getHierarchyGraph(parentMethodDesc);
+ HierarchyGraph childMethodGraph = getHierarchyGraph(childMethodDescriptor);
+
+ Set<HNode> parentMethodNodeSet = parentMethodGraph.getNodeSet();
+ for (Iterator iterator2 = parentMethodNodeSet.iterator(); iterator2.hasNext();) {
+ HNode hNode = (HNode) iterator2.next();
+ childMethodGraph.addNode(hNode);
+ }
+
+ // copies extra information from the parent hierarchy graph
+ Map<HNode, Set<HNode>> parentMethodMergeNodeMap =
+ parentMethodGraph.getMapHNodetoMergeSet();
+ Map<HNode, Set<HNode>> childMethodMergeNodeMap = childMethodGraph.getMapHNodetoMergeSet();
+
+ Set<HNode> methodKeySet = parentMethodMergeNodeMap.keySet();
+ for (Iterator iterator2 = methodKeySet.iterator(); iterator2.hasNext();) {
+ HNode parentKey = (HNode) iterator2.next();
+ if (!childMethodMergeNodeMap.containsKey(parentKey)) {
+ childMethodMergeNodeMap.put(parentKey, new HashSet<HNode>());
+ }
+ childMethodMergeNodeMap.get(parentKey).addAll(parentMethodMergeNodeMap.get(parentKey));
+ }
+
+ // copies nodes/edges from the parent method...
+ for (Iterator iterator2 = parentMethodGraph.getNodeSet().iterator(); iterator2.hasNext();) {
+ HNode parentHNode = (HNode) iterator2.next();
+
+ Set<HNode> parentIncomingHNode = parentMethodGraph.getIncomingNodeSet(parentHNode);
+ Set<HNode> parentOutgoingHNode = parentMethodGraph.getOutgoingNodeSet(parentHNode);
+
+ for (Iterator iterator4 = parentIncomingHNode.iterator(); iterator4.hasNext();) {
+ HNode inHNode = (HNode) iterator4.next();
+ childMethodGraph.addEdge(inHNode, parentHNode);
+ }
+
+ for (Iterator iterator4 = parentOutgoingHNode.iterator(); iterator4.hasNext();) {
+ HNode outHNode = (HNode) iterator4.next();
+ childMethodGraph.addEdge(parentHNode, outHNode);
+ }
+
+ }
+
+ }
+
+ }
+
+ DFSInheritanceTree(childClassDescriptor);
+ }
+
+ }
+
+ public MethodDescriptor getParentMethodDesc(ClassDescriptor classDesc, MethodDescriptor methodDesc) {
+
+ // Node<ClassDescriptor> childNode = inheritanceTree.getTreeNode(classDesc);
+ ClassDescriptor parentClassDesc = classDesc.getSuperDesc();
+ // Node<ClassDescriptor> parentNode = childNode.getParent();
+
+ if (parentClassDesc != null) {
+ // ClassDescriptor parentClassDesc = parentNode.getData();
+ if (parentClassDesc.getMethodTable().contains(methodDesc.getSymbol())) {
+ Set<MethodDescriptor> methodDescSet =
+ parentClassDesc.getMethodTable().getSet(methodDesc.getSymbol());
+ for (Iterator iterator = methodDescSet.iterator(); iterator.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+ if (md.matches(methodDesc)) {
+ return md;
+ }
+ }
+ }
+
+ // traverse to the parent!
+ getParentMethodDesc(parentClassDesc, methodDesc);
+
+ }
+
+ return null;
+ }
+
+ private void checkReturnNodes() {
+ LinkedList<MethodDescriptor> methodDescList =
+ (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
+
+ while (!methodDescList.isEmpty()) {
+ MethodDescriptor md = methodDescList.removeLast();
+
+ if (md.getReturnType() != null && !md.getReturnType().isVoid()) {
+ checkFlowNodeReturnThisField(md);
+ }
+ // // in this case, this method will return the composite location that starts with 'this'
+ // FlowGraph flowGraph = getFlowGraph(md);
+ // Set<FlowNode> returnNodeSet = flowGraph.getReturnNodeSet();
+ // }
+
+ }
+
+ }
+
+ private void addSuperClasses(ClassDescriptor cd) {
+ ClassDescriptor parentClassDesc = cd.getSuperDesc();
+ if (parentClassDesc != null) {
+ toanalyze_classDescSet.add(parentClassDesc);
+ addSuperClasses(parentClassDesc);
+ }
+ }
+
+ private void updateFlowGraph() {
+
+ LinkedList<MethodDescriptor> methodDescList =
+ (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
+
+ while (!methodDescList.isEmpty()) {
+ MethodDescriptor md = methodDescList.removeLast();
+ if (state.SSJAVADEBUG) {
+ System.out.println();
+ System.out.println("SSJAVA: Updating a flow graph: " + md);
+ propagateFlowsFromCalleesWithNoCompositeLocation(md);
+ }
+
+ Set<FlowNode> nodeSet = getFlowGraph(md).getNodeSet();
+ for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
+ FlowNode flowNode = (FlowNode) iterator.next();
+ NTuple<Descriptor> descTuple = flowNode.getCurrentDescTuple();
+ NTuple<Location> locTuple = translateToLocTuple(md, descTuple);
+ for (int i = 0; i < locTuple.size(); i++) {
+ Location loc = locTuple.get(i);
+ if (loc.getDescriptor() instanceof ClassDescriptor) {
+ ClassDescriptor classDesc = (ClassDescriptor) loc.getDescriptor();
+ toanalyze_classDescSet.add(classDesc);
+ addSuperClasses(classDesc);
+ } else if (loc.getDescriptor() instanceof MethodDescriptor) {
+ toanalyze_classDescSet.add(((MethodDescriptor) loc.getDescriptor()).getClassDesc());
+ }
+ }
+
+ }
+
+ }
+ }
+