diff --git a/src/org/ntlab/deltaViewer/CollaborationObjectCallGraph.java b/src/org/ntlab/deltaViewer/CollaborationObjectCallGraph.java index ed4bc60..ff118a1 100644 --- a/src/org/ntlab/deltaViewer/CollaborationObjectCallGraph.java +++ b/src/org/ntlab/deltaViewer/CollaborationObjectCallGraph.java @@ -5,12 +5,15 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; import org.ntlab.deltaExtractor.ExtractedStructure; import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; import org.ntlab.trace.Reference; +import org.ntlab.trace.Statement; import org.ntlab.trace.TracePoint; /** @@ -122,4 +125,149 @@ }).collect(Collectors.toList()); return sortedTpList; } + + public void shrinkAll(Map> newToOldMethodExecutionMap) { + List refs = getReferences(); + List collectionReferences = collectCollectionReferences(refs); + List> collectionChains = collectCollectionChains(collectionReferences); + refs = replaceCollectionChains(refs, collectionChains); + references = new HashSet<>(refs); // Convert to Set from List. + relatedPoints = replaceRelatedPoints(relatedPoints, newToOldMethodExecutionMap); + + // For debug. + System.out.println("collectionReferences: "); + for (Reference ref: collectionReferences) { + System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + "): " + ref.isCollection()); + } + System.out.println("collectionChains: "); + for (int i = 0; i < collectionChains.size(); i++) { + List CollectionChain = collectionChains.get(i); + System.out.println("i = " + i); + for (Reference ref: CollectionChain) { + System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + "): " + ref.isCollection()); + } + } + System.out.println("replaceCollectionChains: "); + for (Reference ref: references) { + System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + "): " + ref.isCollection()); + } + } + + private List collectCollectionReferences(List references) { + // Collect references that are Collection. + List collectionRefs = new ArrayList<>(); + for (Reference ref: references) { + if (ref.isCollection()) { + collectionRefs.add(ref); + } + } + return collectionRefs; + } + + private List> collectCollectionChains(List collectionReferences) { + // Collect follow references. + List collectionRefs = new ArrayList<>(collectionReferences); // Create new instance of coping collectionReference. + List> collectionChains = new ArrayList<>(); + // Search first reference. + int i = 0; + while (i < collectionRefs.size()) { + Reference ref = collectionRefs.get(i); + String srcClassName = ref.getSrcClassName(); + String srcObjId = ref.getSrcObjectId(); + boolean isFirstRef = true; + for (int j = 0; j < collectionReferences.size(); j++) { + if (collectionReferences.indexOf(ref) != j) { + Reference compareRef = collectionReferences.get(j); + if (srcClassName.equals(compareRef.getDstClassName()) + && srcObjId.equals(compareRef.getDstObjectId())) { + isFirstRef = false; + break; + } + } + } + if (isFirstRef) { + List collectionChain = new ArrayList<>(); + collectionChain.add(ref); + collectionChains.add(collectionChain); + collectionRefs.remove(i); + } else { + i++; + } + } + + // Search references follow first reference. + for (i = 0; i < collectionChains.size(); i++) { + List collectionChain = collectionChains.get(i); + int j = 0; + while (j < collectionChain.size()) { + Reference ref = collectionChain.get(j); + String dstClassName = ref.getDstClassName(); + String dstObjId = ref.getDstObjectId(); + j++; + for (int k = 0; k < collectionRefs.size(); k++) { + Reference compareRef = collectionRefs.get(k); + if (dstClassName.equals(compareRef.getSrcClassName()) + && dstObjId.equals(compareRef.getSrcObjectId())) { + collectionChain.add(compareRef); + collectionRefs.remove(k); + break; + } + } + } + if (collectionChain.size() == 1) { + collectionChains.remove(i); + i--; + } + } + return collectionChains; + } + + private List replaceCollectionChains(List references, List> collectionChains) { + // Replace to shrink Reference in references. + List replacedReferences = new ArrayList<>(references); + for (List collectionChain: collectionChains) { + // Create shrink new reference. + Reference firstRef = collectionChain.get(0); + Reference lastRef = collectionChain.get(collectionChain.size() - 1); + Reference newRef = new Reference(firstRef.getSrcObjectId(), lastRef.getDstObjectId(), firstRef.getSrcClassName(), lastRef.getDstClassName()); + newRef.setCollection(true); + + // Remove collectionChains from references. + for (int i = 0; i < collectionChain.size(); i++) { + Reference ref = collectionChain.get(i); + int refIdx = replacedReferences.indexOf(ref); // Get index of collection reference in references. + if (refIdx != - 1) replacedReferences.remove(refIdx); + else System.out.println("Failed to remove collection reference in references..."); + } + replacedReferences.add(newRef); // Add new reference. + } + return replacedReferences; + } + + /** + * Replace calledMethodExec in relatedPoints to newMethodExec. + * @param relatedPoints + * @param newToOldMethodExecutionMap + * @return Replaced related points. + */ + private List replaceRelatedPoints(List relatedPoints, Map> newToOldMethodExecutionMap) { + List replacedRp = new ArrayList<>(relatedPoints); + for (TracePoint rp: replacedRp) { + Statement st = rp.getStatement(); + if (st instanceof MethodInvocation) { + MethodInvocation methodInv = (MethodInvocation)st; + MethodExecution calledMethodExec = methodInv.getCalledMethodExecution(); + for (Entry> entry: newToOldMethodExecutionMap.entrySet()) { + MethodExecution newMethodExec = entry.getKey(); + Set oldMethodExecSet = entry.getValue(); + if (oldMethodExecSet.contains(calledMethodExec)) { + methodInv.setCalledMethodExecution(newMethodExec); + } + } + + } + } + return replacedRp; + } + } diff --git a/src/org/ntlab/deltaViewer/DeltaAliasCollector.java b/src/org/ntlab/deltaViewer/DeltaAliasCollector.java index ebad72e..ae05ff4 100644 --- a/src/org/ntlab/deltaViewer/DeltaAliasCollector.java +++ b/src/org/ntlab/deltaViewer/DeltaAliasCollector.java @@ -1,12 +1,19 @@ package org.ntlab.deltaViewer; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import org.ntlab.deltaExtractor.Alias; +import org.ntlab.deltaExtractor.Alias.AliasType; import org.ntlab.deltaExtractor.IAliasTracker; import org.ntlab.trace.MethodExecution; import org.ntlab.trace.MethodInvocation; +import org.ntlab.trace.Statement; +import org.ntlab.trace.TracePoint; /** * Collect delta alias for MagnetRON.(Derived from DeltaAliasTracker.) @@ -75,4 +82,244 @@ } + public Map> shrink() { + List oldAliasList = new ArrayList<>(aliasList); + List standardMethodInvocations = collectStandardMethodInvocations(aliasList); + List> invocationChains = collectInvocationChains(standardMethodInvocations); + aliasList = replaceInvocationChains(aliasList, invocationChains); + Map> newToOldMethodExecMap = collectNewToOldMethodExecutionMap(oldAliasList, aliasList); + + // for debug. + System.out.println("standardMethodInvocations: "); + for (Alias alias: standardMethodInvocations) { + System.out.println(alias.getAliasType() + ":: " + alias.getObjectId() + ": " + alias.getMethodSignature()); + } + System.out.println("invocationChains: "); + for (int i = 0; i < invocationChains.size(); i++) { + System.out.println("i = " + i); + for (Alias alias: invocationChains.get(i)) { + System.out.println("\t" + alias.getAliasType() + ":: " + alias.getObjectId() + ": " + alias.getMethodSignature()); + } + } + System.out.println("replaceInvocationChains: "); + for (Alias alias: aliasList) { + System.out.println(alias.getObjectId() + ": " + alias.getMethodSignature() + " l." + alias.getLineNo() + " :: " + alias.getAliasType().toString()); + } + return newToOldMethodExecMap; + } + + private List collectStandardMethodInvocations(List aliasList) { + List standardMethodInvocations = new ArrayList<>(); + List standardMethodInvsIdx = new ArrayList<>(); + // Collect 1 set of RECEIVER, THIS RETURN_VALUE, METHOD_INVOCATION and it is CollectionType. + for (int i = 0; i < aliasList.size(); i++) { + Alias alias = aliasList.get(i); + if (alias.getAliasType() == AliasType.RECEIVER) { + Statement st = alias.getOccurrencePoint().getStatement(); + MethodInvocation methodInvocation = (MethodInvocation)st; + if (methodInvocation.getCalledMethodExecution().isCollectionType()) { + if (standardMethodInvsIdx.size() != 0) standardMethodInvsIdx.clear(); + standardMethodInvsIdx.add(i); + } + } else if (alias.getAliasType() == AliasType.THIS) { + if (alias.getMethodExecution().isCollectionType() && standardMethodInvsIdx.size() == 1) { + standardMethodInvsIdx.add(i); + } + } else if (alias.getAliasType() == AliasType.RETURN_VALUE) { + if (alias.getMethodExecution().isCollectionType() && standardMethodInvsIdx.size() == 2) { + standardMethodInvsIdx.add(i); + } + } else if (alias.getAliasType() == AliasType.METHOD_INVOCATION) { + Statement st = alias.getOccurrencePoint().getStatement(); + MethodInvocation methodInvocation = (MethodInvocation)st; + if (methodInvocation.getCalledMethodExecution().isCollectionType() && standardMethodInvsIdx.size() == 3) { + standardMethodInvsIdx.add(i); + for (int index: standardMethodInvsIdx) { + standardMethodInvocations.add(aliasList.get(index)); + } + standardMethodInvsIdx.clear(); + } + } + } + return standardMethodInvocations; + } + + private List> collectInvocationChains(List standardMethodInvocations) { + List> invocationChains = new ArrayList<>(); + if (standardMethodInvocations.isEmpty()) return invocationChains; + List invChainsIdx = new ArrayList<>(); + // Compare whether same callerMethodExecution. + MethodExecution compareMethodExec = null; + for (int i = 0; i < standardMethodInvocations.size(); i++) { + Alias standardMethodInv = standardMethodInvocations.get(i); + MethodExecution methodExec = null; + if (standardMethodInv.getAliasType() == AliasType.RECEIVER && invChainsIdx.size() == 0) { + methodExec = standardMethodInv.getMethodExecution(); + } else if (standardMethodInv.getAliasType() == AliasType.THIS && invChainsIdx.size() == 1) { + methodExec = standardMethodInv.getMethodExecution().getCallerMethodExecution(); + } else if (standardMethodInv.getAliasType() == AliasType.RETURN_VALUE && invChainsIdx.size() == 2) { + methodExec = standardMethodInv.getMethodExecution().getCallerMethodExecution(); + } else if (standardMethodInv.getAliasType() == AliasType.METHOD_INVOCATION && invChainsIdx.size() == 3) { + methodExec = standardMethodInv.getMethodExecution(); + } else { + invChainsIdx.clear(); + continue; + } + + if (compareMethodExec == null) { + compareMethodExec = methodExec; + invocationChains.add(new ArrayList<>()); + } else { + if (compareMethodExec != methodExec) { + compareMethodExec = methodExec; + invocationChains.add(new ArrayList<>()); + } + } + invChainsIdx.add(i); + if (invChainsIdx.size() == 4) { + for (int index: invChainsIdx) { + invocationChains.get(invocationChains.size() - 1).add(standardMethodInvocations.get(index)); + } + invChainsIdx.clear(); + } + } + + // Compare whether same objectId from RETURN_VALUE to THIS. + int i = 0; + while (i < invocationChains.size()) { + List invChain = invocationChains.get(i); + if (invChain.size() > 4) { + int j = 2; + String compareObjId = null; + while (j < invChain.size() - (1 + 2)) { + Alias pRetauVal = invChain.get(j); + Alias pMethodInv = invChain.get(j + 1); + Alias nReceiver = invChain.get(j + 2); + Alias nThis = invChain.get(j + 3); + compareObjId = pRetauVal.getObjectId(); + if (compareObjId.equals(pMethodInv.getObjectId()) + && compareObjId.equals(nReceiver.getObjectId()) + && compareObjId.equals(nThis.getObjectId())) { + j += 4; + } else { + // Remove 1 set of from RECEIVER to METHOD_INVOCATION. + for (int k = i - 2; k < i + 2; k++) { + invChain.remove(k); + } + if (invChain.size() <= 4) { + invocationChains.remove(i); + i--; + } + } + } + i++; + } else { + invocationChains.remove(i); + } + } + return invocationChains; + } + + private List replaceInvocationChains(List aliasList, List> invocationChains) { + List replacedAliasList = new ArrayList<>(aliasList); + if (invocationChains.isEmpty()) return replacedAliasList; + for (List invChain: invocationChains) { + int firstIdx = replacedAliasList.indexOf(invChain.get(0)); // RECEIVER + int secondIdx = replacedAliasList.indexOf(invChain.get(1)); // THIS + int thirdIdx = replacedAliasList.indexOf(invChain.get(invChain.size() - 2)); // RETURN_VALUE + int lastIdx = replacedAliasList.indexOf(invChain.get(invChain.size() - 1)); // METHOD_INVOCATION + if(firstIdx != -1 && secondIdx != -1 && thirdIdx != -1 && lastIdx != -1) { + Alias receiverAlias = replacedAliasList.get(firstIdx); + Alias oldThisAlias = replacedAliasList.get(secondIdx); + Alias oldReturnValAlias = replacedAliasList.get(thirdIdx); + + // Collect signature chains. + StringBuilder sb = new StringBuilder(); + for (int i = 1; i < invChain.size(); i+=4) { + if (i == 1) { + sb.append(invChain.get(i).getMethodSignature()); + } else { + String[] splitMethodSig = invChain.get(i).getMethodSignature().split("\\."); + sb.append("."); + sb.append(splitMethodSig[splitMethodSig.length - 1]); + } + } + String signatureChains = sb.toString(); + String callerSideSignature = signatureChains; + String thisClassName = oldThisAlias.getMethodExecution().getThisClassName(); + long enterTime = oldThisAlias.getOccurrencePoint().getMethodExecution().getEntryTime(); + long exitTime = oldReturnValAlias.getOccurrencePoint().getMethodExecution().getExitTime(); + + // Create new alias for THIS. + String thisObjId = oldThisAlias.getObjectId(); + MethodExecution newCalledMethodExec = new MethodExecution(signatureChains, callerSideSignature, thisClassName, thisObjId, false, false, enterTime); + newCalledMethodExec.setCollectionType(true); + newCalledMethodExec.setExitTime(exitTime); + newCalledMethodExec.setReturnValue(oldReturnValAlias.getOccurrencePoint().getMethodExecution().getReturnValue()); + TracePoint newThisTp = new TracePoint(newCalledMethodExec, -1); + Alias newThisAlias = new Alias(AliasType.THIS, 0, thisObjId, newThisTp.duplicate()); + + // Change called method execution of RECEIVER alias. + // TODO Caution: The trace will be changed by the following code! + TracePoint receiverTp = receiverAlias.getOccurrencePoint(); + Statement st = receiverTp.getStatement(); + MethodInvocation methodInvocation = (MethodInvocation)st; + methodInvocation.setCalledMethodExecution(newCalledMethodExec); + newCalledMethodExec.setCaller(receiverTp.getMethodExecution(), receiverTp.getMethodExecution().getStatements().indexOf(st)); + + // Create new alias for RETURN_VALUE. + String returnValObjId = oldReturnValAlias.getObjectId(); + TracePoint newReturnValTp = new TracePoint(newCalledMethodExec, -1); + Alias newReturnValAlias = new Alias(AliasType.RETURN_VALUE, 0, returnValObjId, newReturnValTp.duplicate()); + + // Create new alias for METHOD_INVOCATION. + Alias newMethodInvAlias = new Alias(AliasType.METHOD_INVOCATION, 0, returnValObjId, receiverTp.duplicate()); + + /* Replace InvocationChains */ + // Remove invocationChains from aliasList. + for (int i = 1; i < invChain.size(); i++) { // Except first alias of THIS. + Alias invAlias = invChain.get(i); + int invAliasIdx = replacedAliasList.indexOf(invAlias); // Get index of invAlias in aliasList. + if (invAliasIdx != - 1) replacedAliasList.remove(invAliasIdx); + else System.out.println("Failed to remove invAlias in aliasList..."); + } + // Add new Alias for THIS and RETURN_VALUE, METHOD_INVOCATION. + replacedAliasList.add(secondIdx, newMethodInvAlias); + replacedAliasList.add(secondIdx, newReturnValAlias); + replacedAliasList.add(secondIdx, newThisAlias); + } else { + System.out.println("Failed to shrink aliasList..."); + } + } + return replacedAliasList; + } + + /** + * Collect methodExecutions for Alias that are not equal in oldAliasList and newAliasList. + * @param oldAliasList + * @param newAliasList + * @return One-to-many, Key is new methodExecution in newAliasList, Values are set of old methodExecutions in oldAlias replaced by newAlias. + */ + private Map> collectNewToOldMethodExecutionMap(List oldAliasList, List newAliasList) { + Map> newToOldMethodExecMap = new HashMap<>(); + int oldIdx = 0, newIdx = 0; + for (oldIdx = 0; oldIdx < oldAliasList.size(); oldIdx++) { + Alias oldAlias = oldAliasList.get(oldIdx); + Alias newAlias = newAliasList.get(newIdx); + if (oldAlias.equals(newAlias)) { + newIdx++; + } else { + MethodExecution oldMethodExec = oldAlias.getMethodExecution(); + MethodExecution newMethodExec = newAlias.getMethodExecution(); + if (!newToOldMethodExecMap.containsKey(newMethodExec)) { + newToOldMethodExecMap.put(newMethodExec, new HashSet<>()); + newToOldMethodExecMap.get(newMethodExec).add(oldMethodExec); + } else { + newToOldMethodExecMap.get(newMethodExec).add(oldMethodExec); + } + } + } + return newToOldMethodExecMap; + } + } diff --git a/src/org/ntlab/deltaViewer/MagnetRONFrame.java b/src/org/ntlab/deltaViewer/MagnetRONFrame.java index 185abdd..79d4a24 100644 --- a/src/org/ntlab/deltaViewer/MagnetRONFrame.java +++ b/src/org/ntlab/deltaViewer/MagnetRONFrame.java @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Map.Entry; import javax.swing.JFrame; @@ -137,10 +138,11 @@ } public Map.Entry extractMulti(List keys) { - CollaborationObjectCallGraph cocg = null; - CollaborationAliasCollector cac = null; trace = null; s = null; + CollaborationObjectCallGraph cocg = null; + CollaborationAliasCollector cac = null; + Map> newToOldMethodExecMap = new HashMap<>(); for(String key: keys) { int index = 0; @@ -164,12 +166,16 @@ } else { cocg.merge(extracted.getKey()); } + IAliasCollector ac = extracted.getValue(); + DeltaAliasCollector dac = (DeltaAliasCollector) ac; + newToOldMethodExecMap.putAll(dac.shrink()); if (cac == null) { - cac = new CollaborationAliasCollector(extracted.getValue()); + cac = new CollaborationAliasCollector(dac); } else { - cac.merge(extracted.getValue()); + cac.merge(dac); } } + cocg.shrinkAll(newToOldMethodExecMap); return new AbstractMap.SimpleEntry(cocg, cac); } @@ -435,7 +441,7 @@ @Override public void startAnimation() { - if (animationThread != null) { + if (animationThread == null) { animationThread = new Thread() { public void run() { // Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. diff --git a/src/org/ntlab/deltaViewer/MagnetRONViewer.java b/src/org/ntlab/deltaViewer/MagnetRONViewer.java index 0339170..f54d8b4 100644 --- a/src/org/ntlab/deltaViewer/MagnetRONViewer.java +++ b/src/org/ntlab/deltaViewer/MagnetRONViewer.java @@ -1123,17 +1123,20 @@ } protected String formatMethodSignature(String methodSignature, String thisClassName) { + // TODO Modify algorithm formatMethodSignature(). // Step1 : split "(" - String[] methodSignatures = methodSignature.split("\\("); - methodSignature = methodSignatures[0]; +// String[] methodSignatures = methodSignature.split("\\("); + methodSignature = methodSignature.substring(0, methodSignature.lastIndexOf('(')); // Step2 : split " " - methodSignatures = methodSignature.split(" "); + String[] methodSignatures = methodSignature.split(" "); String tmpMethodSignature = methodSignatures[methodSignatures.length-1]; - // Step2 : split "." + // Step3 : split "." String[] thisClassNames = thisClassName.split("\\."); methodSignatures = tmpMethodSignature.split("\\."); StringBuffer sb = new StringBuffer(); int i = methodSignatures.length - 2; + int count = methodSignature.split("\\(").length - 1; + if (count > 0) i -= count; if (i >= 0 && !thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i])) { if (thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i + 1])) i += 1; sb.append(methodSignatures[i]); diff --git a/src/tests/CollaborationAliasCollectorTest.java b/src/tests/CollaborationAliasCollectorTest.java index d81051c..df5c686 100644 --- a/src/tests/CollaborationAliasCollectorTest.java +++ b/src/tests/CollaborationAliasCollectorTest.java @@ -32,7 +32,7 @@ } } for (Alias alias: cac.getAliasList()) { - System.out.println(alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo() + " : " + alias.getAliasType().toString() + ", (" + alias.getMethodExecution().getEntryTime() + ", " + alias.getMethodExecution().getExitTime() + "), " + alias.getOccurrencePoint().getStatement().getTimeStamp() + ", " + alias.getTimeStamp()); + System.out.println(alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo() + " : " + alias.getAliasType().toString() + ", (" + alias.getMethodExecution().getEntryTime() + ", " + alias.getMethodExecution().getExitTime() + "), " + alias.getTimeStamp()); } assertNotNull(cac); for (IAliasCollector dac: dacList) { diff --git a/src/tests/CollaborationObjectCallGraphTest.java b/src/tests/CollaborationObjectCallGraphTest.java index 7883a36..6b1662a 100644 --- a/src/tests/CollaborationObjectCallGraphTest.java +++ b/src/tests/CollaborationObjectCallGraphTest.java @@ -3,13 +3,17 @@ import static org.junit.jupiter.api.Assertions.*; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.junit.jupiter.api.Test; import org.ntlab.deltaExtractor.ExtractedStructure; import org.ntlab.deltaExtractor.IAliasCollector; +import org.ntlab.deltaViewer.CollaborationAliasCollector; import org.ntlab.deltaViewer.CollaborationObjectCallGraph; +import org.ntlab.deltaViewer.DeltaAliasCollector; import org.ntlab.trace.FieldUpdate; import org.ntlab.trace.MethodExecution; import org.ntlab.trace.MethodInvocation; @@ -23,12 +27,28 @@ void testMerge() { // Change Here! // String key = "getterOverlap"; - String key = "setterOverlap"; +// String key = "setterOverlap"; + String key = "ArgoUMLDelete"; +// String key = "JHotDrawSelect"; MagnetRONFrameTest magnetRONFrame = new MagnetRONFrameTest(); Map extractedMultipleDeltas = magnetRONFrame.extractMultipleDeltas(key); List eList = new ArrayList<>(extractedMultipleDeltas.keySet()); List dacList = new ArrayList<>(extractedMultipleDeltas.values()); + CollaborationAliasCollector cac = null; + Map> newToOldMethodExecMap = new HashMap<>(); + for (IAliasCollector ac: dacList) { + if (ac instanceof DeltaAliasCollector) { + DeltaAliasCollector dac = (DeltaAliasCollector) ac; + newToOldMethodExecMap.putAll(dac.shrink()); + if (cac == null) { + cac = new CollaborationAliasCollector(dac); + } else { + cac.merge(dac); + } + } + } + CollaborationObjectCallGraph cocg = null; for (ExtractedStructure e: eList) { if (cocg == null) { @@ -39,7 +59,7 @@ } System.out.println("References:"); for (Reference ref: cocg.getReferences()) { - System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")"); + System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + "): " + ref.isCollection()); } System.out.println("StartPoints:"); for (MethodExecution methodExec: cocg.getStartPoints()) { @@ -88,8 +108,15 @@ // TODO Test StartPoint. assertTrue(cocg.getReferences().containsAll(e.getDelta().getSrcSide())); assertTrue(cocg.getReferences().containsAll(e.getDelta().getDstSide())); - assertTrue(cocg.getRelatedPoints().contains(e.getRelatedTracePoint())); - + assertTrue(cocg.getRelatedPoints().contains(e.getRelatedTracePoint())); + } + testShrinkAll(true, cocg, newToOldMethodExecMap); // Replaced References and RelatedPoints. + } + + @Test + private void testShrinkAll(boolean isShrink, CollaborationObjectCallGraph cocg, Map> newToOldMethodExecMap) { + if (isShrink) { + cocg.shrinkAll(newToOldMethodExecMap); } } } diff --git a/src/tests/DeltaAliasCollectorTest.java b/src/tests/DeltaAliasCollectorTest.java new file mode 100644 index 0000000..9ba5459 --- /dev/null +++ b/src/tests/DeltaAliasCollectorTest.java @@ -0,0 +1,33 @@ +package tests; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.ntlab.deltaExtractor.ExtractedStructure; +import org.ntlab.deltaExtractor.IAliasCollector; +import org.ntlab.deltaViewer.CollaborationAliasCollector; +import org.ntlab.deltaViewer.DeltaAliasCollector; + +class DeltaAliasCollectorTest { + + @Test + void testShrink() { + String key = "JHotDrawSelect"; + MagnetRONFrameTest magnetRONFrame = new MagnetRONFrameTest(); + Map extractedMultipleDeltas = magnetRONFrame.extractMultipleDeltas(key); + List eList = new ArrayList<>(extractedMultipleDeltas.keySet()); + List dacList = new ArrayList<>(extractedMultipleDeltas.values()); + CollaborationAliasCollector cac = null; + for (IAliasCollector dac: dacList) { + if (dac instanceof DeltaAliasCollector) { + DeltaAliasCollector deltaAliasCollector = (DeltaAliasCollector)dac; + deltaAliasCollector.shrink(); + assertNotNull(deltaAliasCollector); + } + } + } +} diff --git a/src/tests/MagnetRONFrameTest.java b/src/tests/MagnetRONFrameTest.java index 7dca3cc..916b156 100644 --- a/src/tests/MagnetRONFrameTest.java +++ b/src/tests/MagnetRONFrameTest.java @@ -176,7 +176,7 @@ // MagnetRON Experiment String[] ArgoUMLDelete1 = {null, null, "public void org.argouml.uml.diagram.ui.ActionRemoveFromDiagram.actionPerformed(", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", THIS_ANOTHER}; map.put("ArgoUMLDelete1", ArgoUMLDelete1);// ArgoUML �폜�@�\1 (this to another) String[] ArgoUMLDelete2 = {"450474599", "1675174935", "java.util.Vector", "org.argouml.uml.diagram.static_structure.ui.FigClass", "traces\\ArgoUMLBenchmarkWithMoreStandardClasses.trace", CONTAINER_COMPONENT_COLLECTION}; map.put("ArgoUMLDelete2", ArgoUMLDelete2); // ArgoUML �폜�@�\2 (collection) - + String[] JHotDrawSelect2 = {"1378082106", "1952912699", "java.util.HashSet", "org.jhotdraw.draw.RectangleFigure", "traces\\jHotDrawBenchmarkWithMoreStandardClasses.trace", CONTAINER_COMPONENT_COLLECTION}; map.put("JHotDrawSelect2", JHotDrawSelect2); // JHotDraw �I���@�\2 (collection) } private void setArgsKeysForMultipleDeltasExtract(Map> argsKeysMap, Map argsMap){ @@ -184,5 +184,6 @@ argsKeysMap.put("getterOverlap", new ArrayList(Arrays.asList("getterOverlap2", "getterOverlap1"))); argsKeysMap.put("setterOverlap", new ArrayList(Arrays.asList("setterOverlap1", "setterOverlap2"))); argsKeysMap.put("ArgoUMLDelete", new ArrayList(Arrays.asList("ArgoUMLDelete1", "ArgoUMLDelete2"))); + argsKeysMap.put("JHotDrawSelect", new ArrayList(Arrays.asList("JHotDrawSelect2"))); } }