Merge pull request #70 from nitta-lab/constractor_invocation_bug
>Fixed an animation bug related to CONSTRACTOR_INVOCATION.

I've confirmed all test cases.
commit 8941543b72a79e8241bcb09e9808f4d2759c679d
2 parents d522196 + cbd119b
Naoya Nitta authored on 23 Sep 2021
Showing 16 changed files
View
72
magnetFiles/en/Eclipse.magnet 0 → 100644
{
"trace": "..\\..\\traces\\Eclipse.trace",
"format": "PlainText",
"features": [
{
"feature": "Eclipse (Debug)",
"extracts": [
{
"src": {
"class": "public void org.eclipse.jdt.internal.debug.core.EventDispatcher.run(",
"id": "629542817"
},
"dst": {
"class": "org.eclipse.jdi.internal.event.EventSetImpl",
"id": "1400795012"
},
"type": "This-Another",
"order": "0"
},
{
"src": {
"class": "public boolean org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint.handleBreakpointEvent(",
"id": "666051245"
},
"dst": {
"class": "org.eclipse.jdi.internal.event.BreakpointEventImpl",
"id": "907205473"
},
"type": "This-Another",
"order": "0",
"connect": true
},
{
"src": {
"class": "org.eclipse.jdi.internal.event.EventIteratorImpl",
"id": "239180057"
},
"dst": {
"class": "java.util.ArrayList$ListItr",
"id": "316502076"
},
"type": "Container-Component",
"order": "0"
},
{
"src": {
"class": "java.util.ArrayList",
"id": "1121573201"
},
"dst": {
"class": "org.eclipse.jdi.internal.event.BreakpointEventImpl",
"id": "907205473"
},
"type": "Container-Component(Collection)",
"order": "0"
},
{
"src": {
"class": "public com.sun.jdi.event.EventSet org.eclipse.jdi.internal.event.EventQueueImpl.remove(",
"id": null
},
"dst": {
"class": "org.eclipse.jdi.internal.jdwp.JdwpCommandPacket",
"id": "859038530"
},
"type": "This-Another",
"order": "0"
}
]
}
]
}
View
72
magnetFiles/ja/Eclipse.magnet 0 → 100644
{
"trace": "..\\..\\traces\\Eclipse.trace",
"format": "PlainText",
"features": [
{
"feature": "Eclipseデバッグ機能",
"extracts": [
{
"src": {
"class": "public void org.eclipse.jdt.internal.debug.core.EventDispatcher.run(",
"id": "629542817"
},
"dst": {
"class": "org.eclipse.jdi.internal.event.EventSetImpl",
"id": "1400795012"
},
"type": "This-Another",
"order": "0"
},
{
"src": {
"class": "public boolean org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint.handleBreakpointEvent(",
"id": "666051245"
},
"dst": {
"class": "org.eclipse.jdi.internal.event.BreakpointEventImpl",
"id": "907205473"
},
"type": "This-Another",
"order": "0",
"connect": true
},
{
"src": {
"class": "org.eclipse.jdi.internal.event.EventIteratorImpl",
"id": "239180057"
},
"dst": {
"class": "java.util.ArrayList$ListItr",
"id": "316502076"
},
"type": "Container-Component",
"order": "0"
},
{
"src": {
"class": "java.util.ArrayList",
"id": "1121573201"
},
"dst": {
"class": "org.eclipse.jdi.internal.event.BreakpointEventImpl",
"id": "907205473"
},
"type": "Container-Component(Collection)",
"order": "0"
},
{
"src": {
"class": "public com.sun.jdi.event.EventSet org.eclipse.jdi.internal.event.EventQueueImpl.remove(",
"id": null
},
"dst": {
"class": "org.eclipse.jdi.internal.jdwp.JdwpCommandPacket",
"id": "859038530"
},
"type": "This-Another",
"order": "0"
}
]
}
]
}
View
2
■■■
src/org/ntlab/deltaExtractor/Alias.java
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
if (!(obj instanceof Alias))
return false;
Alias other = (Alias) obj;
if (aliasType != other.aliasType)
return false;
View
1
■■■■
src/org/ntlab/deltaViewer/CollaborationAliasCollector.java
import org.ntlab.deltaExtractor.Alias;
import org.ntlab.deltaExtractor.IAliasCollector;
import org.ntlab.featureExtractor.Extract;
import org.ntlab.trace.MethodExecution;
import org.ntlab.trace.TracePoint;
 
/**
* CollaborationAliasCollector is IAliasCollector implementation class to merge aliasList in time stamp order.
*
View
6
src/org/ntlab/deltaViewer/MagnetRONFrame.java
// Test code (will be deleted)
private static final String TAG = MagnetRONFrame.class.getSimpleName();
 
private static Dimension DEFAULT_FRAME_SIZE = new Dimension(1300, 700);
private static Dimension DEFAULT_FRAME_SIZE = new Dimension(1300, 600);
private static String FRAME_TITLE = "MagnetRON Viewer ";
 
private Trace trace = null;
private DeltaExtractor s = null;
super(FRAME_TITLE);
setSize(DEFAULT_FRAME_SIZE);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setExtendedState(JFrame.MAXIMIZED_BOTH);
this.viewer = new CollaborationViewer();
getContentPane().add(viewer, BorderLayout.CENTER);
menuBar = new MagnetRONMenuBar(this);
objectCallGraph = extracted.getKey();
aliasCollector = extracted.getValue();
fFeatureChanged = true;
animationThread = null;
if (objectCallGraph != null && aliasCollector != null) {
viewer.init(objectCallGraph, aliasCollector, new CollaborationLayout());
viewer.initAnimation();
}
viewer.stepToAnimation(i);
}
}
animationThread = null;
viewer.setAnimationSpeed(1.0);
}
};
animationThread.start();
} else {
public synchronized void stopAnimation() {
if (animationThread != null) {
animationThread.stop();
animationThread = null;
viewer.setAnimationSpeed(1.0);
}
}
 
public void startDeltaViewer(IObjectCallGraph ocg, IAliasCollector ac) {
View
243
src/org/ntlab/deltaViewer/MagnetRONViewer.java
 
// Test code (will be deleted)
private static final String TAG = MagnetRONViewer.class.getSimpleName();
protected static final Dimension DEFAULT_COMPONENT_SIZE = new Dimension(1300, 700);
protected static final Dimension DEFAULT_COMPONENT_SIZE = new Dimension(1300, 600);
 
protected static final Dimension DEFAULT_OBJECT_VERTEX_SIZE = new Dimension(70, 70);
protected static final Dimension DEFAULT_METHOD_EXECUTION_VERTEX_SIZE = new Dimension(55, 20);
 
protected DeltaGraphAdapter mxgraph;
protected mxICell defaultParent;
 
protected int curFrame = 0;
protected int prevFrame = 0;
protected int skipBackFrame = 0; // Use assigned value, when skip back animation.
protected double animationSpeed = DEFAULT_ANIMATION_SPEED;
protected static final double DEFAULT_ANIMATION_SPEED = 1.0;
public mxInteractiveCanvas createCanvas() {
return new CurvedCanvas(this);
}
};
mxgraphComponent.setPreferredSize(DEFAULT_COMPONENT_SIZE);
mxgraphComponent.setPreferredSize(DEFAULT_COMPONENT_SIZE);
this.setLayout(new BorderLayout());
this.add(mxgraphComponent, BorderLayout.CENTER);
this.threadPoolExecutor = new MagnetRONScheduledThreadPoolExecutor(2);
// Test code (will be deleted)
System.out.println("\r\n" + TAG + ": Frame=" + i + ", aliasType=" + alias.getAliasType().toString() + ", objectId=" + alias.getObjectId() + ", methodSignature=" + alias.getMethodSignature() + ", l." + alias.getLineNo());
switch(alias.getAliasType()) {
case RETURN_VALUE:
prevFrame = curFrame;
moveObjectVertex(alias);
update();
break;
case METHOD_INVOCATION:
prevFrame = curFrame;
removeMethodExecutionVertex(alias);
moveObjectVertex(alias);
update();
break;
case CONSTRACTOR_INVOCATION:
prevFrame = curFrame;
// TODO: Confirm the program behavior when called after RECEIVER.
if (!objectToVertexMap.containsKey(alias.getObjectId()) || objectToVertexMap.get(alias.getObjectId()).getCell() == null) {
MethodInvocation methodInv = (MethodInvocation) alias.getOccurrencePoint().getStatement();
String objId = alias.getObjectId();
if (!objectToVertexMap.containsKey(objId) || objectToVertexMap.get(objId).getCell() == null) {
createObjectVertexOnConstractor(alias);
}
if (!methodExecToVertexMap.containsKey(((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution())) {
createMethodExecutionVertex(alias.getObjectId(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCallerSideMethodName(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution());
if (!methodExecToVertexMap.containsKey(methodInv.getCalledMethodExecution())) {
createMethodExecutionVertex(objId, methodInv.getCallerSideMethodName(), methodInv.getCalledMethodExecution());
update();
}
removeMethodExecutionVertex(alias);
update();
break;
case FORMAL_PARAMETER:
prevFrame = curFrame;
moveObjectVertex(alias);
update();
break;
case ACTUAL_ARGUMENT:
prevFrame = curFrame;
moveObjectVertex(alias);
update();
break;
case THIS:
prevFrame = curFrame;
if (curFrame == 0 || alias.getObjectId().startsWith("0:")) {
createMethodExecutionVertex(alias);
update();
}
// Make {@code MethodExecutionVertex} of called method execution.
MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution();
if (calledMethodExec.isConstructor()
&& (!objectToVertexMap.containsKey(alias.getObjectId()) || objectToVertexMap.get(alias.getObjectId()).getCell() == null)) {
prevFrame = curFrame;
createObjectVertexOnConstractor(alias);
}
if (!methodExecToVertexMap.containsKey(calledMethodExec)) {
MethodExecution methodExec = alias.getMethodExecution();
&& methodExec.getSignature() != calledMethodExec.getSignature()
&& objectToVertexMap.containsKey(methodExec.getThisObjId())) {
createMethodExecutionVertex(methodExec.getThisObjId(), methodExec.getSignature(), methodExec);
}
prevFrame = curFrame;
createMethodExecutionVertex(alias.getObjectId(), calledMethodExec.getSignature(), calledMethodExec);
update();
}
break;
*/
private void removeMethodExecutionVertex(Alias alias) {
// source ObjectVertex
ObjectVertex srcObjVx = objectToVertexMap.get(alias.getObjectId());
AliasType aliasType = alias.getAliasType();
// Quick fix
if (aliasType == AliasType.CONSTRACTOR_INVOCATION) {
MethodInvocation methodInv = (MethodInvocation) alias.getOccurrencePoint().getStatement();
List<Statement> statements = methodInv.getCalledMethodExecution().getStatements();
if (!statements.isEmpty() && statements.get(0) instanceof MethodInvocation) {
MethodInvocation calledMethodInv = (MethodInvocation) statements.get(0);
if (!calledMethodInv.getCalledMethodExecution().getArguments().isEmpty()
&& objectToVertexMap.containsKey(calledMethodInv.getCalledMethodExecution().getArguments().get(0).getId())) {
srcObjVx = objectToVertexMap.get(calledMethodInv.getCalledMethodExecution().getArguments().get(0).getId());
}
}
}
MethodExecution methodExec = alias.getMethodExecution();
 
AliasType aliasType = alias.getAliasType();
if(aliasType.equals(AliasType.METHOD_INVOCATION) || aliasType.equals(AliasType.CONSTRACTOR_INVOCATION)) {
MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution();
List<ObjectVertex> arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments());
List<ObjectVertex> locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals());
* @param calledMethodExec: called method execution
*/
protected void removeCalledMethodExecutionVertex(ObjectVertex sourceObjectVertex, MethodExecution methodExecution, MethodExecution calledMethodExecution) {
MagnetRONAnimation.waitAnimationEnd();
 
// Remove ObjectVertex other than source ObjectVertex from locals and arguments of called MethodExecutionVertex.
if (methodExecToVertexMap.containsKey(calledMethodExecution)) {
MethodExecutionVertex calledMethodExecVx = methodExecToVertexMap.get(calledMethodExecution);
 
// TODO: Confirm bug.
List<ObjectVertex> arguments = new ArrayList<>(calledMethodExecVx.getArguments());
if (arguments.size() != 0) {
for (ObjectVertex objVx: arguments) {
if (objVx != sourceObjectVertex) {
mxICell objVxCell = (mxICell)objVx.getCell();
Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell);
// TODO: Confirm bug.
List<ObjectVertex> arguments = new ArrayList<>(calledMethodExecVx.getArguments());
if (arguments.size() != 0) {
for (ObjectVertex objVx: arguments) {
if (objVx != sourceObjectVertex) {
mxICell objVxCell = (mxICell)objVx.getCell();
Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell);
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
synchronized (mxgraph.getModel()) {
try {
if (!objVxCell.getParent().equals(getMxDefaultParent())) {
// If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
objVxCell.getParent().remove(objVxCell);
objVxCell.setParent(getMxDefaultParent());
}
} finally {
mxgraph.getModel().endUpdate();
}
}
if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
synchronized (mxgraph.getModel()) {
try {
if (!objVxCell.getParent().equals(getMxDefaultParent())) {
// If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
objVxCell.getParent().remove(objVxCell);
objVxCell.setParent(getMxDefaultParent());
}
objVxCell.getGeometry().setX(objVxCellAbsPt.getX());
objVxCell.getGeometry().setY(objVxCellAbsPt.getY());
} finally {
mxgraph.getModel().endUpdate();
}
}
if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
synchronized (mxgraph.getModel()) {
try {
objVxCell.getGeometry().setX(objVxCellAbsPt.getX());
objVxCell.getGeometry().setY(objVxCellAbsPt.getY());
} finally {
mxgraph.getModel().endUpdate();
}
MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent());
objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount());
objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis());
objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor);
objVxCellAnim.syncPlay();
}
methodExecToVertexMap.get(calledMethodExecution).getArguments().remove(objVx);
}
}
}
 
List<ObjectVertex> locals = new ArrayList<>(calledMethodExecVx.getLocals());
if (locals.size() != 0) {
for (ObjectVertex objVx: locals) {
if (objVx != sourceObjectVertex) {
mxICell objVxCell = (mxICell)objVx.getCell();
Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell);
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
synchronized (mxgraph.getModel()) {
try {
if (!objVxCell.getParent().equals(getMxDefaultParent())) {
// If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
objVxCell.getParent().remove(objVxCell);
objVxCell.setParent(getMxDefaultParent());
}
MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent());
objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount());
objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis());
objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor);
objVxCellAnim.syncPlay();
} finally {
mxgraph.getModel().endUpdate();
}
methodExecToVertexMap.get(calledMethodExecution).getArguments().remove(objVx);
}
}
}
List<ObjectVertex> locals = new ArrayList<>(calledMethodExecVx.getLocals());
if (locals.size() != 0) {
for (ObjectVertex objVx: locals) {
if (objVx != sourceObjectVertex) {
mxICell objVxCell = (mxICell)objVx.getCell();
Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell);
if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
synchronized (mxgraph.getModel()) {
try {
if (!objVxCell.getParent().equals(getMxDefaultParent())) {
// If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
objVxCell.getParent().remove(objVxCell);
objVxCell.setParent(getMxDefaultParent());
}
objVxCell.getGeometry().setX(objVxCellAbsPt.getX());
objVxCell.getGeometry().setY(objVxCellAbsPt.getY());
} finally {
mxgraph.getModel().endUpdate();
}
}
if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
synchronized (mxgraph.getModel()) {
try {
objVxCell.getGeometry().setX(objVxCellAbsPt.getX());
objVxCell.getGeometry().setY(objVxCellAbsPt.getY());
} finally {
mxgraph.getModel().endUpdate();
}
}
MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent());
objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount());
objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis());
objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor);
objVxCellAnim.syncPlay();
}
methodExecToVertexMap.get(calledMethodExecution).getLocals().remove(objVx);
MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent());
objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount());
objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis());
objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor);
objVxCellAnim.syncPlay();
}
methodExecToVertexMap.get(calledMethodExecution).getLocals().remove(objVx);
}
}
if (methodExecution == null) {
}
 
// Quick fix
if (methodExecution == null || !methodExecToVertexMap.get(calledMethodExecution).getArguments().isEmpty()) {
return;
}
 
mxICell srcMethodExecVxCell = (mxICell)methodExecToVertexMap.get(methodExecution).getCell();
mxICell dstMethodExecVxCell = (mxICell)calledMethodExecVx.getCell();
 
scrollCellsToVisible(srcMethodExecVxCell.getParent(), dstMethodExecVxCell.getParent());
 
try {
Point2D srcMethodExecVxCellAbsPt = null;
Point2D dstMethodExecVxCellAbsPt = null;
final mxICell[] cloneDstMethodExecVxCell = new mxICell[1];
} finally {
mxgraph.getModel().endUpdate();
}
}
 
// Animate an edge to shrink.
MagnetRONAnimation edgeCellAnim = new TranslateAnimation(mxgraph, getGraphComponent());
edgeCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount());
edgeCellAnim.setDelay(getMagnetRONAnimationDelayMillis());
}
}
});
edgeCellAnim.play();
 
if (!calledMethodExecution.isStatic()) {
objectToVertexMap.get(calledMethodExecution.getThisObjId()).getMethodExecutionVertices().remove(methodExecToVertexMap.get(calledMethodExecution));
} else {
// TODO: Confirm why is this object id of the caller method used?
MethodExecution dstMethodExec = methodExecList.get(i + 1);
String methodSig = srcMethodExec.getSignature();
if (!edgeMap.containsKey(methodSig)) {
MagnetRONAnimation.waitAnimationEnd();
 
// Draw an edge from sourceVertexCell to destinationVertexCell.
mxICell srcMethodExecVxCell = (mxICell)methodExecToVertexMap.get(srcMethodExec).getCell();
mxICell dstMethodExecVxCell = (mxICell)methodExecToVertexMap.get(dstMethodExec).getCell();
Point2D srcMethodExecVxCellAbsPt = getAbsolutePointforCell(srcMethodExecVxCell);
Point2D dstMethodExecVxCellAbsPt = getAbsolutePointforCell(dstMethodExecVxCell);
 
MagnetRONAnimation.waitAnimationEnd();
scrollCellsToVisible(srcMethodExecVxCell.getParent(), dstMethodExecVxCell.getParent(), 2);
try {
final mxICell[] cloneDstMethodExecVxCell = new mxICell[1];
this.skipBackFrame = numberFrame;
}
 
public void setAnimationSpeed(double animationSpeed) {
System.out.println(TAG + ": animationSpeed=" + animationSpeed);
this.animationSpeed = animationSpeed;
}
 
protected int getCurrentFrame() {
return this.curFrame;
}
 
protected int getPreviousFrame() {
return this.prevFrame;
}
 
public int getSkipBackFrame() {
return this.skipBackFrame;
View
traces/ArgoUML.magnet
View
traces/Eclipse.magnet 0 → 100644
View
traces/Eclipse.trace 0 → 100644
Not supported
View
traces/JHotDraw.magnet
View
traces/TinyProblemA1_B1_C1_D1.magnet
View
traces/TinyProblemA2_B2_C6_D6.magnet
View
traces/TinyProblemA3_B3_C5_D5.magnet
View
traces/TinyProblemA4_B4_C4_D4.magnet
View
traces/TinyProblemA5_B5_C3_D3.magnet
View
traces/TinyProblemA6_B6_C2_D2.magnet