diff --git a/org.ntlab.reverseDebugger/.settings/CVS/Entries b/org.ntlab.reverseDebugger/.settings/CVS/Entries
new file mode 100644
index 0000000..3f96714
--- /dev/null
+++ b/org.ntlab.reverseDebugger/.settings/CVS/Entries
@@ -0,0 +1 @@
+/org.eclipse.jdt.core.prefs/1.2/Wed Dec 9 07:18:21 2015//
diff --git a/org.ntlab.reverseDebugger/.settings/CVS/Repository b/org.ntlab.reverseDebugger/.settings/CVS/Repository
new file mode 100644
index 0000000..f9ae7d0
--- /dev/null
+++ b/org.ntlab.reverseDebugger/.settings/CVS/Repository
@@ -0,0 +1 @@
+org.ntlab.debuggingControl/.settings
diff --git a/org.ntlab.reverseDebugger/.settings/CVS/Root b/org.ntlab.reverseDebugger/.settings/CVS/Root
new file mode 100644
index 0000000..6041112
--- /dev/null
+++ b/org.ntlab.reverseDebugger/.settings/CVS/Root
@@ -0,0 +1 @@
+:pserver:n-nitta@nitta-lab-www.is.konan-u.ac.jp:\CVSProject
diff --git a/org.ntlab.reverseDebugger/META-INF/CVS/Entries b/org.ntlab.reverseDebugger/META-INF/CVS/Entries
new file mode 100644
index 0000000..8b3db2a
--- /dev/null
+++ b/org.ntlab.reverseDebugger/META-INF/CVS/Entries
@@ -0,0 +1 @@
+/MANIFEST.MF/1.1/Wed Dec 9 07:11:31 2015//
diff --git a/org.ntlab.reverseDebugger/META-INF/CVS/Repository b/org.ntlab.reverseDebugger/META-INF/CVS/Repository
new file mode 100644
index 0000000..0ad0de2
--- /dev/null
+++ b/org.ntlab.reverseDebugger/META-INF/CVS/Repository
@@ -0,0 +1 @@
+org.ntlab.debuggingControl/META-INF
diff --git a/org.ntlab.reverseDebugger/META-INF/CVS/Root b/org.ntlab.reverseDebugger/META-INF/CVS/Root
new file mode 100644
index 0000000..6041112
--- /dev/null
+++ b/org.ntlab.reverseDebugger/META-INF/CVS/Root
@@ -0,0 +1 @@
+:pserver:n-nitta@nitta-lab-www.is.konan-u.ac.jp:\CVSProject
diff --git a/org.ntlab.reverseDebugger/plugin.xml b/org.ntlab.reverseDebugger/plugin.xml
index c7729d6..124c048 100644
--- a/org.ntlab.reverseDebugger/plugin.xml
+++ b/org.ntlab.reverseDebugger/plugin.xml
@@ -15,5 +15,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java
index 5db785d..24d1471 100644
--- a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java
@@ -32,6 +32,7 @@
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
+import org.ntlab.reversedebugger.ObjectFlowAliases;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.BooleanValue;
@@ -60,7 +61,7 @@
import com.sun.jdi.VirtualMachine;
public class DebuggingControlAction implements IWorkbenchWindowActionDelegate {
-
+
@Override
public void run(IAction arg0) {
// TODO Auto-generated method stub
@@ -164,7 +165,7 @@
// printCallTreeDataFromRoot(vm, thread, threadInstance);
// �I�����C����͒���traceCollector��TraceJSON#getObjectFlow()���Ăяo�����̃R�[�h
- printObjectFlow(vm, thread, threadInstance);
+// printObjectFlow(vm, thread, threadInstance);
}
/**
@@ -218,34 +219,44 @@
int aliasNo = scanner.nextInt();
methodName = "get";
Value startAlias = callInstanceMethod(vm, thread, methodName, (ObjectReference)startAliasList, vm.mirrorOf(aliasNo));
- methodName = "toString";
- Value str = callInstanceMethod(vm, thread, methodName, (ObjectReference)startAlias);
- printValue("", "", str, true);
- methodName = "getObjectFlow";
- Value aliasLists = callStaticMethod(vm, thread, packageName, className, methodName, startAlias);
- System.out.println();
- // �擾�������X�g�̒��g�����[�v�ʼnȂ���m�F��, ���łɓ��Y�\�[�X�t�@�C����Ώ�Eclipse�ŊJ�����Ă݂�
- methodName = "size";
- int aliasListsSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasLists)).value();
- for (int i = 0; i < aliasListsSize; i++) {
- System.out.println("---------------------------------------------");
- System.out.println("���X�g" + i);
- methodName = "get";
- Value aliasList = callInstanceMethod(vm, thread, methodName,(ObjectReference)aliasLists, vm.mirrorOf(i));
- methodName = "size";
- int aliasListSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasList)).value();
- for (int j = 0; j < aliasListSize; j++) {
- methodName = "get";
- Value alias = callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasList, vm.mirrorOf(j));
- methodName = "toString";
- Value str2 = callInstanceMethod(vm, thread, methodName, (ObjectReference)alias);
- printValue("", "", str2, true);
- methodName = "getMethodExecution";
- Value aliasMethodExecution = callInstanceMethod(vm ,thread, methodName, (ObjectReference)alias);
- openSrcFileOfMethodExecution(vm, thread, aliasMethodExecution);
- }
- }
+// // DebuggingControl������GUI�֘A�̃N���X�̕��ɖ�����V�[�h�G�C���A�X��n���ăI�u�W�F�N�g�t���[�����s���Ă݂�
+// // �ꎞ�I�Ȃ��̂�, �ŏI�I�ɂ͂����ł�鏈���ł͂Ȃ��Ȃ�̂ŕs�v�ɂȂ�͂�
+// ObjectFlowAliases.getInstance().getObjectFlow(new MethodCaller(vm, thread, (ObjectReference)startAlias));
+
+ // �ȉ��͈ꎞ�I�ɃR�����g�A�E�g���Ă���
+// methodName = "toString";
+// Value str = callInstanceMethod(vm, thread, methodName, (ObjectReference)startAlias);
+// printValue("", "", str, true);
+// methodName = "getObjectFlow";
+// Value aliasLists = callStaticMethod(vm, thread, packageName, className, methodName, startAlias);
+// System.out.println();
+//
+// // �擾�������X�g�̒��g�����[�v�ʼnȂ���m�F��, ���łɓ��Y�\�[�X�t�@�C����Ώ�Eclipse�ŊJ�����Ă݂�
+// methodName = "size";
+// int aliasListsSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasLists)).value();
+// List> objectFlowAliasLists = new ArrayList<>();
+// for (int i = 0; i < aliasListsSize; i++) {
+// List objectFlowAliasList = new ArrayList<>();
+// objectFlowAliasLists.add(objectFlowAliasList);
+// System.out.println("---------------------------------------------");
+// System.out.println("���X�g" + i);
+// methodName = "get";
+// Value aliasList = callInstanceMethod(vm, thread, methodName,(ObjectReference)aliasLists, vm.mirrorOf(i));
+// methodName = "size";
+// int aliasListSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasList)).value();
+// for (int j = 0; j < aliasListSize; j++) {
+// methodName = "get";
+// Value alias = callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasList, vm.mirrorOf(j));
+// methodName = "toString";
+// Value str2 = callInstanceMethod(vm, thread, methodName, (ObjectReference)alias);
+// printValue("", "", str2, true);
+// methodName = "getMethodExecution";
+// Value aliasMethodExecution = callInstanceMethod(vm ,thread, methodName, (ObjectReference)alias);
+// openSrcFileOfMethodExecution(vm, thread, aliasMethodExecution);
+// objectFlowAliasList.add(new MethodCaller(vm, thread, (ObjectReference)alias));
+// }
+// }
}
/**
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java
new file mode 100644
index 0000000..8ed4e37
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/MethodCaller.java
@@ -0,0 +1,93 @@
+package org.ntlab.debuggingControl;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.ClassType;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.LongValue;
+import com.sun.jdi.Method;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+
+public class MethodCaller {
+ private VirtualMachine vm;
+ private ThreadReference thread;
+ private ObjectReference obj;
+
+ public MethodCaller(VirtualMachine vm, ThreadReference thread) {
+ this.vm = vm;
+ this.thread = thread;
+ }
+
+ public MethodCaller(VirtualMachine vm, ThreadReference thread, ObjectReference obj) {
+ this(vm, thread);
+ this.obj = obj;
+ }
+
+ public VirtualMachine getVm() {
+ return vm;
+ }
+
+ public ThreadReference getThread() {
+ return thread;
+ }
+
+ public ObjectReference getObj() {
+ return obj;
+ }
+
+ public long getThreadId() {
+ MethodCaller mc = new MethodCaller(vm, thread, thread);
+ try {
+ return ((LongValue)mc.callInstanceMethod("getId")).value();
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ throw new IllegalStateException();
+ }
+
+ public MethodCaller setObj(ObjectReference obj) {
+ this.obj = obj;
+ return this;
+ }
+
+ /**
+ * �p�b�P�[�W���ƃN���X���ƃ��\�b�h���ƈ������w�肵�Ă��̃N���X���\�b�h���Ăяo��
+ * @param packageName �Ăт����������\�b�h������N���X�̃p�b�P�[�W��
+ * @param className �Ăяo���������\�b�h������N���X��
+ * @param methodName �Ăяo���������\�b�h�� (static)
+ * @param args �Ăяo���������\�b�h�ɓn������(Value �̃N���X�^�ʼnϒ�)
+ * @return �Ăяo�������\�b�h����̖߂�l(Value)
+ */
+ public Value callStaticMethod(String packageName, String className, String methodName, Value... args)
+ throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ List classes = vm.classesByName(packageName + "." + className); // �N���X�� (���S���薼)
+ ClassType type = (ClassType)classes.get(0);
+ List methodsByName = type.methodsByName(methodName);
+ List argList = Arrays.asList(args); // ���\�b�h�ɓn�������̃��X�g
+ return type.invokeMethod(thread, methodsByName.get(0), argList, thread.INVOKE_SINGLE_THREADED); // �f�o�b�O���̃v���O�������̃��\�b�h���Ăяo��
+ }
+
+ /**
+ * ���\�b�h����ObjectReference�ƈ������w�肵�Ă��̃I�u�W�F�N�g�̃C���X�^���X���\�b�h���Ăяo��
+ * @param methodName �Ăяo���������\�b�h��
+ * @param args �Ăяo���������\�b�h�ɓn������(Value �̃N���X�^�ʼnϒ�)
+ * @return �Ăяo�������\�b�h����̖߂�l(Value)
+ */
+ public Value callInstanceMethod(String methodName, Value... args)
+ throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ ClassType type = (ClassType)obj.type();
+ List methodsByName = type.methodsByName(methodName);
+ List argList = Arrays.asList(args); // ���\�b�h�ɓn�������̃��X�g
+ return obj.invokeMethod(thread, methodsByName.get(0), argList, thread.INVOKE_SINGLE_THREADED); // �f�o�b�O���̃v���O�������̃��\�b�h���Ăяo��
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackLabelProvider.java
new file mode 100644
index 0000000..de53070
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackLabelProvider.java
@@ -0,0 +1,47 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.ThreadReference;
+
+public class CallStackLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof TreeNode) {
+ Object value = ((TreeNode)element).getValue();
+ if (value instanceof MethodCaller) {
+ MethodCaller mc = (MethodCaller)value;
+ return "ThreadID: " + mc.getThreadId();
+ }
+ if (value instanceof CallStackModel) {
+ CallStackModel callStackModel = (CallStackModel)value;
+ StringBuilder text = new StringBuilder();
+ text.append(callStackModel.getSignature());
+ text.append(" line: ");
+ text.append(callStackModel.getCallLineNo());
+ return text.toString();
+ }
+ }
+ return "";
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof TreeNode) {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+ }
+ return null;
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModel.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModel.java
new file mode 100644
index 0000000..86040d9
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModel.java
@@ -0,0 +1,83 @@
+package org.ntlab.reversedebugger;
+
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.IntegerValue;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+
+public class CallStackModel {
+ private ObjectReference methodExecution;
+// private ObjectReference childMethodExecution;
+ private MethodCaller methodExecutionMc;
+ private int callLineNo;
+
+// public CallStackModel(VirtualMachine vm, ThreadReference thread, ObjectReference methodExecution, ObjectReference childMethodExecution) {
+// methodExecutionMc = new MethodCaller(vm, thread, methodExecution);
+// this.methodExecution = methodExecution;
+// this.childMethodExecution = childMethodExecution;
+// }
+
+ public CallStackModel(VirtualMachine vm, ThreadReference thread, ObjectReference methodExecution, int callLineNo) {
+ methodExecutionMc = new MethodCaller(vm, thread, methodExecution);
+ this.methodExecution = methodExecution;
+ this.callLineNo = callLineNo;
+// this.childMethodExecution = childMethodExecution;
+ }
+
+
+ public VirtualMachine getVm() {
+ return methodExecutionMc.getVm();
+ }
+
+ public ThreadReference getThread() {
+ return methodExecutionMc.getThread();
+ }
+
+ public MethodCaller getMethodCaller() {
+ return methodExecutionMc;
+ }
+
+ public int getCallLineNo() {
+ return callLineNo;
+ }
+
+// public int getCallLineNo() {
+// if (childMethodExecution == null) {
+// return -1;
+// }
+// int callLineNo = -1;
+// try {
+// ObjectReference callStatement = (ObjectReference)methodExecutionMc.callInstanceMethod("getMethodInvocation", childMethodExecution);
+// MethodCaller callStatementMc = new MethodCaller(methodExecutionMc.getVm(), methodExecutionMc.getThread(), callStatement);
+// callLineNo = ((IntegerValue)callStatementMc.callInstanceMethod("getLineNo")).value();
+// } catch (InvalidTypeException | ClassNotLoadedException
+// | InvocationException | IncompatibleThreadStateException e) {
+// e.printStackTrace();
+// }
+// return callLineNo;
+// }
+
+ public String getSignature() {
+ String signature = "";
+ try {
+ signature = ((StringReference)methodExecutionMc.callInstanceMethod("getSignature")).value();
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ return signature;
+ }
+
+ public Value callInstanceMethod(String methodName, Value... args)
+ throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ return methodExecutionMc.callInstanceMethod(methodName, args);
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModels.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModels.java
new file mode 100644
index 0000000..971ae7a
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackModels.java
@@ -0,0 +1,97 @@
+package org.ntlab.reversedebugger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.TreeNode;
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.IntegerValue;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+import com.sun.jdi.event.MethodEntryEvent;
+
+public class CallStackModels {
+ private List callStackModels = new ArrayList<>();
+
+ public List getCallStackModels() {
+ return callStackModels;
+ }
+
+ public TreeNode[] getCallStackModelsTreeNodes() {
+ TreeNode[] roots = new TreeNode[1];
+ if (callStackModels.isEmpty()) {
+ return roots;
+ }
+ CallStackModel callStackModel = callStackModels.get(0);
+ roots[0] = new TreeNode(new MethodCaller(callStackModel.getVm(), callStackModel.getThread()));
+ TreeNode parentNode = roots[0];
+ TreeNode[] childrenNode = new TreeNode[callStackModels.size()];
+ parentNode.setChildren(childrenNode);
+ for (int i = 0; i < callStackModels.size(); i++) {
+ TreeNode childNode = new TreeNode(callStackModels.get(i));
+ childNode.setParent(parentNode);
+ childrenNode[i] = childNode;
+ }
+ return roots;
+ }
+
+ public void reset() {
+ callStackModels.clear();
+ }
+
+ public void updateByDebuggerStopMethodExecution(MethodCaller me) {
+ if (me == null) {
+ return;
+ }
+ try {
+ VirtualMachine vm = me.getVm();
+ ThreadReference thread = me.getThread();
+ int lineNo = thread.frame(0).location().lineNumber();
+ update(vm, thread, me.getObj(), lineNo);
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void updateByAlias(MethodCaller alias) {
+ if (alias == null) {
+ return;
+ }
+ VirtualMachine vm = alias.getVm();
+ ThreadReference thread = alias.getThread();
+ try {
+ ObjectReference me = (ObjectReference)alias.callInstanceMethod("getMethodExecution");
+ int lineNo = ((IntegerValue)alias.callInstanceMethod("getLineNo")).value();
+ update(vm, thread, me, lineNo);
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void update(VirtualMachine vm, ThreadReference thread, ObjectReference me, int topMethodCallLineNo)
+ throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ callStackModels.clear();
+ ObjectReference childMe = null;
+ int callLineNo = topMethodCallLineNo;
+ while (me != null) {
+ CallStackModel callStackModel = new CallStackModel(vm, thread, me, callLineNo);
+ callStackModels.add(callStackModel);
+ childMe = me;
+ me = (ObjectReference)callStackModel.callInstanceMethod("getParent");
+ if (me != null) {
+ MethodCaller mc = new MethodCaller(vm, thread, me);
+ ObjectReference callStatement = (ObjectReference)mc.callInstanceMethod("getMethodInvocation", childMe);
+ callLineNo = ((IntegerValue)mc.setObj(callStatement).callInstanceMethod("getLineNo")).value();
+ }
+ }
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackView.java
new file mode 100644
index 0000000..2c2ee60
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/CallStackView.java
@@ -0,0 +1,107 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.jface.viewers.TreeNodeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.ntlab.debuggingControl.MethodCaller;
+
+public class CallStackView extends ViewPart {
+ private static TreeViewer viewer;
+ private IAction refreshAction;
+ private static CallStackModels callStackModels = new CallStackModels();
+ private JavaEditorOperator javaEditorOperator = new JavaEditorOperator();
+ public static final String ID = "org.ntlab.reverseDebugger.callStackView";
+
+ public CallStackView() {
+ // TODO Auto-generated constructor stub
+ System.out.println("callStackView�N���X���������ꂽ��");
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ // TODO Auto-generated method stub
+ System.out.println("CallStackView#createPartControl(Composite)���Ăꂽ��!");
+ viewer = new TreeViewer(parent);
+ viewer.setContentProvider(new TreeNodeContentProvider());
+ viewer.setLabelProvider(new CallStackLabelProvider());
+
+ // �I�������J�����ɑΉ����郁�\�b�h���s�̃\�[�X�t�@�C�����J�����郊�X�i�[��o�^����
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+ Object element = sel.getFirstElement();
+ if (element instanceof TreeNode) {
+ Object value = ((TreeNode)element).getValue();
+ if (value instanceof CallStackModel) {
+ MethodCaller methodExecution = ((CallStackModel)value).getMethodCaller();
+ javaEditorOperator.openSrcFileOfMethodExecution(methodExecution);
+ }
+ }
+ }
+ });
+ createActions();
+ createToolBar();
+ createMenuBar();
+ }
+
+ @Override
+ public void setFocus() {
+ // TODO Auto-generated method stub
+ viewer.getControl().setFocus();
+ }
+
+ private void createActions() {
+ refreshAction = new Action() {
+ @Override
+ public void run() {
+ refresh();
+ }
+ };
+ refreshAction.setText("refresh");
+ refreshAction.setToolTipText("refresh");
+ refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));
+ }
+
+ private void createToolBar() {
+ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+ mgr.add(refreshAction);
+ }
+
+ private void createMenuBar() {
+ IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+ mgr.add(refreshAction);
+ }
+
+ public static void updateByAlias(MethodCaller alias) {
+ callStackModels.updateByAlias(alias);
+ }
+
+ public static void refresh() {
+ if (callStackModels.getCallStackModels().isEmpty()) {
+ MethodCaller currentMe = SeedAliasView.getDebuggerStopMethodExecution();
+ callStackModels.updateByDebuggerStopMethodExecution(currentMe);
+ }
+ TreeNode[] nodes = callStackModels.getCallStackModelsTreeNodes();
+ if (nodes == null || nodes[0] == null) {
+ return;
+ }
+ viewer.setInput(callStackModels.getCallStackModelsTreeNodes());
+ }
+
+ public static void reset() {
+ callStackModels.reset();
+ refresh();
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/JavaEditorOperator.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/JavaEditorOperator.java
new file mode 100644
index 0000000..33a603e
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/JavaEditorOperator.java
@@ -0,0 +1,219 @@
+package org.ntlab.reversedebugger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PartInitException;
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+
+public class JavaEditorOperator {
+ private static final String TRACE = "org.ntlab.traceCollector.tracer.trace";
+
+ public void openSrcFileOfAlias(MethodCaller alias) {
+ try {
+ ObjectReference methodExecution = (ObjectReference)alias.callInstanceMethod("getMethodExecution");
+ MethodCaller meCaller = new MethodCaller(alias.getVm(), alias.getThread(), methodExecution);
+ openSrcFileOfMethodExecution(meCaller);
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �����œn����meCaller���ɂ���methodExecution����`����Ă���N���X�̃\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������
+ *
+ * @param meCaller
+ */
+ public void openSrcFileOfMethodExecution(MethodCaller meCaller) {
+ try {
+ IType type = findIType(meCaller);
+ if (type != null) {
+ IMethod method = findIMethod(meCaller, type);
+ if (method != null) {
+ openSrcFileOfIMethod(type, method);
+ }
+ }
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �����œn����IType��IMethod�ɑΉ�����\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������
+ *
+ * @param type
+ * @param method
+ */
+ private void openSrcFileOfIMethod(IType type, IMethod method) throws InvalidTypeException, ClassNotLoadedException,
+ InvocationException, IncompatibleThreadStateException {
+ openInJavaEditor(type, method);
+ }
+
+ private IType findIType(MethodCaller meCaller) throws InvalidTypeException,
+ ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ StringReference declaringClassName = (StringReference)meCaller.callInstanceMethod("getDeclaringClassName");
+ String projectPath = getLoaderPath(meCaller, declaringClassName);
+ IType type = null;
+ if (projectPath != null) {
+ IJavaProject javaProject = findJavaProject(projectPath);
+ if (javaProject != null) {
+ StringReference methodSignature = (StringReference)meCaller.callInstanceMethod("getSignature");
+ try {
+ type = javaProject.findType(declaringClassName.value());
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return type;
+ }
+
+ private String getLoaderPath(MethodCaller meCaller, StringReference declaringClassName)
+ throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ ObjectReference classInfo = (ObjectReference)meCaller.callStaticMethod(TRACE, "TraceJSON", "getClassInfo", declaringClassName);
+ if (classInfo == null) {
+ declaringClassName = (StringReference)meCaller.callInstanceMethod("getThisClassName");
+ classInfo = (ObjectReference)meCaller.callStaticMethod(TRACE, "TraceJSON", "getClassInfo", declaringClassName);
+ }
+ String loaderPath = null;
+ if (classInfo != null) {
+ // �Ȃ���loaderPath���擾�ł��Ă��Ȃ����߁A���ۂɏo�͂����JSON�g���[�X���Q�l�ɂ���path����^���Ă݂�
+ MethodCaller classInfoMethodCaller = new MethodCaller(meCaller.getVm(), meCaller.getThread(), classInfo);
+ String path = ((StringReference)classInfoMethodCaller.callInstanceMethod("getPath")).value();
+ String declaringClassNameString = declaringClassName.value().replace(".", "/");
+ loaderPath = path.substring(0, path.indexOf(declaringClassNameString)); // path����N���X�̊��S���薼�ȍ~��S�ĊO�������̂�projectPath�ɂ��Ă݂�
+ }
+ return loaderPath;
+ }
+
+ private IJavaProject findJavaProject(String projectPath) {
+ IJavaProject javaProject = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject[] projects = root.getProjects();
+ for (IProject project : projects) {
+ if (checkProjectPath(project, projectPath)) {
+ javaProject = JavaCore.create(project);
+ break;
+ }
+ }
+ return javaProject;
+ }
+
+ private boolean checkProjectPath(IProject project, String projectPath) {
+ String projectLocation = project.getLocation().toString();
+ if (projectPath.startsWith(projectLocation)) {
+ String[] projectPathSplit = projectPath.split(projectLocation);
+ return (projectPathSplit[1].charAt(0) == '/'); // �v���W�F�N�g���̑O����v�ɂ�鑼�v���W�F�N�g�Ƃ̌딻��������
+ }
+ return false;
+ }
+
+ private void openInJavaEditor(IType type, IMethod method) {
+ try {
+ if (type != null && method != null) {
+ IEditorPart editor = JavaUI.openInEditor(type);
+ if (!type.isLocal() && !type.isMember()) {
+ JavaUI.revealInEditor(editor, (IJavaElement) method);
+ }
+ }
+ } catch (PartInitException | JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private IMethod findIMethod(MethodCaller meCaller, IType type) throws InvalidTypeException,
+ ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ IMethod method = null;
+ if (type != null) {
+ StringReference methodSignature = (StringReference)meCaller.callInstanceMethod("getSignature");
+ method = findIMethod(type, methodSignature.value());
+ }
+ return method;
+ }
+
+ private IMethod findIMethod(IType type, String methodSignature) {
+ try {
+ for (IMethod method : type.getMethods()) {
+ if (checkMethodSignature(type, method, methodSignature)) {
+ return method;
+ }
+ }
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private boolean checkMethodSignature(IType type, IMethod method, String methodSignature) {
+ String fqcn = type.getFullyQualifiedName();
+ try {
+ StringBuilder jdtMethodSignature = new StringBuilder();
+ jdtMethodSignature.append((method.isConstructor()) ? (fqcn + "(") : (fqcn + "." + method.getElementName() + "("));
+ if (methodSignature.contains(jdtMethodSignature)) {
+ // ������v���Ă����ꍇ�Ɍ���A�������X�g����������ł���v���邩�ǂ����� (�I�[�o�[���[�h�ɂ��딻��������)
+ jdtMethodSignature.append(String.join(",", parseFQCNParameters(type, method)) + ")"); // �S�����̃V�O�l�`�������S����N���X���ɕϊ�����,�ŋ����������
+ return methodSignature.contains(jdtMethodSignature);
+ }
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * IMethod����擾�ł���S�����̃V�O�l�`�������S����N���X���ɒu�������Ċi�[�������X�g��Ԃ�
+ *
+ * @param type
+ * @param method
+ * @return
+ */
+ private List parseFQCNParameters(IType type, IMethod method) throws JavaModelException {
+ List parameters = new ArrayList<>();
+ for (String parameterType : method.getParameterTypes()) {
+ String readableType = Signature.toString(parameterType); // �V�O�l�`���̕�������^���̕�����ɕϊ� (�z��͌���[]����)
+ String[] readableTypeSplit = { "", "" }; // �^����[]�̕����p
+ int firstBracketIndex = readableType.indexOf("[]");
+ final int NO_BRACKET_INDEX = -1;
+ if (firstBracketIndex == NO_BRACKET_INDEX) {
+ readableTypeSplit[0] = readableType; // �^��
+ } else {
+ readableTypeSplit[0] = readableType.substring(0, firstBracketIndex); // �^��
+ readableTypeSplit[1] = readableType.substring(firstBracketIndex); // �^���̌���[]�S��
+ }
+ String[][] resolveType = type.resolveType(readableTypeSplit[0]); // �p�b�P�[�W���ƃN���X���̑g�ݍ��킹���擾
+ if (resolveType != null) {
+ if (resolveType[0][0].isEmpty()) {
+ readableTypeSplit[0] = (resolveType[0][1]); // �f�t�H���g�p�b�P�[�W�̏ꍇ�̓p�b�P�[�W����.�͓���Ȃ�
+ } else {
+ readableTypeSplit[0] = (resolveType[0][0] + "." + resolveType[0][1]); // ���S����N���X��
+ }
+ }
+ parameters.add(readableTypeSplit[0] + readableTypeSplit[1]);
+ }
+ return parameters;
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasLabelProvider.java
new file mode 100644
index 0000000..035e55b
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasLabelProvider.java
@@ -0,0 +1,61 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.IntegerValue;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.StringReference;
+
+public class ObjectFlowAliasLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ if (element instanceof MethodCaller) {
+ MethodCaller mc = (MethodCaller)element;
+ if (mc.getObj() == null) {
+ return "";
+ }
+ try {
+ switch (columnIndex) {
+ case 0:
+ return ((StringReference)mc.callInstanceMethod("getObjectId")).value();
+ case 1:
+ return ((StringReference)mc.callInstanceMethod("getClassName")).value();
+ case 2:
+ return ((StringReference)mc.callInstanceMethod("getMethodExecutionClassName")).value();
+ case 3:
+ return String.valueOf(((IntegerValue)mc.callInstanceMethod("getLineNo")).value());
+ case 4:
+ return ((StringReference)mc.callInstanceMethod("getStatementType")).value();
+ case 5:
+ return ((StringReference)mc.callInstanceMethod("getStatementSignature")).value();
+ case 6:
+ return ((StringReference)mc.callInstanceMethod("getOccurrenceText")).value();
+ }
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+ return "�e�X�g�p�e�L�X�g" + columnIndex;
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex) {
+ return getImage(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasView.java
new file mode 100644
index 0000000..e836290
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliasView.java
@@ -0,0 +1,174 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.ntlab.debuggingControl.MethodCaller;
+
+public class ObjectFlowAliasView extends ViewPart {
+ private static TableViewer viewer;
+ private IAction refreshAction;
+ private IAction findSeedAliasesAction;
+ private MethodCaller selectObjectFlowAlias;
+ private static ObjectFlowAliases objectFlowAliases = new ObjectFlowAliases();
+ private JavaEditorOperator javaEditorOperator = new JavaEditorOperator();
+ public static final String ID = "org.ntlab.reverseDebugger.objectFlowAliasView";
+
+ public ObjectFlowAliasView() {
+ // TODO Auto-generated constructor stub
+ System.out.println("ObjectFlowView�N���X���������ꂽ��!");
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ // TODO Auto-generated method stub
+ System.out.println("ObjectFlowView#createPartControl(Composite)���Ăꂽ��!");
+ viewer = new TableViewer(parent, SWT.FULL_SELECTION);
+ Table table = viewer.getTable();
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ // �e�[�u���̃J�������쐬
+ String[] tableColumnTexts = {"objectID", "objectType", "srcFile", "lineNo", "statementType", "statementSignature", "occurrence"};
+ int[] tableColumnWidth = {150, 160, 160, 80, 180, 300, 110};
+ TableColumn[] tableColumns = new TableColumn[tableColumnTexts.length];
+ for (int i = 0; i < tableColumns.length; i++) {
+ tableColumns[i] = new TableColumn(table, SWT.NULL);
+ tableColumns[i].setText(tableColumnTexts[i]);
+ tableColumns[i].setWidth(tableColumnWidth[i]);
+ }
+ viewer.setContentProvider(new ArrayContentProvider());
+ viewer.setLabelProvider(new ObjectFlowAliasLabelProvider());
+ viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true));
+
+ // �I�������J�����ɑΉ�����G�C���A�X������郁�\�b�h���s���̑S�ẴV�[�h�G�C���A�X�̈ꗗ�����郊�X�i�[��o�^
+// viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+// @Override
+// public void selectionChanged(SelectionChangedEvent event) {
+// IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+// Object element = sel.getFirstElement();
+// if (element instanceof MethodCaller) {
+// MethodCaller alias = (MethodCaller)element;
+// SeedAliasView.createSeedAliases(alias);
+// SeedAliasView.refresh();
+// CallStackView.updateByAlias(alias);
+// CallStackView.refresh();
+// javaEditorOperator.openSrcFileOfAlias(alias);
+// }
+// }
+// });
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+ Object element = sel.getFirstElement();
+ if (element instanceof MethodCaller) {
+ selectObjectFlowAlias = (MethodCaller)element;
+ javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias);
+ }
+ }
+ });
+
+ createActions();
+ createToolBar();
+ createMenuBar();
+ createPopupMenu();
+ }
+
+ @Override
+ public void setFocus() {
+ // TODO Auto-generated method stub
+ viewer.getControl().setFocus();
+// viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true));
+ }
+
+ private void createActions() {
+ refreshAction = new Action() {
+ @Override
+ public void run() {
+ refresh();
+ }
+ };
+ refreshAction.setText("refresh");
+ refreshAction.setToolTipText("refresh");
+ refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));
+
+ findSeedAliasesAction = new Action() {
+ @Override
+ public void run() {
+ findSeedAliases();
+ }
+ };
+ findSeedAliasesAction.setText("findSeedAliases");
+ findSeedAliasesAction.setToolTipText("findSeedAliases");
+ findSeedAliasesAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK));
+ }
+
+ private void createToolBar() {
+ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+ mgr.add(refreshAction);
+ }
+
+ private void createMenuBar() {
+ IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+ mgr.add(refreshAction);
+ }
+
+ private void createPopupMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ manager.add(findSeedAliasesAction);
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ public static void createObjectFlow(MethodCaller seedAlias) {
+ objectFlowAliases.createObjectFlow(seedAlias);
+ }
+
+ private void findSeedAliases() {
+ SeedAliasView.createSeedAliases(selectObjectFlowAlias);
+ SeedAliasView.refresh();
+ CallStackView.updateByAlias(selectObjectFlowAlias);
+ CallStackView.refresh();
+ javaEditorOperator.openSrcFileOfAlias(selectObjectFlowAlias);
+ }
+
+ public static void refresh() {
+ viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true));
+ }
+
+ public static void reset() {
+ objectFlowAliases.reset();
+ viewer.setInput(objectFlowAliases.getObjectFlowSingleList(true));
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliases.java
new file mode 100644
index 0000000..5b32580
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ObjectFlowAliases.java
@@ -0,0 +1,75 @@
+package org.ntlab.reversedebugger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.IntegerValue;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+
+public class ObjectFlowAliases {
+ private List> objectFlowAliases = new ArrayList<>();
+ private static final String TRACE = "org.ntlab.traceCollector.tracer.trace";
+
+ public void reset() {
+ objectFlowAliases.clear();
+ }
+
+ public List> getObjectFlow() {
+ return objectFlowAliases;
+ }
+
+ public List> getObjectFlow(MethodCaller seedAlias) {
+ createObjectFlow(seedAlias);
+ return objectFlowAliases;
+ }
+
+ public List getObjectFlowSingleList(boolean hasBound) {
+ List list = new ArrayList<>();
+ for (int i = 0; i < objectFlowAliases.size(); i++) {
+ for (int j = 0; j < objectFlowAliases.get(i).size(); j++) {
+ list.add(objectFlowAliases.get(i).get(j));
+ }
+ if (hasBound) {
+ list.add(new MethodCaller(null, null)); // ���E�p�̃_�~�[�C���X�^���X�����Ēlj�
+ }
+ }
+ return list;
+ }
+
+ public List getObjectFlowSingleList(MethodCaller seedAlias, boolean hasBound) {
+ createObjectFlow(seedAlias);
+ return getObjectFlowSingleList(hasBound);
+ }
+
+ public void createObjectFlow(MethodCaller seedAlias) {
+ MethodCaller mc = new MethodCaller(seedAlias.getVm(), seedAlias.getThread());
+ objectFlowAliases.clear();
+ try {
+ // �I�������G�C���A�X���N�_�ɃI�u�W�F�N�g�t���[���Ăяo���Č��ʂ����X�g�Ŏ��
+ ObjectReference aliasListsReference = (ObjectReference)seedAlias.callStaticMethod(TRACE, "TraceJSON", "getObjectFlow", seedAlias.getObj());
+
+ // �擾�������X�g�̒��g�����[�v�ʼnȂ�����o��, �Ǘ��p�̃��X�g�ɋl�ߒ���
+ int aliasListsSize = ((IntegerValue)mc.setObj(aliasListsReference).callInstanceMethod("size")).value();
+ for (int i = 0; i < aliasListsSize; i++) {
+ List list = new ArrayList<>();
+ objectFlowAliases.add(list);
+ ObjectReference aliasListReference = (ObjectReference)mc.setObj(aliasListsReference).callInstanceMethod("get", mc.getVm().mirrorOf(i));
+ int aliasListSize = ((IntegerValue)mc.setObj(aliasListReference).callInstanceMethod("size")).value();
+ for (int j = 0; j < aliasListSize; j++) {
+ ObjectReference aliasReference = (ObjectReference)mc.setObj(aliasListReference).callInstanceMethod("get", mc.getVm().mirrorOf(j));
+ list.add(new MethodCaller(seedAlias.getVm(), seedAlias.getThread(), aliasReference));
+ }
+ }
+ } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ReverseDebuggerPerspective.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ReverseDebuggerPerspective.java
new file mode 100644
index 0000000..c3b5584
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/ReverseDebuggerPerspective.java
@@ -0,0 +1,27 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.part.IPage;
+
+public class ReverseDebuggerPerspective implements IPerspectiveFactory {
+
+ @Override
+ public void createInitialLayout(IPageLayout layout) {
+ // �G�f�B�^�̏ꏊ���擾
+ String editorArea = layout.getEditorArea();
+
+ // ����ɃR�[���X�^�b�N�̃r���[��z�u
+ IFolderLayout topLeft = layout.createFolder("topLeft", IPageLayout.TOP, 0.35f, editorArea);
+ topLeft.addView(CallStackView.ID);
+
+ // �E��ɃV�[�h�G�C���A�X�̃r���[��z�u
+ IFolderLayout topRight = layout.createFolder("topRight", IPageLayout.RIGHT, 0.5f, "topLeft");
+ topRight.addView(SeedAliasView.ID);
+
+ // �E���ɃI�u�W�F�N�g�t���[�G�C���A�X�̃r���[��z�u
+ IFolderLayout bottomRight = layout.createFolder("bottomRight", IPageLayout.RIGHT, 0.5f, editorArea);
+ bottomRight.addView(ObjectFlowAliasView.ID);
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasLabelProvider.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasLabelProvider.java
new file mode 100644
index 0000000..e686586
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasLabelProvider.java
@@ -0,0 +1,59 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.IntegerValue;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.Value;
+
+public class SeedAliasLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ if (element instanceof MethodCaller) {
+ MethodCaller mc = (MethodCaller)element;
+ try {
+ switch (columnIndex) {
+ case 0:
+ return ((StringReference)mc.callInstanceMethod("getObjectId")).value();
+ case 1:
+ return ((StringReference)mc.callInstanceMethod("getClassName")).value();
+ case 2:
+ return ((StringReference)mc.callInstanceMethod("getMethodExecutionClassName")).value();
+ case 3:
+ return String.valueOf(((IntegerValue)mc.callInstanceMethod("getLineNo")).value());
+ case 4:
+ return ((StringReference)mc.callInstanceMethod("getStatementType")).value();
+ case 5:
+ return ((StringReference)mc.callInstanceMethod("getStatementSignature")).value();
+ case 6:
+ return ((StringReference)mc.callInstanceMethod("getOccurrenceText")).value();
+ }
+ } catch (InvalidTypeException | ClassNotLoadedException
+ | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+ return "�e�X�g�p�e�L�X�g" + columnIndex;
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex) {
+ return getImage(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasView.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasView.java
new file mode 100644
index 0000000..6c6c043
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliasView.java
@@ -0,0 +1,192 @@
+package org.ntlab.reversedebugger;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.ntlab.debuggingControl.MethodCaller;
+
+public class SeedAliasView extends ViewPart {
+ private static TableViewer viewer;
+ private IAction refreshAction;
+ private IAction resetAction;
+ private IAction getObjectFlowAction;
+ private MethodCaller selectSeedAlias;
+ private static SeedAliases seedAliases = new SeedAliases();
+ private static JavaEditorOperator javaEditorOperator = new JavaEditorOperator();
+ public static final String ID = "org.ntlab.reverseDebugger.seedAliasView";
+
+ public SeedAliasView() {
+ // TODO Auto-generated constructor stub
+ System.out.println("SeedAliasView�N���X���������ꂽ��!");
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ // TODO Auto-generated method stub
+ System.out.println("SeedAliasView#createPartControl(Composite)���Ăꂽ��!");
+ viewer = new TableViewer(parent, SWT.FULL_SELECTION);
+ Table table = viewer.getTable();
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ // �e�[�u���̃J�������쐬
+ String[] tableColumnTexts = {"objectID", "objectType", "srcFile", "lineNo", "statementType", "statementSignature", "occurrence"};
+ int[] tableColumnWidth = {150, 160, 160, 80, 180, 300, 110};
+ TableColumn[] tableColumns = new TableColumn[tableColumnTexts.length];
+ for (int i = 0; i < tableColumns.length; i++) {
+ tableColumns[i] = new TableColumn(table, SWT.NULL);
+ tableColumns[i].setText(tableColumnTexts[i]);
+ tableColumns[i].setWidth(tableColumnWidth[i]);
+ }
+ viewer.setContentProvider(new ArrayContentProvider());
+ viewer.setLabelProvider(new SeedAliasLabelProvider());
+ viewer.setInput(seedAliases.getSeedAliases());
+ CallStackView.refresh();
+
+ // �I�������J�����ɑΉ�����V�[�h�G�C���A�X���N�_�ɃI�u�W�F�N�g�t���[�����s�����郊�X�i�[��o�^
+// viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+// @Override
+// public void selectionChanged(SelectionChangedEvent event) {
+// IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+// Object element = sel.getFirstElement();
+// if (element instanceof MethodCaller) {
+// MethodCaller seedAlias = (MethodCaller)element;
+// ObjectFlowAliasView.createObjectFlow(seedAlias);
+// ObjectFlowAliasView.refresh();
+// }
+// }
+// });
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+ Object element = sel.getFirstElement();
+ if (element instanceof MethodCaller) {
+ selectSeedAlias = (MethodCaller)element;
+ javaEditorOperator.openSrcFileOfAlias(selectSeedAlias);
+ }
+ }
+ });
+
+ createActions();
+ createToolBar();
+ createMenuBar();
+ createPopupMenu();
+ }
+
+ @Override
+ public void setFocus() {
+ // TODO Auto-generated method stub
+ viewer.getControl().setFocus();
+// viewer.refresh();
+ }
+
+ private void createActions() {
+ refreshAction = new Action() {
+ @Override
+ public void run() {
+ refresh();
+ }
+ };
+ refreshAction.setText("refresh");
+ refreshAction.setToolTipText("refresh");
+ refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));
+
+ resetAction = new Action() {
+ @Override
+ public void run() {
+ reset();
+ }
+ };
+ resetAction.setText("reset");
+ resetAction.setToolTipText("reset");
+ resetAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_HOME_NAV));
+
+ getObjectFlowAction = new Action() {
+ @Override
+ public void run() {
+ getObjectFlow();
+ }
+ };
+ getObjectFlowAction.setText("getObjectFlow");
+ getObjectFlowAction.setToolTipText("getObjectFlow");
+ getObjectFlowAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK));
+ }
+
+ private void createToolBar() {
+ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+ mgr.add(refreshAction);
+ mgr.add(resetAction);
+ }
+
+ private void createMenuBar() {
+ IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+ mgr.add(refreshAction);
+ mgr.add(resetAction);
+ }
+
+ private void createPopupMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ manager.add(getObjectFlowAction);
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ public static MethodCaller getDebuggerStopMethodExecution() {
+ return seedAliases.getDebuggerStopMethodExecution();
+ }
+
+ public static void createSeedAliases(MethodCaller alias) {
+ seedAliases.createSeedAliases(alias);
+ }
+
+ public static void refresh() {
+ if (seedAliases.getSeedAliases().isEmpty()) {
+ seedAliases.initSeedAliases();
+ javaEditorOperator.openSrcFileOfMethodExecution(seedAliases.getDebuggerStopMethodExecution());
+ CallStackView.reset();
+ }
+ viewer.refresh();
+ CallStackView.refresh();
+ }
+
+ private void reset() {
+ seedAliases.reset();
+ ObjectFlowAliasView.reset();
+ refresh();
+ }
+
+ private void getObjectFlow() {
+ if (selectSeedAlias != null) {
+ ObjectFlowAliasView.createObjectFlow(selectSeedAlias);
+ ObjectFlowAliasView.refresh();
+ }
+ }
+}
diff --git a/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliases.java b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliases.java
new file mode 100644
index 0000000..e295db3
--- /dev/null
+++ b/org.ntlab.reverseDebugger/src/org/ntlab/reversedebugger/SeedAliases.java
@@ -0,0 +1,141 @@
+package org.ntlab.reversedebugger;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.internal.core.LaunchManager;
+import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.ntlab.debuggingControl.MethodCaller;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.ClassType;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.IntegerValue;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.Location;
+import com.sun.jdi.LongValue;
+import com.sun.jdi.Method;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.StackFrame;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+
+public class SeedAliases {
+ private MethodCaller debuggerStopMethodExecution = null;
+ private List seedAliases = new ArrayList<>();
+ private final String TRACER = "org.ntlab.traceCollector.tracer.trace";
+
+ public SeedAliases() {
+ initSeedAliases();
+ }
+
+ public MethodCaller getDebuggerStopMethodExecution() {
+ return debuggerStopMethodExecution;
+ }
+
+ public List getSeedAliases() {
+ return seedAliases;
+ }
+
+ public void reset() {
+ seedAliases.clear();
+ }
+
+ public void initSeedAliases() {
+ // TODO Auto-generated method stub
+ LaunchManager lm = (LaunchManager)DebugPlugin.getDefault().getLaunchManager();
+
+ ILaunch[] launches = lm.getLaunches();
+ if (launches.length != 0) {
+ ILaunch debugLaunch = null;
+ for (int i = 0; i < launches.length; i++) {
+ System.out.print(launches[i].getLaunchConfiguration().getName() + ":");
+ System.out.print(launches[i].getDebugTarget());
+ if (launches[i].getDebugTarget() != null) {
+ debugLaunch = launches[i];
+ break;
+ }
+ }
+ if (debugLaunch != null) {
+ JDIDebugTarget debugTarget = ((JDIDebugTarget)debugLaunch.getDebugTarget());
+ VirtualMachine vm = debugTarget.getVM();
+ if (vm != null) {
+ // �f�o�b�O���s���̏ꍇ
+ List allThreads = vm.allThreads();
+ for (int i = 0; i < allThreads.size(); i++) {
+ ThreadReference thread = allThreads.get(i);
+ if (thread.isSuspended()) {
+ createSeedAliases(vm, thread);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * ���݃f�o�b�K�Ŏ~�܂��Ă���n�_�ł̃��\�b�h���s���̑S�V�[�h�G�C���A�X�ꗗ���Z�b�g����
+ * @param vm
+ * @param thread
+ */
+ private void createSeedAliases(VirtualMachine vm, ThreadReference thread) {
+ MethodCaller mc = new MethodCaller(vm, thread);
+ try {
+ // threadId�̎擾��StringReference�^�ւ̕ϊ�
+ Value threadIdValue = mc.setObj(thread).callInstanceMethod("getId");
+ StringReference threadId = vm.mirrorOf(String.valueOf(((LongValue)threadIdValue).value()));
+
+ // threadId�ɑΉ�����ThreadInstance���擾
+ ObjectReference threadInstance = (ObjectReference)mc.callStaticMethod(TRACER, "TraceJSON", "getThreadInstance", threadId);
+ Value methodExecution = mc.setObj(threadInstance).callInstanceMethod("getCurrentMethodExecution");
+ debuggerStopMethodExecution = new MethodCaller(vm, thread, (ObjectReference)methodExecution);
+ findAllSeedAlias(vm, thread, methodExecution);
+ } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �n���ꂽ�G�C���A�X������郁�\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ���Z�b�g����
+ * @param alias
+ */
+ public void createSeedAliases(MethodCaller alias) {
+ VirtualMachine vm = alias.getVm();
+ ThreadReference thread = alias.getThread();
+ MethodCaller mc = new MethodCaller(vm, thread);
+ try {
+ Value methodExecution = alias.callInstanceMethod("getMethodExecution");
+ findAllSeedAlias(vm, thread, methodExecution);
+ } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * �n���ꂽ���\�b�h���s���̑S�V�[�h�G�C���A�X�̈ꗗ��, ���ۂ�traceCollector���ƒʐM���Ď擾���Z�b�g����
+ * @param vm
+ * @param thread
+ * @param methodExecution
+ */
+ private void findAllSeedAlias(VirtualMachine vm, ThreadReference thread, Value methodExecution) throws InvalidTypeException,
+ ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
+ MethodCaller mc = new MethodCaller(vm, thread);
+ seedAliases.clear();
+ ObjectReference seedAliasList = (ObjectReference)mc.callStaticMethod(TRACER, "TraceJSON", "findAllStartAlias", methodExecution);
+ int seedAliasListSize = ((IntegerValue)mc.setObj(seedAliasList).callInstanceMethod("size")).value();
+ for (int i = 0; i < seedAliasListSize; i++) {
+ ObjectReference seedAlias = (ObjectReference)mc.setObj(seedAliasList).callInstanceMethod("get", vm.mirrorOf(i));
+ seedAliases.add(new MethodCaller(vm, thread, seedAlias));
+ }
+ }
+}