diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..5d953bc
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..875514e
--- /dev/null
+++ b/.project
@@ -0,0 +1,28 @@
+
+
+ org.ntlab.traceDebugger
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..19117a3
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4ef7b30
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: TraceDebugger
+Bundle-SymbolicName: org.ntlab.traceDebugger3;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Automatic-Module-Name: org.ntlab.objectFlowAnalyzer2
+Require-Bundle: org.eclipse.ui;bundle-version="3.109.100",
+ org.eclipse.core.runtime;bundle-version="3.14.0",
+ org.eclipse.debug.core;bundle-version="3.12.0",
+ org.eclipse.jdt.debug;bundle-version="3.11.100",
+ org.eclipse.jdt.core;bundle-version="3.14.0",
+ org.eclipse.jdt.ui;bundle-version="3.14.0",
+ org.ntlab.traceAnalysisPlatform;bundle-version="1.0.0",
+ org.eclipse.ui.editors;bundle-version="3.11.100",
+ org.eclipse.jface.text;bundle-version="3.13.0",
+ org.eclipse.ui.ide;bundle-version="3.14.0"
diff --git a/bin/org/ntlab/traceDebugger/BreakPointLabelProvider.class b/bin/org/ntlab/traceDebugger/BreakPointLabelProvider.class
new file mode 100644
index 0000000..3465ec5
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointLabelProvider.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$1.class b/bin/org/ntlab/traceDebugger/BreakPointView$1.class
new file mode 100644
index 0000000..255d5d3
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$1.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$10.class b/bin/org/ntlab/traceDebugger/BreakPointView$10.class
new file mode 100644
index 0000000..afef8dd
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$10.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$11.class b/bin/org/ntlab/traceDebugger/BreakPointView$11.class
new file mode 100644
index 0000000..c707ca4
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$11.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$12.class b/bin/org/ntlab/traceDebugger/BreakPointView$12.class
new file mode 100644
index 0000000..fa9cc4f
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$12.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$13.class b/bin/org/ntlab/traceDebugger/BreakPointView$13.class
new file mode 100644
index 0000000..75a9c76
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$13.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$14.class b/bin/org/ntlab/traceDebugger/BreakPointView$14.class
new file mode 100644
index 0000000..234276c
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$14.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$15.class b/bin/org/ntlab/traceDebugger/BreakPointView$15.class
new file mode 100644
index 0000000..2c2242f
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$15.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$16.class b/bin/org/ntlab/traceDebugger/BreakPointView$16.class
new file mode 100644
index 0000000..2f5bc40
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$16.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$17.class b/bin/org/ntlab/traceDebugger/BreakPointView$17.class
new file mode 100644
index 0000000..d93d4e8
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$17.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$2.class b/bin/org/ntlab/traceDebugger/BreakPointView$2.class
new file mode 100644
index 0000000..5a46adb
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$2.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$3.class b/bin/org/ntlab/traceDebugger/BreakPointView$3.class
new file mode 100644
index 0000000..cff85f4
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$3.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$4.class b/bin/org/ntlab/traceDebugger/BreakPointView$4.class
new file mode 100644
index 0000000..a975a73
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$4.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$5.class b/bin/org/ntlab/traceDebugger/BreakPointView$5.class
new file mode 100644
index 0000000..22ff5d9
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$5.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$6.class b/bin/org/ntlab/traceDebugger/BreakPointView$6.class
new file mode 100644
index 0000000..b373fb6
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$6.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$7.class b/bin/org/ntlab/traceDebugger/BreakPointView$7.class
new file mode 100644
index 0000000..abb33b8
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$7.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$8.class b/bin/org/ntlab/traceDebugger/BreakPointView$8.class
new file mode 100644
index 0000000..62cc159
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$8.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView$9.class b/bin/org/ntlab/traceDebugger/BreakPointView$9.class
new file mode 100644
index 0000000..dab4d59
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView$9.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/BreakPointView.class b/bin/org/ntlab/traceDebugger/BreakPointView.class
new file mode 100644
index 0000000..ccabb54
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/BreakPointView.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackLabelProvider.class b/bin/org/ntlab/traceDebugger/CallStackLabelProvider.class
new file mode 100644
index 0000000..b569d40
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackLabelProvider.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackModel.class b/bin/org/ntlab/traceDebugger/CallStackModel.class
new file mode 100644
index 0000000..f253db8
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackModel.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackModels.class b/bin/org/ntlab/traceDebugger/CallStackModels.class
new file mode 100644
index 0000000..fe46453
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackModels.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackView$1.class b/bin/org/ntlab/traceDebugger/CallStackView$1.class
new file mode 100644
index 0000000..a1ab80d
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackView$1.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackView$2.class b/bin/org/ntlab/traceDebugger/CallStackView$2.class
new file mode 100644
index 0000000..483f015
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackView$2.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackView.class b/bin/org/ntlab/traceDebugger/CallStackView.class
new file mode 100644
index 0000000..0e7ca2b
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackView.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/CallStackVisitor.class b/bin/org/ntlab/traceDebugger/CallStackVisitor.class
new file mode 100644
index 0000000..0c361c2
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/CallStackVisitor.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/DebuggingController.class b/bin/org/ntlab/traceDebugger/DebuggingController.class
new file mode 100644
index 0000000..47c1e53
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/DebuggingController.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/JavaEditorOperator.class b/bin/org/ntlab/traceDebugger/JavaEditorOperator.class
new file mode 100644
index 0000000..e3a0a70
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/JavaEditorOperator.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/TraceBreakPoint$1.class b/bin/org/ntlab/traceDebugger/TraceBreakPoint$1.class
new file mode 100644
index 0000000..259f16a
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/TraceBreakPoint$1.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/TraceBreakPoint.class b/bin/org/ntlab/traceDebugger/TraceBreakPoint.class
new file mode 100644
index 0000000..9249ac7
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/TraceBreakPoint.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/TraceBreakPoints$1.class b/bin/org/ntlab/traceDebugger/TraceBreakPoints$1.class
new file mode 100644
index 0000000..15e5399
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/TraceBreakPoints$1.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/TraceBreakPoints.class b/bin/org/ntlab/traceDebugger/TraceBreakPoints.class
new file mode 100644
index 0000000..fcb8add
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/TraceBreakPoints.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/TraceDebuggerPerspective.class b/bin/org/ntlab/traceDebugger/TraceDebuggerPerspective.class
new file mode 100644
index 0000000..95aac69
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/TraceDebuggerPerspective.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/TraceDebuggerPlugin.class b/bin/org/ntlab/traceDebugger/TraceDebuggerPlugin.class
new file mode 100644
index 0000000..394c546
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/TraceDebuggerPlugin.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/Variable$1.class b/bin/org/ntlab/traceDebugger/Variable$1.class
new file mode 100644
index 0000000..9db3084
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/Variable$1.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/Variable$2.class b/bin/org/ntlab/traceDebugger/Variable$2.class
new file mode 100644
index 0000000..f0e52e7
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/Variable$2.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/Variable$DeepHierarchy.class b/bin/org/ntlab/traceDebugger/Variable$DeepHierarchy.class
new file mode 100644
index 0000000..341f79f
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/Variable$DeepHierarchy.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/Variable.class b/bin/org/ntlab/traceDebugger/Variable.class
new file mode 100644
index 0000000..f41ec35
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/Variable.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/VariableLabelProvider.class b/bin/org/ntlab/traceDebugger/VariableLabelProvider.class
new file mode 100644
index 0000000..3effe71
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/VariableLabelProvider.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/VariableView$1.class b/bin/org/ntlab/traceDebugger/VariableView$1.class
new file mode 100644
index 0000000..630e235
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/VariableView$1.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/VariableView$2.class b/bin/org/ntlab/traceDebugger/VariableView$2.class
new file mode 100644
index 0000000..9827e60
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/VariableView$2.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/VariableView$3.class b/bin/org/ntlab/traceDebugger/VariableView$3.class
new file mode 100644
index 0000000..0a3a475
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/VariableView$3.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/VariableView$4.class b/bin/org/ntlab/traceDebugger/VariableView$4.class
new file mode 100644
index 0000000..e8dde6e
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/VariableView$4.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/VariableView.class b/bin/org/ntlab/traceDebugger/VariableView.class
new file mode 100644
index 0000000..4ef7867
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/VariableView.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/Variables.class b/bin/org/ntlab/traceDebugger/Variables.class
new file mode 100644
index 0000000..cdd6aa2
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/Variables.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/AbstractAnalyzer.class b/bin/org/ntlab/traceDebugger/analyzerProvider/AbstractAnalyzer.class
new file mode 100644
index 0000000..037ba68
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/AbstractAnalyzer.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/Alias.class b/bin/org/ntlab/traceDebugger/analyzerProvider/Alias.class
new file mode 100644
index 0000000..17ae051
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/Alias.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/Delta.class b/bin/org/ntlab/traceDebugger/analyzerProvider/Delta.class
new file mode 100644
index 0000000..65a7d15
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/Delta.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaAugmentationInfo.class b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaAugmentationInfo.class
new file mode 100644
index 0000000..dafe19d
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaAugmentationInfo.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractionAnalyzer.class b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractionAnalyzer.class
new file mode 100644
index 0000000..c7fa7f9
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractionAnalyzer.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractor.class b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractor.class
new file mode 100644
index 0000000..bc13fb4
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractor.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractorJSON.class b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractorJSON.class
new file mode 100644
index 0000000..e6da5b6
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractorJSON.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/ExtractedStructure.class b/bin/org/ntlab/traceDebugger/analyzerProvider/ExtractedStructure.class
new file mode 100644
index 0000000..f01bc15
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/ExtractedStructure.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.class b/bin/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.class
new file mode 100644
index 0000000..d425f31
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzerLaunchConfiguration.class b/bin/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzerLaunchConfiguration.class
new file mode 100644
index 0000000..dfe2ec5
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzerLaunchConfiguration.class
Binary files differ
diff --git a/bin/org/ntlab/traceDebugger/analyzerProvider/ReferencePoint.class b/bin/org/ntlab/traceDebugger/analyzerProvider/ReferencePoint.class
new file mode 100644
index 0000000..8c0eb7e
--- /dev/null
+++ b/bin/org/ntlab/traceDebugger/analyzerProvider/ReferencePoint.class
Binary files differ
diff --git a/build.properties b/build.properties
new file mode 100644
index 0000000..6f20375
--- /dev/null
+++ b/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/icons/deltaMarker.png b/icons/deltaMarker.png
new file mode 100644
index 0000000..4be3929
--- /dev/null
+++ b/icons/deltaMarker.png
Binary files differ
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..f3e94ef
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/ntlab/traceDebugger/BreakPointLabelProvider.java b/src/org/ntlab/traceDebugger/BreakPointLabelProvider.java
new file mode 100644
index 0000000..92bd644
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/BreakPointLabelProvider.java
@@ -0,0 +1,36 @@
+package org.ntlab.traceDebugger;
+
+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;
+
+public class BreakPointLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ if (element instanceof TraceBreakPoint) {
+ TraceBreakPoint tbp = (TraceBreakPoint)element;
+ switch (columnIndex) {
+ case 0:
+ return tbp.isAvailable() ? "True" : "False";
+ case 1:
+ return String.valueOf(tbp.getLineNo());
+ case 2:
+ return tbp.getMethodSignature();
+ }
+ }
+ 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/src/org/ntlab/traceDebugger/BreakPointView.java b/src/org/ntlab/traceDebugger/BreakPointView.java
new file mode 100644
index 0000000..89c5f79
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/BreakPointView.java
@@ -0,0 +1,294 @@
+package org.ntlab.traceDebugger;
+
+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.resource.ImageDescriptor;
+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.Shell;
+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.traceAnalysisPlatform.tracer.trace.MethodExecution;
+
+public class BreakPointView extends ViewPart {
+ private TableViewer viewer;
+ private IAction fileOpenAction;
+ private IAction addTraceBreakPointAction;
+ private IAction removeTraceBreakPointAction;
+ private IAction changeAvailableAction;
+ private IAction debugAction;
+ private IAction terminateAction;
+ private IAction stepIntoAction;
+ private IAction stepOverAction;
+ private IAction stepReturnAction;
+ private IAction resumeAction;
+ private IAction stepBackIntoAction;
+ private IAction stepBackOverAction;
+ private IAction stepBackReturnAction;
+ private IAction backResumeAction;
+ private IAction tmpAction;
+ private Shell shell;
+ private DebuggingController debuggingController = new DebuggingController();
+ public static final String ID = "org.ntlab.traceDebugger.breakPointView";
+
+ public BreakPointView() {
+ // TODO Auto-generated constructor stub
+ System.out.println("BreakPointView�N���X���������ꂽ��!");
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ // TODO Auto-generated method stub
+ System.out.println("BreakPointView#createPartControl(Composite)���Ăꂽ��!");
+ shell = parent.getShell();
+ viewer = new TableViewer(parent, SWT.FULL_SELECTION);
+ Table table = viewer.getTable();
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ // �e�[�u���̃J�������쐬
+ String[] tableColumnTexts = {"Available", "Line No", "Signature"};
+ int[] tableColumnWidth = {80, 80, 200};
+ 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 BreakPointLabelProvider());
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection sel = (IStructuredSelection)event.getSelection();
+ Object element = sel.getFirstElement();
+ if (element instanceof TraceBreakPoint) {
+ TraceBreakPoint tbp = (TraceBreakPoint)element;
+ debuggingController.setSelectedTraceBreakPoint(tbp);
+
+ // �I������TraceBreakPoint�̏ꏊ���J���Ĕ��]�\������ (������������?)
+ MethodExecution methodExecution = tbp.getMethodExecutions().iterator().next();
+ int highlightLineNo = tbp.getLineNo();
+ JavaEditorOperator.openSrcFileOfMethodExecution(methodExecution, highlightLineNo);
+ }
+ }
+ });
+
+ createActions();
+ createToolBar();
+ createMenuBar();
+ createPopupMenu();
+ }
+
+ @Override
+ public void setFocus() {
+ // TODO Auto-generated method stub
+ viewer.getControl().setFocus();
+ }
+
+ private void createActions() {
+ ImageDescriptor fileOpenIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
+ fileOpenAction = new Action("Open Trace File...", fileOpenIcon) {
+ @Override
+ public void run() {
+ // �g���[�X�o�͐�Q�ƃE�B�U�[�h
+ debuggingController.fileOpenAction(shell);
+ }
+ };
+
+ addTraceBreakPointAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.addTraceBreakPointAction();
+ }
+ };
+ addTraceBreakPointAction.setText("Add new trace breakpoint");
+ addTraceBreakPointAction.setToolTipText("Add new trace breakpoint");
+
+ removeTraceBreakPointAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.removeTraceBreakPointAction();
+ }
+ };
+ removeTraceBreakPointAction.setText("Remove selected trace breakpoint");
+ removeTraceBreakPointAction.setToolTipText("Remove selected trace breakpoint");
+
+ changeAvailableAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.changeAvailableAction();
+ }
+ };
+ changeAvailableAction.setText("Change available of selected trace breakpoint");
+ changeAvailableAction.setToolTipText("Change available of selected trace breakpoint");
+
+ debugAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.debugAction();
+ }
+ };
+ debugAction.setText("Debug");
+ debugAction.setToolTipText("Debug");
+
+ terminateAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.terminateAction();
+ }
+ };
+ terminateAction.setText("Terminate");
+ terminateAction.setToolTipText("Terminate");
+
+ stepIntoAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.stepIntoAction();
+ }
+ };
+ stepIntoAction.setText("Step Into");
+ stepIntoAction.setToolTipText("Step Into");
+
+ stepOverAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.stepOverAction();
+ }
+ };
+ stepOverAction.setText("Step Over");
+ stepOverAction.setToolTipText("Step Over");
+
+ stepReturnAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.stepReturnAction();
+ }
+ };
+ stepReturnAction.setText("Step Return");
+ stepReturnAction.setToolTipText("Step Return");
+
+ resumeAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.resumeAction();
+ }
+ };
+ resumeAction.setText("Resume");
+ resumeAction.setToolTipText("Resume");
+
+ stepBackIntoAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.stepBackIntoAction();
+ }
+ };
+ stepBackIntoAction.setText("Step Back Into");
+ stepBackIntoAction.setToolTipText("Step Back Into");
+
+ stepBackOverAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.stepBackOverAction();
+ }
+ };
+ stepBackOverAction.setText("Step Back Over");
+ stepBackOverAction.setToolTipText("Step Back Over");
+
+ stepBackReturnAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.stepBackReturnAction();
+ }
+ };
+ stepBackReturnAction.setText("Step Back Return");
+ stepBackReturnAction.setToolTipText("Step Back Return");
+
+ backResumeAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.backResumeAction();
+ }
+ };
+ backResumeAction.setText("Back Resume");
+ backResumeAction.setToolTipText("Back Resume");
+
+ tmpAction = new Action() {
+ @Override
+ public void run() {
+ debuggingController.tmp();
+ }
+ };
+ tmpAction.setText("Tmp");
+ tmpAction.setToolTipText("Tmp");
+ }
+
+ private void createToolBar() {
+ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+ mgr.add(fileOpenAction);
+ mgr.add(debugAction);
+ mgr.add(terminateAction);
+ mgr.add(resumeAction);
+ mgr.add(stepIntoAction);
+ mgr.add(stepOverAction);
+ mgr.add(stepReturnAction);
+ mgr.add(stepBackIntoAction);
+ mgr.add(stepBackOverAction);
+ mgr.add(stepBackReturnAction);
+ mgr.add(backResumeAction);
+ mgr.add(tmpAction);
+ }
+
+ private void createMenuBar() {
+ IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+ mgr.add(fileOpenAction);
+ mgr.add(debugAction);
+ mgr.add(terminateAction);
+ mgr.add(resumeAction);
+ mgr.add(stepIntoAction);
+ mgr.add(stepOverAction);
+ mgr.add(stepReturnAction);
+ mgr.add(stepBackIntoAction);
+ mgr.add(stepBackOverAction);
+ mgr.add(stepBackReturnAction);
+ mgr.add(backResumeAction);
+ mgr.add(tmpAction);
+ }
+
+ private void createPopupMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ manager.add(addTraceBreakPointAction);
+ manager.add(removeTraceBreakPointAction);
+ manager.add(changeAvailableAction);
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ public void update(TraceBreakPoints traceBreakPoints) {
+ viewer.setInput(traceBreakPoints.getAllTraceBreakPoints());
+ viewer.refresh();
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/CallStackLabelProvider.java b/src/org/ntlab/traceDebugger/CallStackLabelProvider.java
new file mode 100644
index 0000000..aa467e8
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/CallStackLabelProvider.java
@@ -0,0 +1,39 @@
+package org.ntlab.traceDebugger;
+
+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.traceAnalysisPlatform.tracer.trace.ThreadInstance;
+
+public class CallStackLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof TreeNode) {
+ Object value = ((TreeNode)element).getValue();
+ if (value instanceof String) {
+ String threadId = (String)value;
+ return "ThreadID: " + threadId;
+ }
+ if (value instanceof CallStackModel) {
+ CallStackModel callStackModel = (CallStackModel)value;
+ StringBuilder text = new StringBuilder();
+ text.append(callStackModel.getCallStackSignature());
+ 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/src/org/ntlab/traceDebugger/CallStackModel.java b/src/org/ntlab/traceDebugger/CallStackModel.java
new file mode 100644
index 0000000..dd056a2
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/CallStackModel.java
@@ -0,0 +1,51 @@
+package org.ntlab.traceDebugger;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class CallStackModel {
+ private TracePoint tracePoint;
+
+ public CallStackModel(TracePoint tracePoint) {
+ this.tracePoint = tracePoint;
+ }
+
+ public TracePoint getTracePoint() {
+ return tracePoint;
+ }
+
+ public MethodExecution getMethodExecution() {
+ return tracePoint.getMethodExecution();
+ }
+
+ public int getCallLineNo() {
+ return tracePoint.getStatement().getLineNo();
+ }
+
+ public String getSignature() {
+ return tracePoint.getMethodExecution().getSignature();
+ }
+
+ public String getCallStackSignature() {
+ String signature = "";
+ signature = getSignature();
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ String objectType = methodExecution.getThisClassName();
+ objectType = objectType.substring(objectType.lastIndexOf(".") + 1);
+ boolean isConstructor = methodExecution.isConstructor();
+ String declaringType = Trace.getDeclaringType(signature, isConstructor);
+ declaringType = declaringType.substring(declaringType.lastIndexOf(".") + 1);
+ String methodName = Trace.getMethodName(signature);
+ String args = "(" + signature.split("\\(")[1];
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(objectType);
+ if (!declaringType.equals(objectType)) {
+ sb.append("(" + declaringType + ")");
+ }
+ sb.append("." + methodName + args);
+ signature = sb.toString();
+ return signature;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/CallStackModels.java b/src/org/ntlab/traceDebugger/CallStackModels.java
new file mode 100644
index 0000000..60a0460
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/CallStackModels.java
@@ -0,0 +1,121 @@
+package org.ntlab.traceDebugger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.TreeNode;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.IStatementVisitor;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ThreadInstance;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class CallStackModels {
+ private String debuggingThreadId = "";
+ private List debuggingThreadCallStacks = new ArrayList<>();
+ private Map> allCallStacks = new HashMap<>();
+
+ public List getDebuggingThreadCallStacks() {
+ return debuggingThreadCallStacks;
+ }
+
+ public TreeNode[] getAllCallStacksTree() {
+ if (allCallStacks.isEmpty()) return new TreeNode[1];
+ TreeNode[] roots = new TreeNode[allCallStacks.size()];
+ int rootIndex = 0;
+ for (String threadId : allCallStacks.keySet()) {
+ TreeNode node = getCallStackModelsTree(threadId);
+ roots[rootIndex++] = node;
+ }
+ return roots;
+ }
+
+ public TreeNode getCallStackModelsTree(String threadId) {
+ List callStackModelsInThread = allCallStacks.get(threadId);
+ if (callStackModelsInThread.isEmpty()) return null;
+ TreeNode root = new TreeNode(threadId);
+ TreeNode parentNode = root;
+ TreeNode[] childrenNode = new TreeNode[callStackModelsInThread.size()];
+ parentNode.setChildren(childrenNode);
+ for (int i = 0; i < callStackModelsInThread.size(); i++) {
+ TreeNode childNode = new TreeNode(callStackModelsInThread.get(i));
+ childNode.setParent(parentNode);
+ childrenNode[i] = childNode;
+ }
+ return root;
+ }
+
+ public TreeNode[] getDebugingThreadCallStacksTree() {
+ TreeNode[] roots = new TreeNode[1];
+ roots[0] = getCallStackModelsTree(debuggingThreadId);
+ return roots;
+ }
+
+ public void reset() {
+ debuggingThreadId = "";
+ debuggingThreadCallStacks.clear();
+ allCallStacks.clear();
+ }
+
+ public void updateByTracePoint(TracePoint tp) {
+ if (tp == null) return;
+ int lineNo = tp.getStatement().getLineNo();
+ updateInAllThreads(tp, lineNo);
+ }
+
+ private void updateInAllThreads(TracePoint tp, int topMethodCallLineNo) {
+ Statement tpStatement = tp.getStatement();
+ reset();
+ debuggingThreadId = tpStatement.getThreadNo();
+ debuggingThreadCallStacks = update(tp);
+ allCallStacks.put(debuggingThreadId, debuggingThreadCallStacks);
+ IStatementVisitor visitor = new CallStackVisitor(tp);
+// updateOtherThreadCallStacks(visitor);
+ }
+
+ private List update(TracePoint tp) {
+ List list = new ArrayList<>();
+ TracePoint tmpTp = tp;
+ while (tmpTp != null) {
+ CallStackModel callStackModel = new CallStackModel(tmpTp);
+ list.add(callStackModel);
+ tmpTp = tmpTp.getMethodExecution().getCallerTracePoint();
+ }
+ return list;
+ }
+
+ private void updateOtherThreadCallStacks(IStatementVisitor visitor) {
+ TraceJSON traceJSON = (TraceJSON)TraceDebuggerPlugin.getAnalyzer().getTrace();
+ Map allThreads = traceJSON.getAllThreads();
+ for (String threadId : allThreads.keySet()) {
+ if (threadId.equals(debuggingThreadId)) continue;
+ TracePoint[] start = new TracePoint[1];
+ start[0] = allThreads.get(threadId).getCurrentTracePoint();
+ traceJSON.getLastStatementInThread(threadId, start, visitor);
+ TracePoint resultTp = start[0];
+ allCallStacks.put(threadId, update(resultTp));
+ }
+ }
+
+// public IStatementVisitor tmp(TracePoint tp) {
+//// return new CallStackVisitor(tp);
+// try {
+// Class> classClass = Class.forName("java.lang.Class");
+// Class>[] classClassArray = (Class[])Array.newInstance(classClass, 1);
+// Class> tpClass = tp.getClass();
+// Array.set(classClassArray, 0, tpClass);
+// Class> visitorClass = Class.forName("org.ntlab.reverseDebugger.CallStackVisitor");
+// Constructor> constructor = visitorClass.getConstructor(classClassArray);
+// Class>[] tpClassArray = (Class[])Array.newInstance(tpClass, 1);
+// Array.set(tpClassArray, 0, tp);
+// IStatementVisitor visitor = (IStatementVisitor)constructor.newInstance(tpClassArray);
+// return visitor;
+// } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
+// | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+// e.printStackTrace();
+// }
+// return null;
+// }
+}
diff --git a/src/org/ntlab/traceDebugger/CallStackView.java b/src/org/ntlab/traceDebugger/CallStackView.java
new file mode 100644
index 0000000..a55bd45
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/CallStackView.java
@@ -0,0 +1,124 @@
+package org.ntlab.traceDebugger;
+
+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.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class CallStackView extends ViewPart {
+ private TreeViewer viewer;
+ private IAction refreshAction;
+ private CallStackModels callStackModels = new CallStackModels();
+ public static final String ID = "org.ntlab.traceDebugger.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());
+ viewer.expandAll();
+
+ // �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) {
+ CallStackModel callStackModel = (CallStackModel)value;
+ MethodExecution methodExecution = callStackModel.getMethodExecution();
+ TracePoint tp = callStackModel.getTracePoint();
+ JavaEditorOperator.openSrcFileOfMethodExecution(methodExecution, callStackModel.getCallLineNo());
+ ((VariableView)getOtherView(VariableView.ID)).updateVariablesByTracePoint(tp, false);
+ }
+ }
+ }
+ });
+ 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 void updateByTracePoint(TracePoint tp) {
+ callStackModels.updateByTracePoint(tp);
+ }
+
+ public void refresh() {
+ TreeNode[] nodes = callStackModels.getAllCallStacksTree();
+ if (nodes == null || nodes[0] == null) {
+ viewer.setInput(null);
+ viewer.expandAll();
+ return;
+ }
+ viewer.setInput(nodes);
+ viewer.expandAll();
+ }
+
+ public void reset() {
+ callStackModels.reset();
+// viewer.setInput(null);
+// viewer.expandAll();
+ refresh();
+ }
+
+ private IViewPart getOtherView(String viewId) {
+ IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ return workbenchPage.showView(viewId);
+ } catch (PartInitException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/CallStackVisitor.java b/src/org/ntlab/traceDebugger/CallStackVisitor.java
new file mode 100644
index 0000000..9fcbf70
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/CallStackVisitor.java
@@ -0,0 +1,32 @@
+package org.ntlab.traceDebugger;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.IStatementVisitor;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class CallStackVisitor implements IStatementVisitor {
+ private TracePoint before = null;
+
+ public CallStackVisitor() {
+
+ }
+
+ public CallStackVisitor(TracePoint before) {
+ this.before = before;
+ }
+
+ @Override
+ public boolean preVisitStatement(Statement statement) {
+ System.out.println("CallStackVisitor#preVisitStatement(Statement)");
+ if (!(statement instanceof MethodInvocation)) return false;
+ if (before == null) return true;
+ MethodInvocation mi = (MethodInvocation)statement;
+ return (mi.getTimeStamp() < before.getStatement().getTimeStamp());
+ }
+
+ @Override
+ public boolean postVisitStatement(Statement statement) {
+ return false;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/DebuggingController.java b/src/org/ntlab/traceDebugger/DebuggingController.java
new file mode 100644
index 0000000..5c0ce48
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/DebuggingController.java
@@ -0,0 +1,278 @@
+package org.ntlab.traceDebugger;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+import org.ntlab.traceDebugger.analyzerProvider.DeltaExtractionAnalyzer;
+import org.ntlab.traceDebugger.analyzerProvider.ReferencePoint;
+
+public class DebuggingController {
+ private TracePoint debuggingTp;
+ private TraceBreakPoint selectedTraceBreakPoint;
+ private TraceBreakPoints traceBreakPoints = new TraceBreakPoints();
+
+ public void setDebuggingTp(TracePoint tp) {
+ this.debuggingTp = tp;
+ }
+
+ public void setSelectedTraceBreakPoint(TraceBreakPoint tbp) {
+ this.selectedTraceBreakPoint = tbp;
+ }
+
+ public boolean fileOpenAction(Shell shell) {
+ FileDialog fileDialog = new FileDialog(shell, SWT.OPEN);
+ fileDialog.setText("Open Trace File");
+ fileDialog.setFilterExtensions(new String[]{"*.*"});
+ String path = fileDialog.open();
+ if (path == null) return false;
+ TraceDebuggerPlugin.setAnalyzer(new DeltaExtractionAnalyzer(new TraceJSON(path)));
+ traceBreakPoints.clear();
+ ((CallStackView)getOtherView(CallStackView.ID)).reset();
+ ((VariableView)getOtherView(VariableView.ID)).reset();
+ ((BreakPointView)getOtherView(BreakPointView.ID)).update(traceBreakPoints);
+ return true;
+ }
+
+ public boolean addTraceBreakPointAction() {
+ if (TraceDebuggerPlugin.getAnalyzer() == null) {
+ MessageDialog.openInformation(null, "Error", "Trace file was not found");
+ return false;
+ }
+// InputDialog inputDialog = new InputDialog(null, "method signature dialog", "Input method signature", "void Company.pay(Money,Person)", null);
+// InputDialog inputDialog = new InputDialog(null, "method signature dialog", "Input method signature", "void worstCase.P.setM(worstCase.M)", null);
+ InputDialog inputDialog = new InputDialog(null, "method signature dialog", "Input method signature", "public void org.jhotdraw.draw.DefaultDrawingView.addToSelection(org.jhotdraw.draw.Figure)", null);
+ if (inputDialog.open() != InputDialog.OK) return false;
+ String methodSignature = inputDialog.getValue();
+ inputDialog = new InputDialog(null, "line No dialog", "Input line no", "", null);
+ if (inputDialog.open() != InputDialog.OK) return false;
+ int lineNo = Integer.parseInt(inputDialog.getValue());
+ long currentTime = 0L;
+ if (debuggingTp != null) {
+ currentTime = debuggingTp.getStatement().getTimeStamp();
+ }
+ boolean isSuccess = traceBreakPoints.addTraceBreakPoint(methodSignature, lineNo, currentTime);
+ if (!isSuccess) {
+ MessageDialog.openInformation(null, "Error", "This trace point does not exist in the trace.");
+ return false;
+ }
+ ((BreakPointView)getOtherView(BreakPointView.ID)).update(traceBreakPoints);
+ return true;
+ }
+
+ public boolean removeTraceBreakPointAction() {
+ if (selectedTraceBreakPoint == null) return false;
+ traceBreakPoints.removeTraceBreakPoint(selectedTraceBreakPoint);
+ ((BreakPointView)getOtherView(BreakPointView.ID)).update(traceBreakPoints);
+ return true;
+ }
+
+ public boolean changeAvailableAction() {
+ if (selectedTraceBreakPoint == null) return false;
+ selectedTraceBreakPoint.changeAvailable();
+ ((BreakPointView)getOtherView(BreakPointView.ID)).update(traceBreakPoints);
+ return true;
+ }
+
+// public boolean debugAction() {
+// if (TraceDebuggerPlugin.getAnalyzer() == null) {
+// MessageDialog.openInformation(null, "Error", "Trace file was not found");
+// return false;
+// }
+// terminateAction();
+// traceBreakPoints.resetAll();
+// debuggingTp = traceBreakPoints.getNextTracePoint(0L);
+// if (debuggingTp == null) return false;
+// refresh(false);
+// return true;
+// }
+
+ public boolean debugAction() {
+ if (TraceDebuggerPlugin.getAnalyzer() == null) {
+ MessageDialog.openInformation(null, "Error", "Trace file was not found");
+ return false;
+ }
+ terminateAction();
+// traceBreakPoints.resetAll();
+ traceBreakPoints.reset();
+// debuggingTp = traceBreakPoints.getNextTracePoint(0L);
+ debuggingTp = traceBreakPoints.getFirstTracePoint();
+ if (debuggingTp == null) return false;
+ refresh(false);
+ return true;
+ }
+
+ public void terminateAction() {
+ debuggingTp = null;
+ ((CallStackView)getOtherView(CallStackView.ID)).reset();
+ ((VariableView)getOtherView(VariableView.ID)).reset();
+ }
+
+ public boolean stepIntoAction() {
+ if (debuggingTp == null) return false;
+ debuggingTp = debuggingTp.duplicate();
+ debuggingTp.stepFull();
+ if (!debuggingTp.isValid()) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.forwardAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(false);
+ return true;
+ }
+
+ public boolean stepOverAction() {
+ if (debuggingTp == null) return false;
+ debuggingTp = debuggingTp.duplicate();
+ int currentLineNo = debuggingTp.getStatement().getLineNo();
+ boolean isReturned;
+ while (!(isReturned = !(debuggingTp.stepOver()))) {
+ if (currentLineNo != debuggingTp.getStatement().getLineNo()) break;
+ }
+ if (!debuggingTp.isValid()) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.forwardAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(isReturned);
+ return true;
+ }
+
+ public boolean stepReturnAction() {
+ if (debuggingTp == null) return false;
+ debuggingTp = debuggingTp.duplicate();
+ while (debuggingTp.stepOver());
+ if (!debuggingTp.isValid()) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.forwardAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(true);
+ return true;
+ }
+
+ public boolean resumeAction() {
+ if (debuggingTp == null) return false;
+ long currentTime = debuggingTp.getStatement().getTimeStamp();
+ debuggingTp = traceBreakPoints.getNextTracePoint(currentTime);
+ if (debuggingTp == null) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.forwardAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(false);
+ return true;
+ }
+
+ public boolean stepBackIntoAction() {
+ if (debuggingTp == null) return false;
+ debuggingTp = debuggingTp.duplicate();
+ debuggingTp.stepBackFull();
+ if (!debuggingTp.isValid()) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.reverseAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(true);
+ return true;
+ }
+
+ public boolean stepBackOverAction() {
+ if (debuggingTp == null) return false;
+ debuggingTp = debuggingTp.duplicate();
+ int currentLineNo = debuggingTp.getStatement().getLineNo();
+ boolean isReturned;
+ while (!(isReturned = !debuggingTp.stepBackOver())) {
+ if (currentLineNo != debuggingTp.getStatement().getLineNo()) break;
+ }
+ if (!debuggingTp.isValid()) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.reverseAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(!isReturned);
+ return true;
+ }
+
+ public boolean stepBackReturnAction() {
+ if (debuggingTp == null) return false;
+ debuggingTp = debuggingTp.duplicate();
+ while (debuggingTp.stepBackOver());
+ if (!debuggingTp.isValid()) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.reverseAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(false);
+ return true;
+ }
+
+ public boolean backResumeAction() {
+ if (debuggingTp == null) return false;
+ long currentTime = debuggingTp.getStatement().getTimeStamp();
+ debuggingTp = traceBreakPoints.getPreviousTracePoint(currentTime);
+ if (debuggingTp == null) {
+ terminateAction();
+ MessageDialog.openInformation(null, "Terminate", "This trace is terminated");
+ return false;
+ }
+// traceBreakPoints.reverseAll(debuggingTp.getStatement().getTimeStamp());
+ refresh(false);
+ return true;
+ }
+
+ /**
+ * ���݂̃f�o�b�O�ʒu�𒊏o�����f���^�̒�ӂ̃g���[�X�|�C���g�ɍ��킹�� (�Ƃ肠�����m�F���邾���p)
+ * @return
+ */
+ public boolean tmp() {
+ DeltaExtractionAnalyzer analyzer = (DeltaExtractionAnalyzer)TraceDebuggerPlugin.getAnalyzer();
+ ReferencePoint rp = analyzer.getBottomPoint();
+ long previousTime = debuggingTp.getStatement().getTimeStamp();
+ long rpTime = rp.getTime();
+ debuggingTp = rp.getTracePoint();
+// if (rpTime < previousTime) {
+// traceBreakPoints.reverseAll(rpTime);
+// } else {
+// traceBreakPoints.forwardAll(rpTime);
+// }
+ refresh(false);
+ return true;
+ }
+
+ private void refresh(boolean isReturned) {
+ MethodExecution me = debuggingTp.getMethodExecution();
+ int lineNo = debuggingTp.getStatement().getLineNo();
+ JavaEditorOperator.openSrcFileOfMethodExecution(me, lineNo);
+ CallStackView callStackView = ((CallStackView)getOtherView(CallStackView.ID));
+ callStackView.updateByTracePoint(debuggingTp);
+ callStackView.refresh();
+ ((VariableView)getOtherView(VariableView.ID)).updateVariablesByTracePoint(debuggingTp, isReturned);
+ ((BreakPointView)getOtherView(BreakPointView.ID)).update(traceBreakPoints);
+ }
+
+ private IViewPart getOtherView(String viewId) {
+ IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ return workbenchPage.showView(viewId);
+ } catch (PartInitException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/JavaEditorOperator.java b/src/org/ntlab/traceDebugger/JavaEditorOperator.java
new file mode 100644
index 0000000..0e5ade2
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/JavaEditorOperator.java
@@ -0,0 +1,336 @@
+package org.ntlab.traceDebugger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+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.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ClassInfo;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceDebugger.analyzerProvider.Alias;
+
+public class JavaEditorOperator {
+ private static List markers = new ArrayList<>();
+
+ public static void openSrcFileOfAlias(Alias alias) {
+ MethodExecution methodExecution = alias.getMethodExecution();
+ int lineNo = alias.getLineNo();
+ openSrcFileOfMethodExecution(methodExecution, lineNo);
+ }
+
+ /**
+ * �����œn����meCaller���ɂ���methodExecution����`����Ă���N���X�̃\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������
+ *
+ * @param methodExecution
+ */
+ public static void openSrcFileOfMethodExecution(MethodExecution methodExecution, int highlightLineNo) {
+ IType type = findIType(methodExecution);
+ if (type != null) {
+ IMethod method = findIMethod(methodExecution, type);
+ openSrcFile(type, method);
+ highlightCurrentJavaFile(highlightLineNo);
+ }
+ }
+
+ /**
+ * �����œn����IType��IMethod�ɑΉ�����\�[�X�R�[�h��Ώ�Eclipse�̃G�f�B�^�ŊJ������
+ *
+ * @param type
+ * @param method
+ */
+ private static void openSrcFile(IType type, IMethod method) {
+ openInJavaEditor(type, method);
+ }
+
+ /**
+ * ���݃G�f�B�^�ŊJ����Ă���t�@�C���̎w�肵���s�Ƀn�C���C�g��������
+ * @param lineNo �n�C���C�g��������s��
+ */
+ public static void highlightCurrentJavaFile(int lineNo) {
+ if (lineNo < 1) return;
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ IEditorPart editorPart = window.getActivePage().getActiveEditor();
+ if (editorPart instanceof ITextEditor) {
+ ITextEditor editor = (ITextEditor)editorPart;
+ IDocumentProvider provider = editor.getDocumentProvider();
+ IDocument document = provider.getDocument(editor.getEditorInput());
+ try {
+ editor.selectAndReveal(document.getLineOffset(lineNo - 1), document.getLineLength(lineNo - 1));
+// tmp();
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void markAndOpenJavaFile(MethodExecution methodExecution, int lineNo, String message, String markerId) {
+ IFile file = findIFile(methodExecution);
+ try {
+ FileEditorInput input = new FileEditorInput(file);
+ FileDocumentProvider provider = new FileDocumentProvider();
+ provider.connect(input);
+ IDocument document = provider.getDocument(input);
+ IMarker marker = file.createMarker(markerId);
+ Map attributes = new HashMap<>();
+ attributes.put(IMarker.MESSAGE, message);
+ attributes.put(IMarker.TRANSIENT, true);
+ if (lineNo > 1) {
+ IRegion r = document.getLineInformation(lineNo - 1);
+ attributes.put(IMarker.LINE_NUMBER, lineNo);
+ attributes.put(IMarker.CHAR_START, r.getOffset());
+ attributes.put(IMarker.CHAR_END, r.getOffset() + r.getLength());
+ }
+ marker.setAttributes(attributes);
+ markers.add(marker);
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IDE.openEditor(page, marker);
+ } catch (CoreException | BadLocationException e) {
+ e.printStackTrace();
+ }
+ }
+
+// private static void tmp() {
+// IBreakpointManager mgr = DebugPlugin.getDefault().getBreakpointManager();
+// IBreakpoint[] bps = mgr.getBreakpoints();
+// for (IBreakpoint bp : bps) {
+// IMarker marker = bp.getMarker();
+// int lineNo = marker.getAttribute(IMarker.LINE_NUMBER, -1);
+// String name = marker.getAttribute("org.eclipse.jdt.debug.core.typeName", "");
+//// TraceJSON trace = (TraceJSON)TraceDebuggerPlugin.getAnalyzer().getTrace();
+//// ClassInfo classInfo = trace.getClassInfo(name);
+//// if (classInfo == null) continue;
+//
+//
+//// name = mgr.getTypeName(bp);
+// try {
+// for (Map.Entry entry: marker.getAttributes().entrySet()) {
+// System.out.println(entry.getKey() + ": " + entry.getValue());
+// }
+// } catch (CoreException e) {
+// e.printStackTrace();
+// }
+// System.out.println("Name: " + name + ", lineNo: " + lineNo);
+// }
+// }
+
+ public static IFile findIFile(MethodExecution methodExecution) {
+ TraceJSON trace = (TraceJSON)TraceDebuggerPlugin.getAnalyzer().getTrace();
+ String declaringClassName = methodExecution.getDeclaringClassName();
+ declaringClassName = declaringClassName.replace(".", "");
+ String tmp = trace.getClassInfo(declaringClassName).getPath();
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ String projectName = "";
+ for (IProject project : projects) {
+ projectName = project.getFullPath().toString();
+ if (tmp.contains(projectName + "/")) break;
+ }
+ tmp = tmp.replace(tmp.substring(0, tmp.lastIndexOf(projectName)), "");
+ tmp = tmp.replace("/bin/", "/src/");
+ tmp = tmp.replace(".class", ".java");
+ String filePath = tmp;
+ IPath path = new Path(filePath);
+ return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ }
+
+ public static void deleteMarkers(String markerId) {
+ Iterator it = markers.iterator();
+ while (it.hasNext()) {
+ IMarker marker = it.next();
+ try {
+ if (marker.getType().equals(markerId)) {
+ marker.delete();
+ it.remove();
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static IType findIType(MethodExecution methodExecution) {
+ String declaringClassName = methodExecution.getDeclaringClassName();
+ declaringClassName = declaringClassName.replace(".", "");
+ return findIType(methodExecution, declaringClassName);
+ }
+
+ public static IType findIType(MethodExecution methodExecution, String declaringClassName) {
+ String projectPath = getLoaderPath(methodExecution, declaringClassName);
+ IType type = null;
+ if (projectPath != null) {
+ IJavaProject javaProject = findJavaProject(projectPath);
+ if (javaProject != null) {
+ try {
+ type = javaProject.findType(declaringClassName);
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return type;
+ }
+
+ private static String getLoaderPath(MethodExecution methodExecution, String declaringClassName) {
+ TraceJSON traceJSON = (TraceJSON)TraceDebuggerPlugin.getAnalyzer().getTrace();
+ ClassInfo classInfo = traceJSON.getClassInfo(declaringClassName);
+ if (classInfo == null && methodExecution != null) {
+ declaringClassName = methodExecution.getThisClassName();
+ classInfo = traceJSON.getClassInfo(declaringClassName);
+ }
+ String loaderPath = null;
+ if (classInfo != null) {
+ // �Ȃ���loaderPath���擾�ł��Ă��Ȃ����߁A���ۂɏo�͂����JSON�g���[�X���Q�l�ɂ���path����^���Ă݂�
+ String path = classInfo.getPath();
+ String declaringClassNameString = declaringClassName.replace(".", "/");
+ loaderPath = path.substring(0, path.lastIndexOf(declaringClassNameString)); // path����N���X�̊��S���薼�ȍ~��S�ĊO�������̂�projectPath�ɂ��Ă݂�
+ }
+ return loaderPath;
+ }
+
+ private static 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 static 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 static void openInJavaEditor(IType type, IMethod method) {
+ try {
+ if (type != null) {
+ IEditorPart editor = JavaUI.openInEditor(type);
+ if (!type.isLocal() && !type.isMember()) {
+ if (method != null) {
+ JavaUI.revealInEditor(editor, (IJavaElement)method);
+ } else {
+ JavaUI.revealInEditor(editor, (IJavaElement)type);
+ }
+ }
+ }
+ } catch (PartInitException | JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static IMethod findIMethod(MethodExecution methodExecution, IType type) {
+ IMethod method = null;
+ if (type != null) {
+ String methodSignature = methodExecution.getSignature();
+ method = findIMethod(type, methodSignature);
+ }
+ return method;
+ }
+
+ public static 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 static 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 static 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/src/org/ntlab/traceDebugger/TraceBreakPoint.java b/src/org/ntlab/traceDebugger/TraceBreakPoint.java
new file mode 100644
index 0000000..720056a
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/TraceBreakPoint.java
@@ -0,0 +1,144 @@
+package org.ntlab.traceDebugger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class TraceBreakPoint {
+ private List tracePoints = new ArrayList<>();
+ private String methodSignature;
+ private int lineNo;
+ private List methodExecutions = new ArrayList<>();
+ private boolean isAvailable = false;
+// private int currentIndex = 0;
+
+ public TraceBreakPoint(String methodSignature, int lineNo, long currentTime) {
+ this.methodSignature = methodSignature;
+ this.lineNo = lineNo;
+ isAvailable = initTracePoints(methodSignature, lineNo);
+// if (isAvailable) forwardIndex(currentTime);
+ }
+
+ private boolean initTracePoints(String methodSignature, int lineNo) {
+ Trace trace = TraceDebuggerPlugin.getAnalyzer().getTrace();
+ methodExecutions = trace.getMethodExecutions(methodSignature);
+ if (methodExecutions.isEmpty()) return false;
+ tracePoints.clear();
+ for (MethodExecution me : methodExecutions) {
+ int order = 0;
+ for (Statement statement : me.getStatements()) {
+ if (statement.getLineNo() == lineNo) {
+ tracePoints.add(me.getTracePoint(order));
+// break;
+ }
+ order++;
+ }
+ }
+ if (tracePoints.isEmpty()) return false;
+ Collections.sort(tracePoints, new Comparator() {
+ @Override
+ public int compare(TracePoint o1, TracePoint o2) {
+ long o1Time = getTime(o1);
+ long o2Time = getTime(o2);
+ return (o1Time < o2Time) ? -1 : 1;
+ }
+
+ private long getTime(TracePoint tp) {
+ Statement statement = tp.getStatement();
+ if (statement instanceof MethodInvocation) {
+ return ((MethodInvocation)statement).getCalledMethodExecution().getEntryTime();
+ }
+ return statement.getTimeStamp();
+ }
+ });
+ return true;
+ }
+
+ public String getMethodSignature() {
+ return methodSignature;
+ }
+
+ public int getLineNo() {
+ return lineNo;
+ }
+
+ public List getMethodExecutions() {
+ return methodExecutions;
+ }
+
+ public List getTracePoints() {
+ return tracePoints;
+ }
+
+
+ public boolean isAvailable() {
+ return isAvailable;
+ }
+
+ public void changeAvailable() {
+ isAvailable = !isAvailable;
+ }
+
+// public void reset() {
+// initTracePoints(methodSignature, lineNo);
+// currentIndex = 0;
+// }
+//
+// public TracePoint peekTracePoint() {
+// if ((currentIndex < 0) || (currentIndex >= tracePoints.size())) return null;
+// return tracePoints.get(currentIndex);
+// }
+//
+// public TracePoint previousTracePoint() {
+// if ((currentIndex - 1 < 0) || (currentIndex - 1 >= tracePoints.size())) return null;
+// return tracePoints.get(currentIndex - 1);
+// }
+//
+// public TracePoint dequeueTracePoint(boolean isForward) {
+// TracePoint result = null;
+// if (isForward) {
+// result = peekTracePoint();
+// currentIndex++;
+// } else {
+// result = previousTracePoint();
+// currentIndex--;
+// }
+// return result;
+// }
+//
+// public void forwardIndex(long currentTime) {
+// int start = currentIndex;
+// for (int i = start; i < tracePoints.size(); i++) {
+// long time = getTime(tracePoints.get(i).getStatement());
+// if (time > currentTime) {
+// currentIndex = i;
+// return;
+// }
+// }
+// currentIndex = tracePoints.size();
+// }
+//
+// public void reverseIndex(long currentTime) {
+// for (int i = tracePoints.size() - 1; i >= 0; i--) {
+// long time = getTime(tracePoints.get(i).getStatement());
+// if (time <= currentTime) {
+// currentIndex = i + 1;
+// return;
+// }
+// }
+// currentIndex = 0;
+// }
+//
+// private long getTime(Statement statement) {
+// if (statement instanceof MethodInvocation) {
+// return ((MethodInvocation)statement).getCalledMethodExecution().getEntryTime();
+// }
+// return statement.getTimeStamp();
+// }
+}
diff --git a/src/org/ntlab/traceDebugger/TraceBreakPoints.java b/src/org/ntlab/traceDebugger/TraceBreakPoints.java
new file mode 100644
index 0000000..0787f1a
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/TraceBreakPoints.java
@@ -0,0 +1,340 @@
+package org.ntlab.traceDebugger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class TraceBreakPoints {
+ private Map> traceBreakPoints = new HashMap<>();
+ private List histories = new LinkedList<>();
+ private ListIterator historyIt = histories.listIterator();
+ private TracePoint curHistPoint;
+ private int curIdx = -1;
+
+ public List getAllTraceBreakPoints() {
+ List list = new ArrayList<>();
+ for (Map innerMap : traceBreakPoints.values()) {
+ list.addAll(innerMap.values());
+ }
+ Collections.sort(list, new Comparator() {
+ @Override
+ public int compare(TraceBreakPoint arg0, TraceBreakPoint arg1) {
+ if (arg0.getMethodSignature().equals(arg1.getMethodSignature())) {
+ return (arg0.getLineNo() < arg1.getLineNo()) ? -1 : 1;
+ }
+ return arg0.getMethodSignature().compareTo(arg1.getMethodSignature());
+ }
+ });
+ return list;
+ }
+
+ public boolean addTraceBreakPoint(String methodSignature, int lineNo, long currentTime) {
+ Map innerMap = traceBreakPoints.get(methodSignature);
+ if (innerMap == null) {
+ innerMap = new HashMap<>();
+ traceBreakPoints.put(methodSignature, innerMap);
+ }
+ TraceBreakPoint tbp = new TraceBreakPoint(methodSignature, lineNo, currentTime);
+ if (!tbp.isAvailable()) return false;
+ innerMap.put(lineNo, tbp);
+ addHistories(tbp);
+ return true;
+ }
+
+ public boolean addTraceBreakPoint(String methodSignature, int lineNo) {
+ return addTraceBreakPoint(methodSignature, lineNo, 0L);
+ }
+
+ public void removeTraceBreakPoint(String methodSignature, int lineNo) {
+ Map innerMap = traceBreakPoints.get(methodSignature);
+ if (innerMap == null) return;
+ TraceBreakPoint tbp = innerMap.remove(lineNo);
+ if (tbp != null) removeHistories(tbp);
+ if (innerMap.isEmpty()) traceBreakPoints.remove(methodSignature);
+ }
+
+ public void removeTraceBreakPoint(TraceBreakPoint traceBreakPoint) {
+ String methodSignature = traceBreakPoint.getMethodSignature();
+ int lineNo = traceBreakPoint.getLineNo();
+ removeTraceBreakPoint(methodSignature, lineNo);
+ }
+
+ private void addHistories(TraceBreakPoint tbp) {
+ ListIterator it = histories.listIterator();
+ Iterator tbpIt = tbp.getTracePoints().iterator();
+ if (!(tbpIt.hasNext())) return;
+ TracePoint addedTp = tbpIt.next();
+ int idx = 0;
+ while (it.hasNext()) {
+ TracePoint tp = it.next();
+ if (getTime(addedTp) < getTime(tp)) {
+ it.previous();
+ it.add(addedTp);
+ if (idx <= curIdx) {
+ curIdx++;
+ }
+ addedTp = null;
+ if (!(tbpIt.hasNext())) break;
+ addedTp = tbpIt.next();
+ }
+ idx++;
+ }
+ if (addedTp != null) {
+ it.add(addedTp);
+ while (tbpIt.hasNext()) {
+ it.add(tbpIt.next());
+ }
+ }
+ historyIt = histories.listIterator(curIdx + 1); // ���Ɏ擾����C���f�b�N�X�ɍ��킹���C�e���[�^���Ď擾
+ confirm();
+ }
+
+ private void removeHistories(TraceBreakPoint tbp) {
+ ListIterator it = histories.listIterator();
+ Iterator tbpIt = tbp.getTracePoints().iterator();
+ if (!(tbpIt.hasNext())) return;
+ TracePoint removedTp = tbpIt.next();
+ int idx = 0;
+ while (it.hasNext()) {
+ TracePoint tp = it.next();
+ if (tp.equals(removedTp)) {
+ it.remove();
+ if (tp.equals(curHistPoint)) {
+ curHistPoint = null; // ���݈ʒu�ɑΉ�����u���[�N�|�C���g���폜���ꂽ�ꍇ�͌��݈ʒu���Ȃ��ɂ���
+ curIdx = -1;
+ } else if (-1 < curIdx && idx <= curIdx) {
+ curIdx--;
+ }
+ if (!(tbpIt.hasNext())) break;
+ removedTp = tbpIt.next();
+ } else {
+ idx++;
+ }
+ }
+ if (curHistPoint == null) {
+ historyIt = null;
+ } else {
+ historyIt = histories.listIterator(curIdx + 1); // ���Ɏ擾����C���f�b�N�X�ɍ��킹���C�e���[�^���Ď擾
+ }
+ confirm();
+ }
+
+ public TracePoint getFirstTracePoint() {
+ return getNextTracePoint(0L);
+ }
+
+ public TracePoint getNextTracePoint(long time) {
+ long curHistTime;
+ if (curHistPoint == null) {
+ curHistTime = 0L;
+ curIdx = -1;
+ historyIt = histories.listIterator();
+ } else {
+ curHistTime = getTime(curHistPoint);
+ }
+ if (curHistTime <= time) {
+ while (historyIt.hasNext()) {
+ TracePoint tp = historyIt.next();
+ if (tp.equals(curHistPoint)) continue;
+ curHistPoint = tp;
+ curIdx++;
+ if (!checkAvailable(curHistPoint)) continue;
+ curHistTime = getTime(curHistPoint);
+ if (curHistTime > time) {
+ confirm();
+ return curHistPoint;
+ }
+ }
+ } else {
+ while (historyIt.hasPrevious()) {
+ TracePoint tp = historyIt.previous();
+ if (tp.equals(curHistPoint)) continue;
+ curIdx--;
+ if (!checkAvailable(tp)) continue;
+ curHistTime = getTime(tp);
+ if (curHistTime <= time) {
+ confirm();
+ return curHistPoint;
+ }
+ curHistPoint = tp;
+ }
+ confirm();
+ return curHistPoint;
+ }
+ confirm();
+ return null;
+ }
+
+ public TracePoint getPreviousTracePoint(long time) {
+ long curHistTime;
+ if (curHistPoint == null) {
+ curHistTime = Long.MAX_VALUE;
+ curIdx = histories.size();
+ historyIt = histories.listIterator(histories.size());
+ } else {
+ curHistTime = getTime(curHistPoint);
+ }
+ if (curHistTime >= time) {
+ while (historyIt.hasPrevious()) {
+ TracePoint tp = historyIt.previous();
+ if (tp.equals(curHistPoint)) continue;
+ curHistPoint = tp;
+ curIdx--;
+ if (!checkAvailable(curHistPoint)) continue;
+ curHistTime = getTime(curHistPoint);
+ if (curHistTime < time) {
+ confirm();
+ return curHistPoint;
+ }
+ }
+ } else {
+ while (historyIt.hasNext()) {
+ TracePoint tp = historyIt.next();
+ if (tp.equals(curHistPoint)) continue;
+ curIdx++;
+ if (!checkAvailable(tp)) continue;
+ curHistTime = getTime(tp);
+ if (curHistTime >= time) {
+ confirm();
+ return curHistPoint;
+ }
+ curHistPoint = tp;
+ }
+ confirm();
+ return curHistPoint;
+ }
+ confirm();
+ return null;
+ }
+
+ private TraceBreakPoint getTraceBreakPoint(TracePoint tp) {
+ String signature = tp.getMethodExecution().getSignature();
+ int lineNo = tp.getStatement().getLineNo();
+ Map innerMap = traceBreakPoints.get(signature);
+ return (innerMap != null) ? innerMap.get(lineNo) : null;
+ }
+
+ private boolean checkAvailable(TracePoint tp) {
+ TraceBreakPoint tbp = getTraceBreakPoint(tp);
+ return (tbp != null) ? tbp.isAvailable() : false;
+ }
+
+ public void reset() {
+ curIdx = -1;
+ historyIt = histories.listIterator();
+ curHistPoint = null;
+ }
+
+ public void clear() {
+ traceBreakPoints.clear();
+ histories.clear();
+ curIdx = -1;
+ historyIt = null;
+ curHistPoint = null;
+ }
+
+ private long getTime(TracePoint tp) {
+ Statement statement = tp.getStatement();
+ if (statement instanceof MethodInvocation) {
+ return ((MethodInvocation)statement).getCalledMethodExecution().getEntryTime();
+ }
+ return statement.getTimeStamp();
+ }
+
+ private void confirm() {
+ System.out.println();
+ if (curHistPoint == null) {
+ System.out.println("cur: " + "Not Exist");
+ } else {
+ System.out.println("cur: " + getTime(curHistPoint));
+ }
+ int idx = 0;
+ for (TracePoint tp : histories) {
+ String signature = tp.getMethodExecution().getSignature();
+ int lineNo = tp.getStatement().getLineNo();
+ long time = getTime(tp);
+ String idxStr = (idx == curIdx) ? "����������" : "";
+ System.out.println(time + " " + signature + " line: " + lineNo + " " + idxStr);
+ idx++;
+ }
+ System.out.println();
+ }
+
+// public TracePoint getNextTracePoint(long currentTime) {
+// TraceBreakPoint resultTbp = null;
+// long resultTpTime = 0L;
+// for (Map innerMap : traceBreakPoints.values()) {
+// for (TraceBreakPoint tbp: innerMap.values()) {
+// if (!tbp.isAvailable()) continue;
+// TracePoint tp = tbp.peekTracePoint();
+// if (tp == null) continue;
+// long tpTime = tp.getStatement().getTimeStamp();
+// if (tpTime <= currentTime) continue;
+// if (resultTbp == null) {
+// resultTbp = tbp;
+// resultTpTime = tp.getStatement().getTimeStamp();
+// } else if (tpTime < resultTpTime) {
+// resultTbp = tbp;
+// resultTpTime = tp.getStatement().getTimeStamp();
+// }
+// }
+// }
+// return (resultTbp != null) ? resultTbp.dequeueTracePoint(true) : null;
+// }
+//
+// public TracePoint getPreviousTracePoint(long currentTime) {
+// TraceBreakPoint resultTbp = null;
+// long resultTpTime = 0L;
+// for (Map innerMap : traceBreakPoints.values()) {
+// for (TraceBreakPoint tbp: innerMap.values()) {
+// if (!tbp.isAvailable()) continue;
+// TracePoint tp = tbp.previousTracePoint();
+// if (tp == null) continue;
+// long tpTime = tp.getStatement().getTimeStamp();
+// if (tpTime >= currentTime) continue;
+// if (resultTbp == null) {
+// resultTbp = tbp;
+// resultTpTime = tp.getStatement().getTimeStamp();
+// } else if (tpTime > resultTpTime) {
+// resultTbp = tbp;
+// resultTpTime = tp.getStatement().getTimeStamp();
+// }
+// }
+// }
+// return (resultTbp != null) ? resultTbp.dequeueTracePoint(false) : null;
+// }
+//
+// public void forwardAll(long currentTime) {
+// for (Map innerMap : traceBreakPoints.values()) {
+// for (TraceBreakPoint tbp : innerMap.values()) {
+// tbp.forwardIndex(currentTime);
+// }
+// }
+// }
+//
+// public void reverseAll(long currentTime) {
+// for (Map innerMap : traceBreakPoints.values()) {
+// for (TraceBreakPoint tbp : innerMap.values()) {
+// tbp.reverseIndex(currentTime);
+// }
+// }
+// }
+//
+// public void resetAll() {
+// for (Map innerMap : traceBreakPoints.values()) {
+// for (TraceBreakPoint tbp : innerMap.values()) {
+// tbp.reset();
+// }
+// }
+// }
+}
diff --git a/src/org/ntlab/traceDebugger/TraceDebuggerPerspective.java b/src/org/ntlab/traceDebugger/TraceDebuggerPerspective.java
new file mode 100644
index 0000000..f96cd55
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/TraceDebuggerPerspective.java
@@ -0,0 +1,26 @@
+package org.ntlab.traceDebugger;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class TraceDebuggerPerspective 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��Ƀu���[�N�|�C���g�̃r���[��z�u
+ IFolderLayout topRight = layout.createFolder("topRight", IPageLayout.RIGHT, 0.5f, "topLeft");
+ topRight.addView(BreakPointView.ID);
+
+ // �E��ɕϐ��̃r���[��z�u
+ IFolderLayout topRight2 = layout.createFolder("topRight2", IPageLayout.RIGHT, 0.5f, "topLeft");
+ topRight2.addView(VariableView.ID);
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/TraceDebuggerPlugin.java b/src/org/ntlab/traceDebugger/TraceDebuggerPlugin.java
new file mode 100644
index 0000000..dd5ad9a
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/TraceDebuggerPlugin.java
@@ -0,0 +1,70 @@
+package org.ntlab.traceDebugger;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.ntlab.traceDebugger.analyzerProvider.AbstractAnalyzer;
+import org.ntlab.traceDebugger.analyzerProvider.ObjectFlowAnalyzer;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class TraceDebuggerPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.ntlab.helloWorld"; //$NON-NLS-1$
+
+// private static ObjectFlowAnalyzer objectFlowAnalyzer;
+ private static AbstractAnalyzer analyzer;
+
+ // The shared instance
+ private static TraceDebuggerPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public TraceDebuggerPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static TraceDebuggerPlugin getDefault() {
+ return plugin;
+ }
+
+// public static ObjectFlowAnalyzer getObjectFlowAnalyzer() {
+// return objectFlowAnalyzer;
+// }
+//
+// public static void setObjectFlowAnalyzer(ObjectFlowAnalyzer objectFlowAnalyzer) {
+// TraceDebuggerPlugin.objectFlowAnalyzer = objectFlowAnalyzer;
+// }
+
+ public static AbstractAnalyzer getAnalyzer() {
+ return analyzer;
+ }
+
+ public static void setAnalyzer(AbstractAnalyzer analyzer) {
+ TraceDebuggerPlugin.analyzer = analyzer;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/Variable.java b/src/org/ntlab/traceDebugger/Variable.java
new file mode 100644
index 0000000..413bf50
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/Variable.java
@@ -0,0 +1,211 @@
+package org.ntlab.traceDebugger;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class Variable {
+ private String variableName;
+ private String className;
+ private String id;
+ private Variable parent;
+ private List children = new ArrayList<>();
+ private String containerClassName;
+ private String containerId;
+ private TracePoint tracePoint;
+ private boolean isReturned;
+ private DeepHierarchy deepHierarchy;
+ private boolean alreadyCreatedChildHierarchy = false;
+ private boolean alreadyCreatedGrandChildHierarchy = false;
+
+ public Variable(String variableName, String containerClassName, String containerId,
+ String className, String id, TracePoint before, boolean isReturned) {
+ this.variableName = variableName;
+ this.containerClassName = containerClassName;
+ this.containerId = containerId;
+ this.className = className;
+ this.id = id;
+ this.tracePoint = before;
+ this.isReturned = isReturned;
+ this.deepHierarchy = checkDeepHierarchy();
+ }
+
+ public String getVariableName() {
+ return variableName;
+ }
+
+ public String getContainerClassName() {
+ return containerClassName;
+ }
+
+ public String getContainerId() {
+ return containerId;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public TracePoint getTracePoint() {
+ return tracePoint;
+ }
+
+ public Variable getParent() {
+ return parent;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ private void addChild(Variable child) {
+ children.add(child);
+ child.parent = this;
+ }
+
+ @Override
+ public String toString() {
+ return variableName + ": " + className + "(" + "id = " + id + ")";
+ }
+
+ /**
+ * ���̃t�B�[���h���Q�ƌ^�I�u�W�F�N�g���z�肵�Ĕ��茋�ʂ�Ԃ�.
+ * (�ϐ��r���[�ɕ\��������f�[�^���ċA�I�ɋ��߂邽�߂�, �Ăяo�����Ŏ��ɂǂ̃��\�b�h���ĂԂ��f����̂ɗ��p)
+ *
+ * @param objData
+ * @return FIELD: �Q�ƌ^�I�u�W�F�N�g�̏ꍇ, ARRAY: �z��̏ꍇ, NONE: ����ȊO�̏ꍇ
+ */
+ private DeepHierarchy checkDeepHierarchy() {
+ // �t�B�[���h��ID��Type���Ȃ��ꍇ��AType(=ActualType)��"---"�̏ꍇ�͉������Ȃ�
+ if (this.getId() == null || this.getId().isEmpty()
+ || this.getClassName() == null || this.getClassName().isEmpty()) {
+ return DeepHierarchy.NONE;
+ }
+ final String NULL_ACTUAL_TYPE = "---"; // �t�B�[���h�ɑ��Ė����I��null����ꂽ�ꍇ��ActualType�̎擾������
+ if (this.getClassName().equals(NULL_ACTUAL_TYPE)) return DeepHierarchy.NONE;
+
+ final String ARRAY_SIGNATURE_HEAD = "["; // �z��̃V�O�l�`���̐擪�́A�z��̎��������� [ ���A�Ȃ�
+ if (this.getClassName().startsWith(ARRAY_SIGNATURE_HEAD)) {
+ // �t�B�[���h��Type���z��^(�@[ �Ŏn�܂�@)�ꍇ (���̔z���e�v�f�ɂ��Ă���Ȃ�f�[�^�擾�������Ăяo��)
+ return DeepHierarchy.ARRAY;
+ } else {
+ String[] primitives = {"byte", "short", "int", "long", "float", "double", "char", "boolean"};
+ if (!Arrays.asList(primitives).contains(this.getClassName())) {
+ // �t�B�[���h��Type���Q�ƌ^(=�I�u�W�F�N�g)�̏ꍇ (���̃I�u�W�F�N�g�������Ă���t�B�[���h�ɂ��Ă���Ȃ�f�[�^�擾�������Ăяo��)
+ return DeepHierarchy.FIELD;
+ }
+ }
+ return DeepHierarchy.NONE;
+ }
+
+ public void createNextHierarchyState() {
+ if (alreadyCreatedGrandChildHierarchy) return;
+ getDeepHierarchyState();
+ for (Variable child : children) {
+ child.getDeepHierarchyState();
+ }
+ alreadyCreatedGrandChildHierarchy = true;
+ }
+
+ private void getDeepHierarchyState() {
+ if (alreadyCreatedChildHierarchy) return;
+ switch (this.deepHierarchy) {
+ case FIELD:
+ getFieldsState();
+ Collections.sort(children, new Comparator() {
+ @Override
+ public int compare(Variable arg0, Variable arg1) {
+ // �ϐ����̏����ɕ��ёւ���
+ return arg0.getVariableName().compareTo(arg1.getVariableName());
+ }
+ });
+ break;
+ case ARRAY:
+ getArrayState();
+ Collections.sort(children, new Comparator() {
+ @Override
+ public int compare(Variable arg0, Variable arg1) {
+ // �z��C���f�b�N�X�̏����ɕ��ёւ���
+ String arg0Name = arg0.variableName;
+ String arg1Name = arg1.variableName;
+ int arg0Index = Integer.parseInt(arg0Name.substring(arg0Name.indexOf("[") + 1, arg0Name.lastIndexOf("]")));
+ int arg1Index = Integer.parseInt(arg1Name.substring(arg0Name.indexOf("[") + 1, arg1Name.lastIndexOf("]")));
+ return (arg0Index < arg1Index) ? -1 : 1;
+ }
+ });
+ break;
+ case NONE:
+ break;
+ }
+ alreadyCreatedChildHierarchy = true;
+ }
+
+ private void getFieldsState() {
+ // �t�B�[���h��ID��Type���擾���ĕ\��
+ TraceJSON trace = (TraceJSON)TraceDebuggerPlugin.getAnalyzer().getTrace();
+ String declaringClassName = className;
+ IType type = JavaEditorOperator.findIType(null, declaringClassName);
+ if (type == null) {
+ System.out.println("IType == null: " + declaringClassName);
+ return;
+ }
+ try {
+ for (IField field : type.getFields()) {
+ if (Flags.isStatic(field.getFlags())) continue;
+ String fieldName = field.getDeclaringType().getElementName() + "." + field.getElementName(); // ���S����N���X��
+ String fullyQualifiedFieldName = field.getDeclaringType().getFullyQualifiedName() + "." + field.getElementName(); // ���S����N���X��
+
+ // ���̃t�B�[���h�ɂ��Ă̍ŐV�̍X�V�����擾(FieldUpdate)
+// FieldUpdate fieldUpdate = trace.getRecentlyFieldUpdate(thisObjData.getId(), fieldName, tp);
+ FieldUpdate fieldUpdate = trace.getFieldUpdate(id, fullyQualifiedFieldName, tracePoint, isReturned);
+
+ // �t�B�[���h��ID��Type���擾(String)
+ String fieldObjId = (fieldUpdate != null) ? fieldUpdate.getValueObjId() : "0";
+ String fieldType = (fieldUpdate != null) ? fieldUpdate.getValueClassName() : "---";
+ Variable fieldData = new Variable(fieldName, className, id, fieldType, fieldObjId, tracePoint, isReturned);
+ this.addChild(fieldData);
+ }
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void getArrayState() {
+ TraceJSON trace = (TraceJSON)TraceDebuggerPlugin.getAnalyzer().getTrace();
+ for (int i = 0;; i++){
+ // ���̔z��v�f�ɂ��Ă̍ŐV�̍X�V�����擾(ArrayUpdate)
+ ArrayUpdate arrayUpdate = trace.getRecentlyArrayUpdate(id, i, tracePoint);
+ if (arrayUpdate == null) {
+ // �z��̃T�C�Y���擾�ł��Ȃ����߁A�C���f�b�N�X���T�C�Y���߂̂Ƃ��Ɋm���ɔ���������@�Ƃ��ĉ�����
+ // �������A�z��v�f�̓r���ɖ���`���������ꍇ�ł��A�����Ă��܂��̂����_
+ break;
+ }
+ String arrayIndexName = this.getVariableName() + "[" + i + "]";
+
+ // �z��v�f��ID��Type���擾(String)
+ String valueObjId = arrayUpdate.getValueObjectId();
+ String valueType = arrayUpdate.getValueClassName();
+ Variable arrayIndexData = new Variable(arrayIndexName, className, id, valueType, valueObjId, tracePoint, isReturned);
+ this.addChild(arrayIndexData);
+ }
+ }
+
+ private enum DeepHierarchy {
+ NONE, FIELD, ARRAY;
+ }
+}
\ No newline at end of file
diff --git a/src/org/ntlab/traceDebugger/VariableLabelProvider.java b/src/org/ntlab/traceDebugger/VariableLabelProvider.java
new file mode 100644
index 0000000..3607ae2
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/VariableLabelProvider.java
@@ -0,0 +1,43 @@
+package org.ntlab.traceDebugger;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+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;
+
+public class VariableLabelProvider extends LabelProvider implements ITableLabelProvider {
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ if (element instanceof TreeNode) {
+ Object value = ((TreeNode)element).getValue();
+ if (value instanceof Variable) {
+ Variable variableData = (Variable)value;
+ switch (columnIndex) {
+ case 0:
+ String variableName = variableData.getVariableName();
+ if (variableName.contains("[")) {
+ return variableName.substring(variableName.lastIndexOf("["));
+ } else if (variableName.contains(".")) {
+ return variableName.substring(variableName.lastIndexOf(".") + 1);
+ }
+ return variableName;
+ case 1:
+ return variableData.getClassName() + " (" + "id = " + variableData.getId() + ")";
+ }
+ }
+ }
+ 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/src/org/ntlab/traceDebugger/VariableView.java b/src/org/ntlab/traceDebugger/VariableView.java
new file mode 100644
index 0000000..d87ba6a
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/VariableView.java
@@ -0,0 +1,184 @@
+package org.ntlab.traceDebugger;
+
+import java.util.List;
+
+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.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.jface.viewers.TreeNodeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+import org.ntlab.traceDebugger.analyzerProvider.AbstractAnalyzer;
+import org.ntlab.traceDebugger.analyzerProvider.DeltaExtractionAnalyzer;
+
+public class VariableView extends ViewPart {
+ private TreeViewer viewer;
+ private IAction deltaAction;
+ private Variable selectedVariable;
+ private Variables variables = Variables.getInstance();
+ public static final String ID = "org.ntlab.traceDebugger.variableView";
+
+ public VariableView() {
+ // TODO Auto-generated constructor stub
+ System.out.println("VariableView�N���X���������ꂽ��!");
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ // TODO Auto-generated method stub
+ System.out.println("VariableView#createPartControl(Composite)���Ăꂽ��!");
+ viewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+ Tree tree = viewer.getTree();
+ tree.setHeaderVisible(true);
+ tree.setLinesVisible(true);
+
+ String[] treeColumnTexts = {"Name", "Value"};
+ int[] treeColumnWidth = {100, 200};
+ TreeColumn[] treeColumns = new TreeColumn[treeColumnTexts.length];
+ for (int i = 0; i < treeColumns.length; i++) {
+ treeColumns[i] = new TreeColumn(tree, SWT.NULL);
+ treeColumns[i].setText(treeColumnTexts[i]);
+ treeColumns[i].setWidth(treeColumnWidth[i]);
+ }
+ viewer.setContentProvider(new TreeNodeContentProvider());
+ viewer.setLabelProvider(new VariableLabelProvider());
+ 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 Variable) {
+ selectedVariable = (Variable)value;
+ }
+ }
+ }
+ });
+ viewer.addTreeListener(new ITreeViewerListener() {
+ @Override
+ public void treeExpanded(TreeExpansionEvent event) {
+ // �c���[���J������Ɏ��s�����B �����ł͊J�����m�[�h����3��̃m�[�h�����Ēlj�����B
+ Object element = event.getElement();
+ if (!(element instanceof TreeNode)) return;
+ TreeNode expandedNode = (TreeNode)element;
+ Object value = expandedNode.getValue();
+ if (!(value instanceof Variable)) return;
+ TreeNode[] childNodes = expandedNode.getChildren();
+ if (childNodes == null) return;
+ for (TreeNode childNode : childNodes) {
+ TreeNode[] grandChildNodes = childNode.getChildren();
+ if (grandChildNodes == null) continue;
+ for (TreeNode grandChildNode : grandChildNodes) {
+ Variable grandChildVariable = (Variable)grandChildNode.getValue();
+ grandChildVariable.createNextHierarchyState();
+ List list = grandChildVariable.getChildren();
+ TreeNode[] nodes = new TreeNode[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ nodes[i] = new TreeNode(list.get(i));
+ }
+ grandChildNode.setChildren(nodes);
+ }
+ }
+ viewer.refresh();
+ }
+
+ @Override
+ public void treeCollapsed(TreeExpansionEvent event) {}
+ });
+ createActions();
+ createToolBar();
+ createMenuBar();
+ createPopupMenu();
+ }
+
+ @Override
+ public void setFocus() {
+ // TODO Auto-generated method stub
+ viewer.getControl().setFocus();
+ }
+
+ private void createActions() {
+ deltaAction = new Action() {
+ @Override
+ public void run() {
+ AbstractAnalyzer analyzer = TraceDebuggerPlugin.getAnalyzer();
+ if (analyzer instanceof DeltaExtractionAnalyzer) {
+ DeltaExtractionAnalyzer deltaAnalyzer = (DeltaExtractionAnalyzer)analyzer;
+ deltaAnalyzer.extractDelta(selectedVariable);
+ }
+ }
+ };
+ deltaAction.setText("Extract Delta");
+ deltaAction.setToolTipText("Extract Delta");
+ }
+
+ private void createToolBar() {
+ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
+ }
+
+ private void createMenuBar() {
+ IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
+ }
+
+ private void createPopupMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ manager.add(deltaAction);
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ public void reset() {
+ variables.resetData();
+ viewer.setInput(variables.getVariablesTreeNodes());
+ viewer.refresh();
+ }
+
+ public void updateVariablesByTracePoint(TracePoint tp, boolean isReturned) {
+ variables.getAllObjectDataByTracePoint(tp, isReturned);
+ viewer.setInput(variables.getVariablesTreeNodes());
+ }
+
+// public void updateVariablesByAlias(Alias alias) {
+// variables.getAllObjectDataByAlias(alias);
+// viewer.setInput(variables.getVariablesTreeNodesList());
+// }
+
+ private IViewPart getOtherView(String viewId) {
+ IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try {
+ return workbenchPage.showView(viewId);
+ } catch (PartInitException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/org/ntlab/traceDebugger/Variables.java b/src/org/ntlab/traceDebugger/Variables.java
new file mode 100644
index 0000000..211ba3e
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/Variables.java
@@ -0,0 +1,118 @@
+package org.ntlab.traceDebugger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.viewers.TreeNode;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ObjectReference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class Variables {
+ private static final Variables theInstance = new Variables();
+ private Variable rootThisObjData;
+ private List argsData = new ArrayList<>();
+ private List allObjData = new ArrayList<>();
+
+ public static Variables getInstance() {
+ return theInstance;
+ }
+
+ public TreeNode[] getVariablesTreeNodes() {
+ TreeNode[] roots = new TreeNode[allObjData.size()];
+ if (allObjData.isEmpty()) {
+ return roots;
+ }
+ for (int i = 0; i < allObjData.size(); i++) {
+ Variable rootVariableData = allObjData.get(i);
+ createVariablesTreeNode(null, roots, i, rootVariableData);
+ }
+ return roots;
+ }
+
+ private void createVariablesTreeNode(TreeNode parentNode, TreeNode[] addingNodes, int index, Variable addingVariableData) {
+ TreeNode newNode = new TreeNode(addingVariableData);
+ newNode.setParent(parentNode);
+ addingNodes[index] = newNode;
+ TreeNode[] childNodes = new TreeNode[addingVariableData.getChildren().size()];
+ addingNodes[index].setChildren(childNodes);
+ for (int i = 0; i < addingVariableData.getChildren().size(); i++) {
+ Variable child = addingVariableData.getChildren().get(i);
+ createVariablesTreeNode(newNode, childNodes, i, child);
+ }
+ }
+
+ public List getAllObjectDataByMethodExecution(MethodExecution methodExecution) {
+ if (methodExecution == null) return new ArrayList<>();
+ List statements = methodExecution.getStatements();
+ int lastOrder = statements.size() - 1;
+ TracePoint tp = methodExecution.getTracePoint(lastOrder);
+ getAllObjectData(methodExecution, tp, false);
+ return allObjData;
+ }
+
+ public List getAllObjectDataByTracePoint(TracePoint tp, boolean isReturned) {
+ MethodExecution methodExecution = tp.getMethodExecution();
+ getAllObjectData(methodExecution, tp, isReturned);
+ return allObjData;
+ }
+
+ public void resetData() {
+ rootThisObjData = null;
+ argsData.clear();
+ allObjData.clear();
+ }
+
+ private void getAllObjectData(MethodExecution methodExecution, TracePoint tp, boolean isReturned) {
+ resetData();
+ getRootThisState(methodExecution, tp, isReturned);
+ getArgsState(methodExecution, tp, isReturned);
+ allObjData.add(rootThisObjData);
+ for (Variable argData : argsData) {
+ allObjData.add(argData);
+ }
+ }
+
+ private void getRootThisState(MethodExecution methodExecution, TracePoint tp, boolean isReturned) {
+ String thisObjId = methodExecution.getThisObjId();
+ String thisClassName = methodExecution.getThisClassName();
+ rootThisObjData = new Variable("this", null, null, thisClassName, thisObjId, tp, isReturned);
+ rootThisObjData.createNextHierarchyState();
+ }
+
+ private void getArgsState(MethodExecution methodExecution, TracePoint tp, boolean isReturned) {
+ // methodExecution������arguments���擾(ArrayList)���A����arguments�̃T�C�Y���擾(int)
+ List args = methodExecution.getArguments();
+ if (args.size() > 0) {
+ IType type = JavaEditorOperator.findIType(methodExecution);
+ String methodSignature = methodExecution.getSignature();
+ IMethod method = JavaEditorOperator.findIMethod(type, methodSignature);
+ String[] argNames = getParameterNames(method); // ������IMethod���牼���������擾����
+ for (int i = 0; i < args.size(); i++) {
+ String argName = (argNames.length == args.size()) ? argNames[i] : "arg" + i; // ���Ȃ��Ƃ������̌����s��v�̂Ƃ��͐����������������Ă��Ȃ�
+ ObjectReference arg = args.get(i);
+ String argId = arg.getId();
+ String argType = arg.getActualType();
+ Variable argData = new Variable(argName, null, null, argType, argId, tp, isReturned);
+ argData.createNextHierarchyState();
+ argsData.add(argData);
+ }
+ }
+ }
+
+ private String[] getParameterNames(IMethod method) {
+ String[] argNames = new String[0];
+ if (method != null) {
+ try {
+ argNames = method.getParameterNames();
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+ return argNames;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/AbstractAnalyzer.java b/src/org/ntlab/traceDebugger/analyzerProvider/AbstractAnalyzer.java
new file mode 100644
index 0000000..8463711
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/AbstractAnalyzer.java
@@ -0,0 +1,15 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+
+public abstract class AbstractAnalyzer {
+ protected Trace trace;
+
+ public AbstractAnalyzer(Trace trace) {
+ this.trace = trace;
+ }
+
+ public Trace getTrace() {
+ return trace;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/Alias.java b/src/org/ntlab/traceDebugger/analyzerProvider/Alias.java
new file mode 100644
index 0000000..370f2e7
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/Alias.java
@@ -0,0 +1,240 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.ArrayList;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayCreate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ObjectReference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+/**
+ * �I�u�W�F�N�g�̎Q�Ə��(�G�C���A�X)��\���N���X
+ * @author Isitani
+ *
+ */
+public class Alias {
+ private String objectId;
+ private TracePoint occurrencePoint; // ���Y�I�u�W�F�N�g�̎Q�Ƃ��s���Ă�����s�ӏ��ɑΉ�����TracePoint
+ /**
+ * ���Y�I�u�W�F�N�g�̎Q�Ƃ�TracePoint�ɂ����Ăǂ��Ɍ���Ă��邩��\��
+ * 0 �t�B�[���h�A�N�Z�X���̃R���e�i �������� ���\�b�h�Ăяo�����̃��V�[�o
+ * 1, 2, 3 �c�c n �t�B�[���h�A�N�Z�X���̃t�B�[���h(1) �������� ���\�b�h�Ăяo������n�Ԗڂ̎����� (1���珇�Ԃ�)
+ * -1 ���\�b�h�Ăяo�����̖߂�l
+ *
+ * ��1: d = a.m(b, c);
+ *
+ * ��1�̎��s���ɂ�����, a�̓��\�b�h�Ăяo���̃��V�[�o�Ȃ̂�0, b�̓��\�b�h�Ăяo����1�Ԗڂ̎������Ȃ̂�1,
+ * c�̓��\�b�h�Ăяo����2�Ԗڂ̎������Ȃ̂�2, a.m(b, c)�̖߂�l��-1 �ƂȂ�.
+ *
+ * ��2: d = a.f;
+ * ��2�̎��s���ɂ�����, a�̓t�B�[���h�̃R���e�i�Ȃ̂�0, b�̓t�B�[���h�Ȃ̂�1 �ƂȂ�.
+ *
+ */
+ private int occurrenceExp;
+ public static final int OCCURRENCE_EXP_CONTAINER = 0;
+ public static final int OCCURRENCE_EXP_RECEIVER = 0;
+ public static final int OCCURRENCE_EXP_FIELD = 1;
+ public static final int OCCURRENCE_EXP_ARRAY = 1;
+ public static final int OCCURRENCE_EXP_FIRST_ARG = 1;
+ public static final int OCCURRENCE_EXP_RETURN = -1;
+
+ private static final String FIELD_ACCESS = "Field Access";
+ private static final String FIELD_UPDATE = "Field Update";
+ private static final String ARRAY_ACCESS = "Array Access";
+ private static final String ARRAY_UPDATE = "Array Update";
+ private static final String ARRAY_CREATE = "Array Create";
+ private static final String METHOD_INVOCATION = "Method Invocation";
+ private static final String CREATION = "Creation";
+
+ public Alias(String objectId, TracePoint occurrencePoint, int occurrenceExp) {
+ this.objectId = objectId;
+ this.occurrencePoint = occurrencePoint;
+ this.occurrenceExp = occurrenceExp;
+ }
+
+ public String getObjectId() {
+ return objectId;
+ }
+
+ public TracePoint getOccurrencePoint() {
+ return occurrencePoint;
+ }
+
+ public int getOccurrenceExp() {
+ return occurrenceExp;
+ }
+
+ public MethodExecution getMethodExecution() {
+ return occurrencePoint.getMethodExecution();
+ }
+
+ public String getMethodExecutionClassName() {
+ MethodExecution methodExecution = occurrencePoint.getMethodExecution();
+ return Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor());
+ }
+
+ public String getSourceFileName() {
+ String methodExecutionClassName = getMethodExecutionClassName();
+ methodExecutionClassName = methodExecutionClassName.replace(".", "");
+ return methodExecutionClassName + ".java";
+ }
+
+ public String getMethodSignature() {
+ return occurrencePoint.getMethodExecution().getCallerSideSignature();
+ }
+
+ public int getLineNo() {
+ Statement statement = occurrencePoint.getStatement();
+ return statement.getLineNo();
+ }
+
+ public String getStatementType() {
+ Statement statement = occurrencePoint.getStatement();
+ String statementType = "";
+ if (statement instanceof FieldAccess) {
+ statementType = FIELD_ACCESS;
+ } else if (statement instanceof FieldUpdate) {
+ statementType = FIELD_UPDATE;
+ } else if (statement instanceof ArrayAccess) {
+ statementType = ARRAY_ACCESS;
+ } else if (statement instanceof ArrayUpdate) {
+ statementType = ARRAY_UPDATE;
+ } else if (statement instanceof ArrayCreate) {
+ statementType = ARRAY_CREATE;
+ } else if (statement instanceof MethodInvocation) {
+ MethodInvocation mi = (MethodInvocation)statement;
+ if (mi.getCalledMethodExecution().isConstructor()) {
+ statementType = CREATION;
+ } else {
+ statementType = METHOD_INVOCATION;
+ }
+ }
+ return statementType;
+ }
+
+ public String getStatementSignature() {
+ Statement statement = occurrencePoint.getStatement();
+ String statementSignature = "";
+ if (statement instanceof FieldAccess) {
+ FieldAccess fa = (FieldAccess)statement;
+ statementSignature = fa.getFieldName();
+ } else if (statement instanceof FieldUpdate) {
+ FieldUpdate fu = (FieldUpdate)statement;
+ statementSignature = fu.getFieldName();
+ } else if (statement instanceof ArrayAccess) {
+ ArrayAccess aa = (ArrayAccess)statement;
+ statementSignature = aa.getArrayClassName() + "[" + aa.getIndex() + "]";
+ } else if (statement instanceof ArrayUpdate) {
+ ArrayUpdate au = (ArrayUpdate)statement;
+ statementSignature = au.getArrayClassName() + "[" + au.getIndex() + "]";
+ } else if (statement instanceof ArrayCreate) {
+ ArrayCreate ac = (ArrayCreate)statement;
+ statementSignature = ac.getArrayClassName();
+ } else if (statement instanceof MethodInvocation) {
+ MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution();
+ statementSignature = me.getCallerSideSignature();
+ }
+ return statementSignature;
+ }
+
+ public String getClassName() {
+ Statement statement = occurrencePoint.getStatement();
+ String className = "";
+ if (statement instanceof FieldAccess) {
+ if (occurrenceExp == OCCURRENCE_EXP_CONTAINER) {
+ className = ((FieldAccess) statement).getContainerClassName();
+ } else if (occurrenceExp == OCCURRENCE_EXP_FIELD) {
+ className = ((FieldAccess) statement).getValueClassName();
+ }
+ } else if (statement instanceof FieldUpdate) {
+ if (occurrenceExp == OCCURRENCE_EXP_CONTAINER) {
+ className = ((FieldUpdate) statement).getContainerClassName();
+ } else if (occurrenceExp == OCCURRENCE_EXP_FIELD) {
+ className = ((FieldUpdate) statement).getValueClassName();
+ }
+ } else if (statement instanceof ArrayAccess) {
+ className = ((ArrayAccess) statement).getValueClassName();
+ } else if (statement instanceof ArrayUpdate) {
+ className = ((ArrayUpdate) statement).getValueClassName();
+ } else if (statement instanceof ArrayCreate) {
+ className = ((ArrayCreate) statement).getArrayClassName();
+ } else if (statement instanceof MethodInvocation) {
+ MethodExecution me = ((MethodInvocation)statement).getCalledMethodExecution();
+ if (occurrenceExp == OCCURRENCE_EXP_RETURN) {
+ className = me.getReturnValue().getActualType();
+ } else if (occurrenceExp == OCCURRENCE_EXP_RECEIVER) {
+ className = me.getThisClassName();
+ } else {
+ int index = occurrenceExp - OCCURRENCE_EXP_FIRST_ARG;
+ ArrayList args = me.getArguments();
+ if (index >= 0 && index < args.size()) {
+ className = me.getArguments().get(index).getActualType();
+ }
+ }
+ }
+ return className;
+ }
+
+ public String getOccurrenceText() {
+ String statementType = getStatementType();
+ switch (statementType) {
+ case FIELD_ACCESS:
+ case FIELD_UPDATE:
+ return (occurrenceExp == OCCURRENCE_EXP_CONTAINER) ? "Container" : "Field";
+ case ARRAY_ACCESS:
+ case ARRAY_UPDATE:
+ return (occurrenceExp == OCCURRENCE_EXP_CONTAINER) ? "Array Object" : "Array Value";
+ case ARRAY_CREATE:
+ return "New Array";
+ case METHOD_INVOCATION:
+ if (occurrenceExp <= 0) {
+ return (occurrenceExp == OCCURRENCE_EXP_RECEIVER) ? "Receiver" : "Return Value";
+ }
+ final String[] ORDER_TEXT = {"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th"}; // 0-13�ɑΉ�
+ if (occurrenceExp % 100 >= ORDER_TEXT.length) {
+ return occurrenceExp + ORDER_TEXT[occurrenceExp % 10] + " arg"; // ��2����14�ȏ�Ȃ�, ��1���̐����ɑΉ�������
+ } else if (occurrenceExp % 100 >= 0) {
+ return occurrenceExp + ORDER_TEXT[occurrenceExp % 100] + " arg"; // ��2����0�ȏ�13�ȉ��Ȃ�, ��2���̐����ɑΉ�������
+ }
+ case CREATION:
+ return "New Object";
+ }
+ return String.valueOf(occurrenceExp);
+ }
+
+ public boolean isOrigin() {
+ Statement statement = occurrencePoint.getStatement();
+ if (statement instanceof MethodInvocation) {
+ MethodExecution calledMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ return calledMethodExecution.isConstructor();
+ } else if (statement instanceof ArrayCreate) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ Statement statement = occurrencePoint.getStatement();
+ String className = getClassName();
+ String methodSignature = getMethodSignature();
+ String statementType = getStatementType();
+ String statementSigunarure = getStatementSignature();
+ String indent = " ";
+ StringBuilder str = new StringBuilder();
+ str.append("objId: " + objectId + " (class = " + className + ")" + "\n");
+ str.append("tp: " + occurrencePoint + "\n");
+ str.append(indent + "signature: " + methodSignature + "\n");
+ str.append(indent + "lineNo: " + statement.getLineNo() + "\n");
+ str.append(indent + "statementType: " + statementType + " -> " + statementSigunarure + "\n");
+ str.append("occurrenceExp: " + occurrenceExp + "\n");
+ return str.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/Delta.java b/src/org/ntlab/traceDebugger/analyzerProvider/Delta.java
new file mode 100644
index 0000000..47f52f1
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/Delta.java
@@ -0,0 +1,28 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.ArrayList;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+
+
+public class Delta {
+
+ private ArrayList srcSide = new ArrayList();
+ private ArrayList dstSide = new ArrayList();
+
+ public void addSrcSide(Reference r){
+ getSrcSide().add(r);
+ }
+
+ public void addDstSide(Reference r){
+ getDstSide().add(r);
+ }
+
+ public ArrayList getSrcSide() {
+ return srcSide;
+ }
+
+ public ArrayList getDstSide() {
+ return dstSide;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/DeltaAugmentationInfo.java b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaAugmentationInfo.java
new file mode 100644
index 0000000..3808947
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaAugmentationInfo.java
@@ -0,0 +1,34 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.AugmentationInfo;
+
+public class DeltaAugmentationInfo extends AugmentationInfo {
+ private Boolean isCoodinator = false;
+ private Boolean isSetter = true;
+ private int traceObjectId = 0;
+
+ public void setTraceObjectId(int traceObjectId) {
+ this.traceObjectId = traceObjectId;
+ }
+
+ public int getTraceObjectId() {
+ return traceObjectId;
+ }
+
+ public void setSetterSide(boolean isSetter) {
+ this.isSetter = isSetter;
+ }
+
+ public boolean isSetterSide() {
+ return isSetter;
+ }
+
+ public void setCoodinator(boolean isCoodinator) {
+ this.isCoodinator = isCoodinator;
+ }
+
+ public boolean isCoodinator() {
+ return isCoodinator;
+ }
+
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractionAnalyzer.java b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractionAnalyzer.java
new file mode 100644
index 0000000..0621515
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractionAnalyzer.java
@@ -0,0 +1,163 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+import org.ntlab.traceDebugger.JavaEditorOperator;
+import org.ntlab.traceDebugger.Variable;
+
+public class DeltaExtractionAnalyzer extends AbstractAnalyzer {
+ private static DeltaExtractionAnalyzer getInstance = null;
+ private DeltaExtractorJSON deltaExtractor;
+ private MethodExecution coordinator;
+ private ReferencePoint coordinatorPoint;
+ private List srcSidePoints = new ArrayList<>();
+ private List dstSidePoints = new ArrayList<>();
+ private ReferencePoint bottomPoint;
+ private Delta delta;
+ private static final String DELTA_MARKER_ID = "org.ntlab.traceDebugger.deltaMarker";
+
+ public DeltaExtractionAnalyzer(Trace trace) {
+ super(trace);
+ deltaExtractor = new DeltaExtractorJSON((TraceJSON)trace);
+ JavaEditorOperator.deleteMarkers(DELTA_MARKER_ID);
+ }
+
+ private static DeltaExtractionAnalyzer getInstance() {
+ if (getInstance == null) {
+ getInstance = new DeltaExtractionAnalyzer(TraceJSON.getInstance());
+ }
+ return getInstance;
+ }
+
+ public ReferencePoint getBottomPoint() {
+ return bottomPoint;
+ }
+
+ public ReferencePoint getCoordinatorPoint() {
+ return coordinatorPoint;
+ }
+
+ public List getSrcSidePoints() {
+ return srcSidePoints;
+ }
+
+ public List getDstSidePoints() {
+ return dstSidePoints;
+ }
+
+ public void extractDelta(Variable variable) {
+ String srcId = variable.getContainerId();
+ String srcClassName = variable.getContainerClassName();
+ String dstId = variable.getId();
+ String dstClassName = variable.getClassName();
+ TracePoint before = variable.getTracePoint();
+ Reference reference = new Reference(srcId, dstId, srcClassName, dstClassName);
+
+ reset();
+ bottomPoint = createReferencePoint(reference, before, true);
+ coordinatorPoint = createCoordinatorReferencePoint(coordinator, bottomPoint.getMethodExecution());
+ if (delta != null) {
+ for (Reference srcSideReference : delta.getSrcSide()) {
+ ReferencePoint rp = createReferencePoint(srcSideReference, before, false);
+ if (rp != null) srcSidePoints.add(rp);
+ }
+ for (Reference dstSideReference : delta.getDstSide()) {
+ ReferencePoint rp = createReferencePoint(dstSideReference, before, false);
+ if (rp != null) dstSidePoints.add(rp);
+ }
+ Collections.reverse(srcSidePoints);
+ Collections.reverse(dstSidePoints);
+ }
+ confirm();
+
+ String message;
+ int cnt = 1;
+ for (ReferencePoint rp : srcSidePoints) {
+ message = String.format("%s%03d: %s", "SrcSide", cnt, rp.getReferenceMessage());
+ markAndOpenJavaFile(rp, message);
+ cnt++;
+ }
+ cnt = 1;
+ for (ReferencePoint rp : dstSidePoints) {
+ message = String.format("%s%03d: %s", "DstSide", cnt, rp.getReferenceMessage());
+ markAndOpenJavaFile(rp, message);
+ cnt++;
+ }
+ message = String.format("%s: %s", "Coordinator", coordinatorPoint.getReferenceMessage());
+ markAndOpenJavaFile(coordinatorPoint, message);
+ message = String.format("%s: %s", "Bottom", bottomPoint.getReferenceMessage());
+ markAndOpenJavaFile(bottomPoint, message);
+ }
+
+ private ReferencePoint createReferencePoint(Reference reference, TracePoint before, boolean isBottom) {
+ ExtractedStructure extractedStructure = deltaExtractor.extract(reference, before.duplicate());
+ if (extractedStructure == null) return null;
+ MethodExecution creationCallTree = extractedStructure.getCreationCallTree();
+ long beforeTime = before.getStatement().getTimeStamp();
+ if (isBottom) {
+ coordinator = extractedStructure.getCoordinator();
+ delta = extractedStructure.getDelta();
+ }
+ return new ReferencePoint(reference, creationCallTree, beforeTime);
+ }
+
+ private ReferencePoint createCoordinatorReferencePoint(MethodExecution coordinator, MethodExecution bottom) {
+ MethodExecution me = bottom;
+ MethodExecution childMe = null;
+ while (me != null) {
+ if (coordinator.equals(me)) break;
+ childMe = me;
+ me = me.getParent();
+ }
+ Statement statement = null;
+ if (me != null && childMe != null) {
+ statement = me.getStatements().get(childMe.getCallerStatementExecution());
+ }
+ return new ReferencePoint(null, me, statement);
+ }
+
+ private void reset() {
+ coordinator = null;
+ srcSidePoints.clear();
+ dstSidePoints.clear();
+ bottomPoint = null;
+ delta = null;
+ JavaEditorOperator.deleteMarkers(DELTA_MARKER_ID);
+ }
+
+ private void markAndOpenJavaFile(ReferencePoint rp, String message) {
+ if (rp == null) return;
+ MethodExecution methodExecution = rp.getMethodExecution();
+ int lineNo = rp.getLineNo();
+ JavaEditorOperator.markAndOpenJavaFile(methodExecution, lineNo, message, DELTA_MARKER_ID);
+ }
+
+ private void confirm() {
+ System.out.println();
+ System.out.println();
+ System.out.println("Coordinator:");
+ System.out.println(" " + coordinator);
+ System.out.println();
+ System.out.println("SrcSide:");
+ for (ReferencePoint point : srcSidePoints) {
+ System.out.println(" " + point);
+ }
+ System.out.println();
+ System.out.println("DstSide: ");
+ for (ReferencePoint point : dstSidePoints) {
+ System.out.println(" " + point);
+ }
+ System.out.println();
+ System.out.println("Bottom:");
+ System.out.println(" " + bottomPoint);
+ System.out.println();
+ }
+}
\ No newline at end of file
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractor.java b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractor.java
new file mode 100644
index 0000000..ca2a414
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractor.java
@@ -0,0 +1,1041 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.ArrayList;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ObjectReference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+/**
+ * �f���^���o�A���S���Y��(�z��ւ̃A�N�Z�X�𐄑�����]���̃o�[�W����)
+ * extract(...)���\�b�h�Q�Œ��o����B
+ *
+ * @author Nitta
+ *
+ */
+public class DeltaExtractor {
+ protected static final int LOST_DECISION_EXTENSION = 0; // ��{�� 0 �ɐݒ�Bfinal�ϐ��̒ǐՃA���S���Y���̕s��C����͕s�v�̂͂��B
+ protected ArrayList data = new ArrayList();
+ protected ArrayList objList = new ArrayList(2);
+ protected ArrayList methodList = new ArrayList();
+ protected ExtractedStructure eStructure = new ExtractedStructure();
+ protected ObjectReference srcObject = null;
+ protected ObjectReference dstObject = null;
+ protected String returnValue;
+ protected String threadNo;
+ protected boolean isLost = false;
+ protected ArrayList checkList = new ArrayList();
+ protected Trace trace = null;
+ protected int finalCount = 0; // final�ϐ������o�ł��Ȃ��\��������̂ŁA�R���̉������ł��Ȃ������ꍇ�ł����炭�ǐՂ��Â���
+
+ protected static final boolean DEBUG1 = true;
+ protected static final boolean DEBUG2 = true;
+
+ public DeltaExtractor(String traceFile) {
+ trace = new Trace(traceFile);
+ }
+
+ public DeltaExtractor(Trace trace) {
+ this.trace = trace;
+ }
+
+// public MethodExecution getMethodExecution(Reference createdReference, MethodExecution before) {
+// return trace.getMethodExecution(createdReference, before);
+// }
+//
+// public MethodExecution getMethodExecution(String methodSignature) {
+// return trace.getMethodExecution(methodSignature);
+// }
+//
+// public MethodExecution getMethodExecutionBackwardly(String methodSignature) {
+// return trace.getMethodExecutionBackwardly(methodSignature);
+// }
+//
+// public MethodExecution getCollectionTypeMethodExecution(Reference r, MethodExecution before) {
+// return trace.getCollectionTypeMethodExecution(r, before);
+// }
+//
+// public MethodExecution getArraySetMethodExecution(Reference r, MethodExecution before) {
+// return trace.getArraySetMethodExecution(r, before);
+// }
+//
+// public CallTree getLastCallTree(ArrayList refs,
+// ArrayList colls,
+// ArrayList arrys,
+// int endLine,
+// Reference[] lastRef) throws TraceFileException {
+// return trace.getLastCallTree(refs, colls, arrys, endLine, lastRef);
+// }
+
+ /**
+ * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j
+ * @param trace�@��͑Ώۃg���[�X
+ * @param methodExecution �T�����郁�\�b�h���s
+ * @param objList�@�ǐՒ��̃I�u�W�F�N�g
+ * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s
+ * @return ���������R�[�f�B�l�[�^
+ * @throws TraceFileException
+ */
+ protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ methodExecution.setAugmentation(new DeltaAugmentationInfo());
+ eStructure.createParent(methodExecution);
+ String thisObjectId = methodExecution.getThisObjId();
+ ArrayList removeList = new ArrayList(); // �ǐՂ��Ă���I�u�W�F�N�g���ō폜�ΏۂƂȂ��Ă������
+ ArrayList creationList = new ArrayList(); // ���̃��\�b�h���s���ɐ������ꂽ�I�u�W�F�N�g
+ int existsInFields = 0; // ���̃��\�b�h���s���Ńt�B�[���h�ɗR�����Ă���I�u�W�F�N�g�̐�(1�ȏ�Ȃ炱�̃��\�b�h���s����this�Ɉˑ�)
+ boolean isTrackingThis = false; // �Ăяo�����this�Ɉˑ�����
+ boolean isSrcSide = true; // �Q�ƌ����Q�Ɛ�̂�����̑��̃I�u�W�F�N�g�̗R�������ǂ���this�I�u�W�F�N�g�ɓ��B������?
+ ArrayList fieldArrays = new ArrayList();
+ ArrayList fieldArrayElements = new ArrayList();
+ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+
+ if (childMethodExecution == null) {
+ // �T���J�n���͈�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ���������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+
+ if (childMethodExecution != null && objList.contains(childMethodExecution.getThisObjId())) {
+ // �Ăяo�����this�Ɉˑ�����
+ if (thisObjectId.equals(childMethodExecution.getThisObjId())) {
+ // �I�u�W�F�N�g���Ăяo���̂Ƃ��݈̂�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ���������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+ }
+
+ if (childMethodExecution != null && childMethodExecution.isConstructor()) {
+ // �Ăяo���悪�R���X�g���N�^�������ꍇ
+ int newIndex = objList.indexOf(childMethodExecution.getThisObjId());
+ if (newIndex != -1) {
+ // �Ăяo���悪�ǐՑΏۂ̃R���X�g���N�^��������field�Ɠ��l�ɏ���
+ removeList.add(childMethodExecution.getThisObjId());
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ }
+
+ if (childMethodExecution != null && Trace.getMethodName(childMethodExecution.getSignature()).startsWith("access$")) {
+ // �G���N���[�W���O�C���X�^���X�ɑ��郁�\�b�h�Ăяo���������ꍇ
+ String enclosingObj = childMethodExecution.getArguments().get(0).getId(); // �G���N���[�W���O�C���X�^���X�͑������ɓ����Ă���炵��
+ int encIndex = objList.indexOf(enclosingObj);
+ if (encIndex != -1) {
+ // thisObject �ɒu����������Afield�Ɠ��l�ɏ���
+ removeList.add(enclosingObj);
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ }
+
+ // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch���ċA�Ăяo��
+ while (tracePoint.stepBackOver()) {
+ Statement statement = tracePoint.getStatement();
+ // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T��
+ if (statement instanceof FieldAccess) {
+ FieldAccess fs = (FieldAccess)statement;
+ String refObjectId = fs.getValueObjId();
+ int index = objList.indexOf(refObjectId);
+ if (index != -1) {
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ removeList.add(refObjectId);
+ existsInFields++; // set�������get�����o������\��������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ
+ if (refObjectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(ownerObjectId, refObjectId,
+ fs.getContainerClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ } else if(refObjectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(ownerObjectId, refObjectId,
+ fs.getContainerClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ }
+ objList.set(index, ownerObjectId);
+ }
+ } else {
+ // �ŏI�I�ɃI�u�W�F�N�g�̗R����������Ȃ������ꍇ�ɁA�����ŎQ�Ƃ����z������̗v�f�ɗR�����Ă���\��������
+ String refObjType = fs.getValueClassName();
+ if (refObjType.startsWith("[L")) {
+ // �Q�Ƃ����t�B�[���h���z��̏ꍇ
+ ObjectReference trackingObj = null;
+ if ((srcObject.getActualType() != null && refObjType.endsWith(srcObject.getActualType() + ";"))
+ || (srcObject.getCalleeType() != null && refObjType.endsWith(srcObject.getCalleeType() + ";"))
+ || (srcObject.getCallerType() != null && refObjType.endsWith(srcObject.getCallerType() + ";"))) {
+ trackingObj = srcObject;
+ } else if ((dstObject.getActualType() != null && refObjType.endsWith(dstObject.getActualType() + ";"))
+ || (dstObject.getCalleeType() != null && refObjType.endsWith(dstObject.getCalleeType() + ";"))
+ || (dstObject.getCallerType() != null && refObjType.endsWith(dstObject.getCallerType() + ";"))) {
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ // �ǐՒ��̃I�u�W�F�N�g�ɁA�z��v�f�Ɠ����^�����I�u�W�F�N�g�����݂���ꍇ
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j
+ fieldArrays.add(new ObjectReference(refObjectId, refObjType));
+ fieldArrayElements.add(trackingObj);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B)
+ }
+ }
+ }
+ }
+ } else if (statement instanceof MethodInvocation) {
+ MethodExecution prevChildMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ if (!prevChildMethodExecution.equals(childMethodExecution)) {
+ // �߂�l
+ ObjectReference ret = prevChildMethodExecution.getReturnValue();
+ if (ret != null) {
+ int retIndex = -1;
+ retIndex = objList.indexOf(ret.getId());
+ if (retIndex != -1) {
+ // �߂�l���R��������
+ prevChildMethodExecution.setAugmentation(new DeltaAugmentationInfo());
+ if (prevChildMethodExecution.isConstructor()) {
+ // �ǐՑΏۂ�constractor���Ă�ł�����(�I�u�W�F�N�g�̐�����������)field�Ɠ��l�ɏ���
+ String newObjId = ret.getId();
+ creationList.add(newObjId);
+ removeList.add(newObjId);
+ existsInFields++;
+ // objList.remove(callTree.getThisObjId());
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(newObjId)); // �ǐՑΏ�
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setSetterSide(false); // getter�Ăяo���Ɠ��l
+ continue;
+ }
+ String retObj = objList.get(retIndex);
+ if (removeList.contains(retObj)) {
+ // ��xget�Ō��o���ăt�B�[���h�Ɉˑ����Ă���Ɣ��f�������{���̗R�����߂�l���������Ƃ����������̂ŁA�t�B�[���h�ւ̈ˑ����L�����Z������
+ removeList.remove(retObj);
+ existsInFields--;
+ if (existsInFields == 0) {
+ removeList.remove(thisObjectId);
+ }
+ }
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ�
+ TracePoint prevChildTracePoint = tracePoint.duplicate();
+ prevChildTracePoint.stepBackNoReturn();
+ calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex); // �Ăяo�����T��
+ if (objList.get(retIndex) != null && objList.get(retIndex).equals(prevChildMethodExecution.getThisObjId())
+ && thisObjectId.equals(prevChildMethodExecution.getThisObjId())) {
+ // �Ăяo����Ńt�B�[���h�Ɉˑ����Ă����ꍇ�̏���
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+ if (isLost) {
+ checkList.add(objList.get(retIndex));
+ isLost = false;
+ }
+ } else {
+ // �ŏI�I�ɃI�u�W�F�N�g�̗R����������Ȃ������ꍇ�ɁA���̖߂�l�Ŏ擾�����z������̗v�f�ɗR�����Ă���\��������
+ String retType = ret.getActualType();
+ if (retType.startsWith("[L")) {
+ // �߂�l���z��̏ꍇ
+ if ((srcObject.getActualType() != null && retType.endsWith(srcObject.getActualType() + ";"))
+ || (srcObject.getCalleeType() != null && retType.endsWith(srcObject.getCalleeType() + ";"))
+ || (srcObject.getCallerType() != null && retType.endsWith(srcObject.getCallerType() + ";"))) {
+ retType = srcObject.getActualType();
+ } else if ((dstObject.getActualType() != null && retType.endsWith(dstObject.getActualType() + ";"))
+ || (dstObject.getCalleeType() != null && retType.endsWith(dstObject.getCalleeType() + ";"))
+ || (dstObject.getCallerType() != null && retType.endsWith(dstObject.getCallerType() + ";"))) {
+ retType = dstObject.getActualType();
+ } else {
+ retType = null;
+ }
+ if (retType != null) {
+ // �{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u�������āA�Ăяo�����T�����ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // --- ���̎��_�� tracePoint �͌Ăяo�������w���Ă��� ---
+
+ // �R���N�V�����^�Ή�
+ if (methodExecution.isCollectionType()) {
+ objList.add(thisObjectId);
+ }
+
+ // �����̎擾
+ ArrayList argments = methodExecution.getArguments();
+
+ // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z��
+ Reference r;
+ for (int i = 0; i < removeList.size(); i++) {
+ String removeId = removeList.get(i);
+ if (argments.contains(new ObjectReference(removeId))) {
+ removeList.remove(removeId); // �t�B�[���h�ƈ����̗����ɒǐՑΏۂ����݂����ꍇ�A������D��
+ } else if(objList.contains(removeId)) {
+ // �t�B�[���h�ɂ����Ȃ������ꍇ(�������A�I�u�W�F�N�g�̐������t�B�[���h�Ɠ��l�Ɉ���)
+ objList.remove(removeId); // �ǐՑΏۂ���O��
+ if (!removeId.equals(thisObjectId)) {
+ // �t�B�[���h�ithis ���� removeId �ւ̎Q�Ɓj���f���^�̍\���v�f�ɂȂ�
+ if (removeId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����?
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else if (removeId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����?
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ }
+ // --- ���̎��_�� this ���ǐՑΏۂł������Ƃ��Ă� objList �̒����炢������폜����Ă��� ---
+
+ // �����T��
+ boolean existsInAnArgument = false;
+ for (int i = 0; i < objList.size(); i++) {
+ String objectId = objList.get(i);
+ if (objectId != null) {
+ ObjectReference trackingObj = new ObjectReference(objectId);
+ if (argments.contains(trackingObj)) {
+ // �������R��������
+ existsInAnArgument = true;
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId));
+ } else {
+ // �R�����ǂ��ɂ�������Ȃ�����
+ boolean isSrcSide2 = true;
+ trackingObj = null;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide2 = true;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide2 = false;
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ // �܂��z������̗v�f��R���Ƃ��ċ^��(������D��)
+ for (int j = 0; j < argments.size(); j++) {
+ ObjectReference argArray = argments.get(j);
+ if (argArray.getActualType().startsWith("[L")
+ && (trackingObj.getActualType() != null && (argArray.getActualType().endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && argArray.getActualType().endsWith(trackingObj.getCallerType() + ";")))) {
+ // �^����v������z������̗v�f��R���Ƃ݂Ȃ�
+ existsInAnArgument = true;
+ objList.remove(objectId);
+ objList.add(argArray.getId()); // �ǐՑΏۂ�z��v�f����z��ɒu������
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(argArray.getId()));
+ r = new Reference(argArray.getId(), trackingObj.getId(),
+ argArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ srcObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ }
+ objectId = null;
+ break;
+ }
+ }
+ if (objectId != null) {
+ // ���ɔz��t�B�[���h�̗v�f��R���Ƃ��ċ^��(�t�B�[���h�͈�������)
+ int index = fieldArrayElements.indexOf(trackingObj);
+ if (index != -1) {
+ // �^����v���Ă�̂Ŕz��t�B�[���h�̗v�f��R���Ƃ݂Ȃ�
+ ObjectReference fieldArray = fieldArrays.get(index);
+ existsInFields++;
+ objList.remove(objectId);
+ r = new Reference(fieldArray.getId(), trackingObj.getId(),
+ fieldArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(r);
+ eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ if (trackingObj.getActualType() != null && trackingObj.getActualType().startsWith("[L")) {
+ // �ǂ��ɂ�������Ȃ������ꍇ�A�T���Ă���̂��z��^�Ȃ�A���̃��\�b�h���Ő������ꂽ���̂ƍl����
+ objList.remove(objectId);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (existsInAnArgument) {
+ // ������1�ł��ǐՑΏۂ����݂����ꍇ
+ if (existsInFields > 0 || isTrackingThis) {
+ // this�I�u�W�F�N�g��ǐՒ��̏ꍇ
+ if (!Trace.isNull(thisObjectId)) {
+ objList.add(thisObjectId); // ����ɒT������ꍇ�A��U��菜���� thisObject ��
+ } else {
+ objList.add(null); // ������static�Ăяo���������ꍇ�A����ȏ�ǐՂ��Ȃ�
+ }
+ }
+// if (existsInFields > 0) {
+// // �t�B�[���h��R���Ɏ��I�u�W�F�N�g�����݂����ꍇ
+// if (isSrcSide) {
+// srcObject = thisObj;
+// } else {
+// dstObject = thisObj;
+// }
+// }
+ if (tracePoint.isValid()) {
+ finalCount = 0;
+ return callerSearch(trace, tracePoint, objList, methodExecution); // �Ăяo����������ɒT��
+ }
+ }
+
+ for (int i = 0; i < objList.size(); i++) {
+ objList.remove(null);
+ }
+ if (objList.isEmpty()) {
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(true);
+ } else {
+ // �R���������ł��Ȃ�����
+ if (!methodExecution.isStatic()) {
+ finalCount++;
+ if (finalCount <= LOST_DECISION_EXTENSION) {
+ // final�ϐ����Q�Ƃ��Ă���ꍇ�R���������ł��Ȃ��\��������̂ŁA�ǐՂ������I�������P�\���Ԃ�݂���
+ if (tracePoint.isValid()) {
+ MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution); // �Ăяo����������ɒT��
+ if (((DeltaAugmentationInfo)c.getAugmentation()).isCoodinator()) {
+ methodExecution = c; // �ǐՂ𑱂������ʃR�[�f�B�l�[�^����������
+ }
+ }
+ } else if (thisObj.getActualType().contains("$")) {
+ // �����������܂��͖����N���X�̏ꍇ�A���������I�u�W�F�N�g���O�����\�b�h�̓���final�ϐ�����擾�����Ƃ݂Ȃ��A����Ɏ����̒��̃t�B�[���h�̈��Ƃ݂Ȃ�
+ for (int i = objList.size() - 1; i >= 0; i--) {
+ String objectId = objList.get(i);
+ if (objectId != null) {
+ ObjectReference trackingObj = new ObjectReference(objectId);
+ boolean isSrcSide2 = true;
+ trackingObj = null;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide2 = true;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide2 = false;
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ r = new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType());
+ r.setFinalLocal(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ existsInFields++;
+ objList.remove(objectId);
+ }
+ }
+ }
+ }
+ }
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(false);
+ }
+ finalCount = 0;
+ return methodExecution;
+ }
+
+ /**
+ * �f���^���o�A���S���Y���̌Ăяo����T������(�ċA�Ăяo���ɂȂ��Ă���)
+ * @param trace ��͑Ώۃg���[�X
+ * @param methodExecution �T�����郁�\�b�h���s
+ * @param objList �ǐՒ��̃I�u�W�F�N�g
+ * @param isStatic�@�ÓI���\�b�h���ۂ�
+ * @param index�@objList���̂ǂ̃I�u�W�F�N�g��ǐՂ��Ă��̃��\�b�h���s�ɓ����Ă����̂�
+ * @throws TraceFileException
+ */
+ protected void calleeSearch(Trace trace, TracePoint tracePoint, ArrayList objList, Boolean isStatic, int index) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ Boolean isResolved = false;
+ String objectId = objList.get(index); // calleeSearch() �ł͒ǐՑΏۂ̃I�u�W�F�N�g�͈�����A��objList��index�Ԗڂ̗v�f�ȊO�ύX���Ă͂����Ȃ�
+ String thisObjectId = methodExecution.getThisObjId();
+ ArrayList fieldArrays = new ArrayList();
+ ArrayList fieldArrayElements = new ArrayList();
+ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()),
+ Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(false); // ��{�I��getter�Ăяo���̂͂������A����
+ ArrayList argments = methodExecution.getArguments();
+ ObjectReference trackingObj = null;
+ //static���o�R�����null�������Ă��鎞������
+ if (objectId != null) {
+ String returnType = Trace.getReturnType(methodExecution.getSignature());
+ if (objectId.equals(srcObject.getId())) {
+ trackingObj = srcObject;
+ trackingObj.setCalleeType(returnType);
+ } else if(objectId.equals(dstObject.getId())) {
+ trackingObj = dstObject;
+ trackingObj.setCalleeType(returnType);
+ } else {
+ trackingObj = new ObjectReference(objectId, null, returnType);
+ }
+
+ Reference r;
+ // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch�Ăяo��
+ do {
+ if (!tracePoint.isValid()) break;
+ Statement statement = tracePoint.getStatement();
+ // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T��
+ if (statement instanceof FieldAccess) {
+ FieldAccess fs = (FieldAccess)statement;
+ if (objectId != null && objectId.equals(fs.getValueObjId())) {
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(thisObj, srcObject));
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(thisObj, dstObject));
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(ownerObjectId, objectId,
+ fs.getContainerClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(ownerObjectId, objectId,
+ fs.getContainerClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(ownerObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = ownerObjectId;
+ objList.set(index, objectId);
+ }
+ isResolved = true;
+ } else {
+ // �I�u�W�F�N�g�̗R�������ڌ�����Ȃ������ꍇ�ł��A�����ꂩ�̔z��̗v�f�ɗR�����Ă���\��������
+ String refObjType = fs.getValueClassName();
+ if (refObjType.startsWith("[L")) {
+ // �Q�Ƃ����t�B�[���h���z��̏ꍇ
+ if ((trackingObj.getActualType() != null && refObjType.endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && refObjType.endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && refObjType.endsWith(trackingObj.getCallerType() + ";"))) {
+ // �z��̗v�f�̕����ǐՒ��̃I�u�W�F�N�g�̌^�ƈ�v�����ꍇ
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ�i���ɗR���̉\�����Ȃ��Ƃ킩�������_�ŁA���̔z��̗v�f�ɗR�����Ă�����̂Ɛ�������B�j
+ fieldArrays.add(new ObjectReference(fs.getValueObjId(), refObjType));
+ fieldArrayElements.add(trackingObj);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ(�{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u��������ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B)
+ }
+ }
+ }
+ }
+ } else if (statement instanceof MethodInvocation) {
+ // �߂�l
+ MethodExecution childMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ ObjectReference ret = childMethodExecution.getReturnValue();
+ if (ret != null && objectId != null && objectId.equals(ret.getId())) {
+ childMethodExecution.setAugmentation(new DeltaAugmentationInfo());
+ ((DeltaAugmentationInfo)childMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId));
+ TracePoint childTracePoint = tracePoint.duplicate();
+ childTracePoint.stepBackNoReturn();
+ calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index); // �Ăяo���������ɒT��
+ if (childMethodExecution.isConstructor()) {
+ // �R���X�g���N�^�Ăяo���������ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCreation(true);
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCreation(true);
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ isResolved = true;
+ isLost = false;
+ continue;
+ }
+ objectId = objList.get(index);
+ if (objectId == null) {
+ // static�Ăяo���̖߂�l�������ꍇ�i���Ԃ�j
+ trackingObj = null;
+ isResolved = true;
+ } else if (objectId.equals(srcObject.getId())) {
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ trackingObj = dstObject;
+ }
+ if (isLost) {
+ checkList.add(objList.get(index));
+ isLost = false;
+ }
+ } else {
+ // �I�u�W�F�N�g�̗R�������ڌ�����Ȃ������ꍇ�ł��A�ǂ����̔z��̗v�f�ɗR�����Ă���\��������
+ String retType = ret.getActualType();
+ if (retType.startsWith("[L")) {
+ // �߂�l���z��̏ꍇ
+ if ((trackingObj.getActualType() != null && retType.endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && retType.endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && retType.endsWith(trackingObj.getCallerType() + ";"))) {
+ // �{���ɂ��̔z��̗v�f����擾���ꂽ���̂Ȃ炱���ŒǐՑΏۂ�u�������āA�Ăяo�����T�����ׂ������A
+ // ���̎��_�ő��̗R���̉\����r���ł��Ȃ��B�����ŒǐՑΏۂ�u�������Ă��܂��ƁA��ŕʂɗR�������邱�Ƃ��킩�����ꍇ��
+ // ��蒼��������B
+ }
+ }
+ }
+ }
+ } while (tracePoint.stepBackOver());
+
+ //�����T��
+ if (argments.contains(new ObjectReference(objectId))) {
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(true); // �������K�v?
+ isResolved = true;
+ }
+ }
+
+ //�R���N�V�����^�Ή�
+ Reference r;
+ if (methodExecution.isCollectionType()) {
+ if (objectId != null) {
+ // �R���N�V�����^�̏ꍇ�A�����ŌX�̗v�f�ڕێ����Ă���Ɖ��肷��
+ if (objectId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCollection(true);
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ } else if(objectId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCollection(true);
+ eStructure.addDstSide(r);
+ dstObject =thisObj;
+ }
+ }
+ objList.set(index, methodExecution.getThisObjId());
+ isResolved = true; // �K�v�Ȃ̂ł�?
+ }
+
+ if (!isResolved && objectId != null) {
+ // �R�����ǂ��ɂ�������Ȃ�����
+ boolean isSrcSide = true;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide = true;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide = false;
+ }
+ if (trackingObj != null) {
+ // �܂��z������̗v�f��R���Ƃ��ċ^��(�������D��)
+ for (int i = 0; i < argments.size(); i++) {
+ ObjectReference argArray = argments.get(i);
+ if (argArray.getActualType().startsWith("[L")
+ && ((trackingObj.getActualType() != null && argArray.getActualType().endsWith(trackingObj.getActualType() + ";"))
+ || (trackingObj.getCalleeType() != null && argArray.getActualType().endsWith(trackingObj.getCalleeType() + ";"))
+ || (trackingObj.getCallerType() != null && argArray.getActualType().endsWith(trackingObj.getCallerType() + ";")))) {
+ // �^����v������z������̗v�f��R���Ƃ݂Ȃ�
+ isResolved = true;
+ objList.set(index, argArray.getId()); // �ǐՑΏۂ�z��v�f����z��ɒu������
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(argArray.getId()));
+ r = new Reference(argArray.getId(), trackingObj.getId(),
+ argArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide) {
+ eStructure.addSrcSide(r);
+ srcObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = new ObjectReference(argArray.getId(), argArray.getActualType());
+ }
+ objectId = null;
+ break;
+ }
+ }
+ if (objectId != null) {
+ // ���ɔz��t�B�[���h�̗v�f��R���Ƃ��ċ^��(�t�B�[���h�͈�������)
+ int indArg = fieldArrayElements.indexOf(trackingObj);
+ if (indArg != -1) {
+ // �^����v���Ă�̂Ŕz��t�B�[���h�̗v�f��R���Ƃ݂Ȃ�
+ isResolved = true;
+ ObjectReference fieldArray = fieldArrays.get(indArg);
+ objList.set(index, thisObjectId); // �ǐՑΏۂ�this�ɒu������
+ r = new Reference(fieldArray.getId(), trackingObj.getId(),
+ fieldArray.getActualType(), trackingObj.getActualType());
+ r.setArray(true);
+ if (isSrcSide) {
+ eStructure.addSrcSide(r);
+ eStructure.addSrcSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ srcObject = thisObj;
+ } else {
+ eStructure.addDstSide(r);
+ eStructure.addDstSide(new Reference(thisObjectId, fieldArray.getId(),
+ methodExecution.getThisClassName(), fieldArray.getActualType()));
+ dstObject = thisObj;
+ }
+ }
+ }
+ if (trackingObj.getActualType() != null && trackingObj.getActualType().startsWith("[L")) {
+ // �ǂ��ɂ�������Ȃ������ꍇ�A�T���Ă���̂��z��^�Ȃ�A���̃��\�b�h���Ő������ꂽ���̂ƍl����
+ isResolved = true;
+ objList.set(index, thisObjectId); // �ǐՑΏۂ�this�ɒu������
+ if (isSrcSide) {
+ eStructure.addSrcSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ srcObject = thisObj;
+ } else {
+ eStructure.addDstSide(new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType()));
+ dstObject = thisObj;
+ }
+ }
+ }
+ }
+
+ if (objectId == null && isResolved && !isStatic) { // static �Ăяo������̖߂�l��Ԃ��Ă���ꍇ
+ objList.set(index, thisObjectId); // ������ǐՂ�����
+ if (Trace.isNull(srcObject.getId())) {
+ srcObject = thisObj;
+ } else if (Trace.isNull(dstObject.getId())) {
+ dstObject = thisObj;
+ }
+ }
+
+ if (isStatic && !isResolved) { // ���͋N���肦�Ȃ�?(get�|�C���g�J�b�g���擾����悤�ɂ�������)
+ objList.set(index, null);
+ }
+ if(!isStatic && !isResolved){
+ isLost = true; // final�ϐ�������N���X�ŎQ�Ƃ��Ă���\�������邪�AcalleeSearch()�͕K���Ăяo�����ɕ��A���Ă����̂ŁA�����ł͉������Ȃ�
+ }
+ }
+
+ /**
+ * �v�ύX��̃A���S���Y���̋N�����\�b�h(������)
+ * @param targetRef �ΏۂƂȂ�Q��
+ * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return ���o����
+ */
+ public ExtractedStructure extract(Reference targetRef, TracePoint before) {
+ TracePoint creationTracePoint;
+ if (targetRef.isArray()) {
+ // srcId �̔z��� dstId ���������Ă���\�������郁�\�b�h���s���擾�i�z���p�̏����j
+ creationTracePoint = trace.getArraySetTracePoint(targetRef, before);
+ } else if (targetRef.isCollection()) {
+ // srcId �̃R���N�V�����^�I�u�W�F�N�g�� dstId ���n����Ă��郁�\�b�h���s���擾�i�R���N�V�����^��p�̏����j
+ creationTracePoint = trace.getCollectionAddTracePoint(targetRef, before);
+ } else if (targetRef.isFinalLocal()) {
+ // srcId �̓����܂��͖����N���X�̃C���X�^���X�� final local �ϐ��ɑ������Ă��� dstId �� �I�u�W�F�N�g���n���ꂽ�\�������郁�\�b�h���s���擾�ifinal local�̋^��������ꍇ�̏����j
+ creationTracePoint = trace.getCreationTracePoint(targetRef.getSrcObject(), before);
+ targetRef = new Reference(creationTracePoint.getMethodExecution().getThisObjId(), targetRef.getDstObjectId(), creationTracePoint.getMethodExecution().getThisClassName(), targetRef.getDstClassName());
+ } else {
+ // �I�u�W�F�N�g�ԎQ�� r ���������ꂽ���\�b�h���s���擾�i�ʏ�j
+ creationTracePoint = trace.getFieldUpdateTracePoint(targetRef, before);
+ }
+ if (creationTracePoint == null) {
+ return null;
+ }
+ return extractSub(creationTracePoint, targetRef);
+ }
+
+ /**
+ * �v�ύX��̃A���S���Y���̋N�����\�b�h(������)
+ * @param creationTracePoint �I�u�W�F�N�g�ԎQ�Ɛ����g���[�X�|�C���g(�t�B�[���h�ւ̑��)
+ * @return ���o����
+ */
+ public ExtractedStructure extract(TracePoint creationTracePoint) {
+ creationTracePoint = creationTracePoint.duplicate();
+ Statement statement = creationTracePoint.getStatement();
+ if (statement instanceof FieldUpdate) {
+ Reference targetRef = ((FieldUpdate)statement).getReference();
+ return extractSub(creationTracePoint, targetRef);
+ } else {
+ return null;
+ }
+ }
+
+ private ExtractedStructure extractSub(TracePoint creationTracePoint, Reference targetRef) {
+ eStructure = new ExtractedStructure();
+ ArrayList objList = new ArrayList();
+ srcObject = targetRef.getSrcObject();
+ dstObject = targetRef.getDstObject();
+if (DEBUG1) {
+ System.out.println("extract delta of:" + targetRef.getSrcObject().getActualType() + "(" + targetRef.getSrcObjectId() + ")" + " -> " + targetRef.getDstObject().getActualType() + "(" + targetRef.getDstObjectId() + ")");
+}
+ if (!Trace.isNull(targetRef.getSrcObjectId())) {
+ objList.add(targetRef.getSrcObjectId());
+ } else {
+ objList.add(null);
+ }
+ if (!Trace.isNull(targetRef.getDstObjectId())) {
+ objList.add(targetRef.getDstObjectId());
+ } else {
+ objList.add(null);
+ }
+ return extractSub2(creationTracePoint, objList);
+ }
+
+ public ExtractedStructure extract(TracePoint tracePoint, ObjectReference argObj) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ eStructure = new ExtractedStructure();
+ ArrayList objList = new ArrayList();
+ String thisObjectId = methodExecution.getThisObjId();
+ objList.add(thisObjectId);
+ objList.add(argObj.getId());
+ srcObject = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+ dstObject = argObj;
+if (DEBUG1) {
+ System.out.println("extract delta of:" + methodExecution.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")");
+}
+ return extractSub2(tracePoint, objList);
+ }
+
+ private ExtractedStructure extractSub2(TracePoint creationTracePoint, ArrayList objList) {
+ eStructure.setCreationMethodExecution(creationTracePoint.getMethodExecution());
+ MethodExecution coordinator = callerSearch(trace, creationTracePoint, objList, null);
+ eStructure.setCoordinator(coordinator);
+if (DEBUG2) {
+ if (((DeltaAugmentationInfo)coordinator.getAugmentation()).isCoodinator()) {
+ System.out.println("Coordinator");
+ } else {
+ System.out.println("Warning");
+ }
+ System.out.println("coordinator:" + coordinator.getSignature());
+ System.out.println("srcSide:");
+ for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) {
+ Reference ref = eStructure.getDelta().getSrcSide().get(i);
+ if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+ System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+ }
+ }
+ System.out.println("dstSide:");
+ for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) {
+ Reference ref = eStructure.getDelta().getDstSide().get(i);
+ if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+ System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+ }
+ }
+ System.out.println("overCoordinator:");
+ MethodExecution parent = coordinator.getParent();
+ while (parent != null) {
+ System.out.println("\t" + parent.getSignature());
+ parent = parent.getParent();
+ }
+}
+ return eStructure;
+ }
+
+ /**
+ * �Q�ƌ��ƎQ�Ɛ�̃I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p)
+ * @param srcObj �Q�ƌ��I�u�W�F�N�g
+ * @param dstObj �Q�Ɛ�I�u�W�F�N�g
+ * @param before �T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return�@���o����
+ */
+ public ExtractedStructure extract(Object srcObj, Object dstObj, TracePoint before) {
+ Reference targetRef = new Reference(Integer.toString(System.identityHashCode(srcObj)), Integer.toString(System.identityHashCode(dstObj)), null, null);
+ return extract(targetRef, before);
+ }
+
+
+ /**
+ * ���\�b�h���s���̃g���[�X�|�C���g�ƎQ�Ɛ�I�u�W�F�N�g���w�肵�ăf���^�𒊏o����(�I�����C����͗p)
+ * @param tracePoint ���\�b�h���s���̃g���[�X�|�C���g
+ * @param arg �Q�Ɛ�I�u�W�F�N�g(���[�J���ϐ�������ɂ��Q�Ɛ�)
+ * @return ���o����
+ */
+ public ExtractedStructure extract(TracePoint tracePoint, Object arg) {
+ ObjectReference argObj = new ObjectReference(Integer.toString(System.identityHashCode(arg)));
+ return extract(tracePoint, argObj);
+ }
+
+ /**
+ * �w�肵���X���b�h��Ō��ݎ��s���̃��\�b�h���s���擾����(�I�����C����͗p)
+ * @param thread �ΏۃX���b�h
+ * @return thread ��Ō��ݎ��s���̃��\�b�h���s
+ */
+ public MethodExecution getCurrentMethodExecution(Thread thread) {
+ return trace.getCurrentMethodExecution(thread);
+ }
+
+ /**
+ * methodSignature �ɑO����v���郁�\�b�h���������\�b�h�̍Ō�̎��s
+ * @param methodSignature ���\�b�h��(�O����v��������)
+ * @return �Y������Ō�̃��\�b�h���s
+ */
+ public MethodExecution getLastMethodExecution(String methodSignature) {
+ return trace.getLastMethodExecution(methodSignature);
+ }
+
+ /**
+ * methodSignature �ɑO����v���郁�\�b�h���������\�b�h�� before �ȑO�̍Ō�̎��s
+ * @param methodSignature ���\�b�h��(�O����v��������)
+ * @param before�@�T���J�n�g���[�X�|�C���g(������ȑO��T��)
+ * @return�@�Y������Ō�̃��\�b�h���s
+ */
+ public MethodExecution getLastMethodExecution(String methodSignature, TracePoint before) {
+ return trace.getLastMethodExecution(methodSignature, before);
+ }
+
+ public ArrayList getMethodExecutions(String methodSignature) {
+ return trace.getMethodExecutions(methodSignature);
+ }
+
+// public ExtractedStructure extract(MethodExecution caller, MethodExecution callee) {
+// eStructure = new ExtractedStructure();
+// ArrayList objList = new ArrayList();
+// String thisObjectId = caller.getThisObjId();
+// objList.add(thisObjectId);
+// objList.add(callee.getThisObjId());
+// srcObject = new ObjectReference(thisObjectId, caller.getThisClassName(),
+// Trace.getDeclaringType(caller.getSignature(), caller.isConstractor()), Trace.getDeclaringType(caller.getCallerSideSignature(), caller.isConstractor()));
+// dstObject = new ObjectReference(callee.getThisObjId(), callee.getThisClassName(),
+// Trace.getDeclaringType(callee.getSignature(), callee.isConstractor()), Trace.getDeclaringType(callee.getCallerSideSignature(), callee.isConstractor()));
+//if (DEBUG1) {
+// System.out.println("extract delta of:" + caller.getSignature() + " -> " + callee.getSignature());
+//}
+//
+// caller = new MethodExecution(caller); // ��͗p�p�����[�^���������������̂��g�p����
+// eStructure.setCreationMethodExecution(caller);
+// MethodExecution coordinator = callerSearch(trace, caller, objList, null);
+// eStructure.setCoordinator(coordinator);
+//if (DEBUG2) {
+// if (coordinator.isCoodinator()) {
+// System.out.println("Coordinator");
+// } else {
+// System.out.println("Warning");
+// }
+// System.out.println("coordinator:" + coordinator.getSignature());
+// System.out.println("srcSide:");
+// for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getSrcSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("dstSide:");
+// for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getDstSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("overCoordinator:");
+// MethodExecution parent = coordinator.getParent();
+// while (parent != null) {
+// System.out.println("\t" + parent.getSignature());
+// parent = parent.getParent();
+// }
+//}
+// return eStructure;
+// }
+//
+//
+// /**
+// * ���\�b�h�̈����Ƃ��ăI�u�W�F�N�g���Q�Ƃ����ꍇ�̃f���^�𒊏o����
+// * @param caller �Q�ƌ��̃��\�b�h
+// * @param argObj �����Ƃ��ĎQ�Ƃ����I�u�W�F�N�g
+// * @return�@���o����
+// */
+// public ExtractedStructure extract(MethodExecution caller, ObjectReference argObj) {
+// eStructure = new ExtractedStructure();
+// ArrayList objList = new ArrayList();
+// String thisObjectId = caller.getThisObjId();
+// objList.add(thisObjectId);
+// objList.add(argObj.getId());
+// srcObject = new ObjectReference(thisObjectId, caller.getThisClassName(),
+// Trace.getDeclaringType(caller.getSignature(), caller.isConstractor()), Trace.getDeclaringType(caller.getCallerSideSignature(), caller.isConstractor()));
+// dstObject = argObj;
+//if (DEBUG1) {
+// System.out.println("extract delta of:" + caller.getSignature() + " -> " + argObj.getActualType() + "(" + argObj.getId() + ")");
+//}
+//
+// caller = new MethodExecution(caller); // ��͗p�p�����[�^���������������̂��g�p����
+// eStructure.setCreationMethodExecution(caller);
+// MethodExecution coordinator = callerSearch(trace, caller, objList, null);
+// eStructure.setCoordinator(coordinator);
+//if (DEBUG2) {
+// if (coordinator.isCoodinator()) {
+// System.out.println("Coordinator");
+// } else {
+// System.out.println("Warning");
+// }
+// System.out.println("coordinator:" + coordinator.getSignature());
+// System.out.println("srcSide:");
+// for (int i = 0; i < eStructure.getDelta().getSrcSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getSrcSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("dstSide:");
+// for (int i = 0; i < eStructure.getDelta().getDstSide().size(); i++) {
+// Reference ref = eStructure.getDelta().getDstSide().get(i);
+// if (!ref.isCreation() || !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
+// System.out.println("\t" + ref.getSrcClassName() + "(" + ref.getSrcObjectId() + ")" + " -> " + ref.getDstClassName() + "(" + ref.getDstObjectId() + ")");
+// }
+// }
+// System.out.println("overCoordinator:");
+// MethodExecution parent = coordinator.getParent();
+// while (parent != null) {
+// System.out.println("\t" + parent.getSignature());
+// parent = parent.getParent();
+// }
+//}
+// return eStructure;
+// }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractorJSON.java b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractorJSON.java
new file mode 100644
index 0000000..29b2b9f
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/DeltaExtractorJSON.java
@@ -0,0 +1,546 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.ArrayList;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayCreate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ObjectReference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+
+/**
+ * �f���^���o�A���S���Y��(�z��ւ̃A�N�Z�X�����m�ł���Javassist��JSON�g���[�X�ɑΉ����A�A���S���Y����P����)
+ *
+ * @author Nitta
+ *
+ */
+public class DeltaExtractorJSON extends DeltaExtractor {
+ public DeltaExtractorJSON(String traceFile) {
+ super(new TraceJSON(traceFile));
+ }
+
+ public DeltaExtractorJSON(TraceJSON trace) {
+ super(trace);
+ }
+
+ /**
+ * �f���^���o�A���S���Y���̌Ăяo�����T�������icalleeSearch�Ƒ��ݍċA�ɂȂ��Ă���j
+ * @param trace�@��͑Ώۃg���[�X
+ * @param methodExecution �T�����郁�\�b�h���s
+ * @param objList�@�ǐՒ��̃I�u�W�F�N�g
+ * @param child�@���O�ɒT�����Ă����Ăяo����̃��\�b�h���s
+ * @return ���������R�[�f�B�l�[�^
+ * @throws TraceFileException
+ */
+ protected MethodExecution callerSearch(Trace trace, TracePoint tracePoint, ArrayList objList, MethodExecution childMethodExecution) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ methodExecution.setAugmentation(new DeltaAugmentationInfo());
+ eStructure.createParent(methodExecution);
+ String thisObjectId = methodExecution.getThisObjId();
+ ArrayList removeList = new ArrayList(); // �ǐՂ��Ă���I�u�W�F�N�g���ō폜�ΏۂƂȂ��Ă������
+ ArrayList creationList = new ArrayList(); // ���̃��\�b�h���s���ɐ������ꂽ�I�u�W�F�N�g
+ int existsInFields = 0; // ���̃��\�b�h���s���Ńt�B�[���h�ɗR�����Ă���I�u�W�F�N�g�̐�(1�ȏ�Ȃ炱�̃��\�b�h���s����this�Ɉˑ�)
+ boolean isTrackingThis = false; // �Ăяo�����this�Ɉˑ�����
+ boolean isSrcSide = true; // �Q�ƌ����Q�Ɛ�̂�����̑��̃I�u�W�F�N�g�̗R�������ǂ���this�I�u�W�F�N�g�ɓ��B������?
+ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()), Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+
+ if (childMethodExecution == null) {
+ // �T���J�n���͈�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ���������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+
+ if (childMethodExecution != null && objList.contains(childMethodExecution.getThisObjId())) {
+ // �Ăяo�����this�Ɉˑ�����
+ if (thisObjectId.equals(childMethodExecution.getThisObjId())) {
+ // �I�u�W�F�N�g���Ăяo���̂Ƃ��݈̂�U�폜���A�Ăяo�����̒T���𑱂���ۂɕ���������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+ }
+
+ if (childMethodExecution != null && childMethodExecution.isConstructor()) {
+ // �Ăяo���悪�R���X�g���N�^�������ꍇ
+ int newIndex = objList.indexOf(childMethodExecution.getThisObjId());
+ if (newIndex != -1) {
+ // �Ăяo���悪�ǐՑΏۂ̃R���X�g���N�^��������field�Ɠ��l�ɏ���
+ removeList.add(childMethodExecution.getThisObjId());
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ }
+
+ if (childMethodExecution != null && Trace.getMethodName(childMethodExecution.getSignature()).startsWith("access$")) {
+ // �G���N���[�W���O�C���X�^���X�ɑ��郁�\�b�h�Ăяo���������ꍇ
+ String enclosingObj = childMethodExecution.getArguments().get(0).getId(); // �G���N���[�W���O�C���X�^���X�͑������ɓ����Ă���炵��
+ int encIndex = objList.indexOf(enclosingObj);
+ if (encIndex != -1) {
+ // thisObject �ɒu����������Afield�Ɠ��l�ɏ���
+ removeList.add(enclosingObj);
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ }
+
+ // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch���ċA�Ăяo��
+ while (tracePoint.stepBackOver()) {
+ Statement statement = tracePoint.getStatement();
+ // ���ڎQ�ƁA�t�B�[���h�Q�Ƃ���єz��A�N�Z�X�̒T��
+ if (statement instanceof FieldAccess) {
+ FieldAccess fs = (FieldAccess)statement;
+ String refObjectId = fs.getValueObjId();
+ int index = objList.indexOf(refObjectId);
+ if (index != -1) {
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ removeList.add(refObjectId);
+ existsInFields++; // set�������get�����o������\��������
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ
+ if (refObjectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(ownerObjectId, refObjectId,
+ fs.getContainerClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ } else if(refObjectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(ownerObjectId, refObjectId,
+ fs.getContainerClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ }
+ objList.set(index, ownerObjectId);
+ }
+ }
+ } else if (statement instanceof ArrayAccess) {
+ ArrayAccess aa = (ArrayAccess)statement;
+ String elementObjectId = aa.getValueObjectId();
+ int index = objList.indexOf(elementObjectId);
+ if (index != -1) {
+ // �z��A�N�Z�X�̏ꍇ
+ String arrayObjectId = aa.getArrayObjectId();
+ if (elementObjectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(arrayObjectId, elementObjectId,
+ aa.getArrayClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(arrayObjectId, aa.getArrayClassName());
+ } else if(elementObjectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(arrayObjectId, elementObjectId,
+ aa.getArrayClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(arrayObjectId, aa.getArrayClassName());
+ }
+ objList.set(index, arrayObjectId);
+ }
+ } else if (statement instanceof ArrayCreate) {
+ ArrayCreate ac = (ArrayCreate)statement;
+ String arrayObjectId = ac.getArrayObjectId();
+ int index = objList.indexOf(arrayObjectId);
+ if (index != -1) {
+ // �z���̏ꍇfield�Ɠ��l�ɏ���
+ creationList.add(arrayObjectId);
+ removeList.add(arrayObjectId);
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ }
+ } else if (statement instanceof MethodInvocation) {
+ MethodExecution prevChildMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ if (!prevChildMethodExecution.equals(childMethodExecution)) {
+ // �߂�l
+ ObjectReference ret = prevChildMethodExecution.getReturnValue();
+ if (ret != null) {
+ int retIndex = -1;
+ retIndex = objList.indexOf(ret.getId());
+ if (retIndex != -1) {
+ // �߂�l���R��������
+ prevChildMethodExecution.setAugmentation(new DeltaAugmentationInfo());
+ if (prevChildMethodExecution.isConstructor()) {
+ // �ǐՑΏۂ�constractor���Ă�ł�����(�I�u�W�F�N�g�̐�����������)field�Ɠ��l�ɏ���
+ String newObjId = ret.getId();
+ creationList.add(newObjId);
+ removeList.add(newObjId);
+ existsInFields++;
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(newObjId)); // �ǐՑΏ�
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setSetterSide(false); // getter�Ăяo���Ɠ��l
+ continue;
+ }
+ String retObj = objList.get(retIndex);
+ if (removeList.contains(retObj)) {
+ // ��xget�Ō��o���ăt�B�[���h�Ɉˑ����Ă���Ɣ��f�������{���̗R�����߂�l���������Ƃ����������̂ŁA�t�B�[���h�ւ̈ˑ����L�����Z������
+ removeList.remove(retObj);
+ existsInFields--;
+ if (existsInFields == 0) {
+ removeList.remove(thisObjectId);
+ }
+ }
+ ((DeltaAugmentationInfo)prevChildMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(retObj)); // �ǐՑΏ�
+ TracePoint prevChildTracePoint = tracePoint.duplicate();
+ prevChildTracePoint.stepBackNoReturn();
+ calleeSearch(trace, prevChildTracePoint, objList, prevChildMethodExecution.isStatic(), retIndex); // �Ăяo�����T��
+ if (objList.get(retIndex) != null && objList.get(retIndex).equals(prevChildMethodExecution.getThisObjId())
+ && thisObjectId.equals(prevChildMethodExecution.getThisObjId())) {
+ // �Ăяo����Ńt�B�[���h�Ɉˑ����Ă����ꍇ�̏���
+ removeList.add(thisObjectId); // ��ň�U�AthisObject ����菜��
+ isTrackingThis = true; // �Ăяo�����T���O�ɕ���
+ }
+ if (isLost) {
+ checkList.add(objList.get(retIndex));
+ isLost = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ // --- ���̎��_�� tracePoint �͌Ăяo�������w���Ă��� ---
+
+ // �R���N�V�����^�Ή�
+ if (methodExecution.isCollectionType()) {
+ objList.add(thisObjectId);
+ }
+
+ // �����̎擾
+ ArrayList argments = methodExecution.getArguments();
+
+ // �����ƃt�B�[���h�ɓ���ID�̃I�u�W�F�N�g������ꍇ��z��
+ Reference r;
+ for (int i = 0; i < removeList.size(); i++) {
+ String removeId = removeList.get(i);
+ if (argments.contains(new ObjectReference(removeId))) {
+ removeList.remove(removeId); // �t�B�[���h�ƈ����̗����ɒǐՑΏۂ����݂����ꍇ�A������D��
+ } else if(objList.contains(removeId)) {
+ // �t�B�[���h�ɂ����Ȃ������ꍇ(�������A�I�u�W�F�N�g�̐������t�B�[���h�Ɠ��l�Ɉ���)
+ objList.remove(removeId); // �ǐՑΏۂ���O��
+ if (!removeId.equals(thisObjectId)) {
+ // �t�B�[���h�ithis ���� removeId �ւ̎Q�Ɓj���f���^�̍\���v�f�ɂȂ�
+ if (removeId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����?
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else if (removeId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCreation(creationList.contains(removeId)); // �I�u�W�F�N�g�̐�����?
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ }
+ }
+ }
+ // --- ���̎��_�� this ���ǐՑΏۂł������Ƃ��Ă� objList �̒����炢������폜����Ă��� ---
+
+ // �����T��
+ boolean existsInAnArgument = false;
+ for (int i = 0; i < objList.size(); i++) {
+ String objectId = objList.get(i);
+ if (objectId != null) {
+ ObjectReference trackingObj = new ObjectReference(objectId);
+ if (argments.contains(trackingObj)) {
+ // �������R��������
+ existsInAnArgument = true;
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId));
+ } else {
+ // �R�����ǂ��ɂ�������Ȃ�����
+ boolean isSrcSide2 = true;
+ trackingObj = null;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide2 = true;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide2 = false;
+ trackingObj = dstObject;
+ }
+ }
+ }
+ }
+ if (existsInAnArgument) {
+ // ������1�ł��ǐՑΏۂ����݂����ꍇ
+ if (existsInFields > 0 || isTrackingThis) {
+ // this�I�u�W�F�N�g��ǐՒ��̏ꍇ
+ if (!Trace.isNull(thisObjectId)) {
+ objList.add(thisObjectId); // ����ɒT������ꍇ�A��U��菜���� thisObject ��
+ } else {
+ objList.add(null); // ������static�Ăяo���������ꍇ�A����ȏ�ǐՂ��Ȃ�
+ }
+ }
+ if (tracePoint.isValid()) {
+ finalCount = 0;
+ return callerSearch(trace, tracePoint, objList, methodExecution); // �Ăяo����������ɒT��
+ }
+ }
+
+ for (int i = 0; i < objList.size(); i++) {
+ objList.remove(null);
+ }
+ if (objList.isEmpty()) {
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(true);
+ } else {
+ // �R���������ł��Ȃ�����
+ if (!methodExecution.isStatic()) {
+ finalCount++;
+ if (finalCount <= LOST_DECISION_EXTENSION) {
+ // final�ϐ����Q�Ƃ��Ă���ꍇ�R���������ł��Ȃ��\��������̂ŁA�ǐՂ������I�������P�\���Ԃ�݂���
+ if (tracePoint.isValid()) {
+ MethodExecution c = callerSearch(trace, tracePoint, objList, methodExecution); // �Ăяo����������ɒT��
+ if (((DeltaAugmentationInfo)c.getAugmentation()).isCoodinator()) {
+ methodExecution = c; // �ǐՂ𑱂������ʃR�[�f�B�l�[�^����������
+ }
+ }
+ } else if (thisObj.getActualType().contains("$")) {
+ // �����������܂��͖����N���X�̏ꍇ�A���������I�u�W�F�N�g���O�����\�b�h�̓���final�ϐ�����擾�����Ƃ݂Ȃ��A����Ɏ����̒��̃t�B�[���h�̈��Ƃ݂Ȃ�
+ for (int i = objList.size() - 1; i >= 0; i--) {
+ String objectId = objList.get(i);
+ if (objectId != null) {
+ ObjectReference trackingObj = new ObjectReference(objectId);
+ boolean isSrcSide2 = true;
+ trackingObj = null;
+ if (objectId.equals(srcObject.getId())) {
+ isSrcSide2 = true;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ isSrcSide2 = false;
+ trackingObj = dstObject;
+ }
+ if (trackingObj != null) {
+ r = new Reference(thisObjectId, trackingObj.getId(),
+ methodExecution.getThisClassName(), trackingObj.getActualType());
+ r.setFinalLocal(true);
+ if (isSrcSide2) {
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ isSrcSide = true;
+ } else {
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ isSrcSide = false;
+ }
+ existsInFields++;
+ objList.remove(objectId);
+ }
+ }
+ }
+ }
+ }
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setCoodinator(false);
+ }
+ finalCount = 0;
+ return methodExecution;
+ }
+
+ /**
+ * �f���^���o�A���S���Y���̌Ăяo����T������(�ċA�Ăяo���ɂȂ��Ă���)
+ * @param trace ��͑Ώۃg���[�X
+ * @param methodExecution �T�����郁�\�b�h���s
+ * @param objList �ǐՒ��̃I�u�W�F�N�g
+ * @param isStatic�@�ÓI���\�b�h���ۂ�
+ * @param index�@objList���̂ǂ̃I�u�W�F�N�g��ǐՂ��Ă��̃��\�b�h���s�ɓ����Ă����̂�
+ * @throws TraceFileException
+ */
+ protected void calleeSearch(Trace trace, TracePoint tracePoint, ArrayList objList, Boolean isStatic, int index) {
+ MethodExecution methodExecution = tracePoint.getMethodExecution();
+ Boolean isResolved = false;
+ String objectId = objList.get(index); // calleeSearch() �ł͒ǐՑΏۂ̃I�u�W�F�N�g�͈�����A��objList��index�Ԗڂ̗v�f�ȊO�ύX���Ă͂����Ȃ�
+ String thisObjectId = methodExecution.getThisObjId();
+ ObjectReference thisObj = new ObjectReference(thisObjectId, methodExecution.getThisClassName(),
+ Trace.getDeclaringType(methodExecution.getSignature(), methodExecution.isConstructor()),
+ Trace.getDeclaringType(methodExecution.getCallerSideSignature(), methodExecution.isConstructor()));
+
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(false); // ��{�I��getter�Ăяo���̂͂������A����
+ ArrayList argments = methodExecution.getArguments();
+ ObjectReference trackingObj = null;
+ //static���o�R�����null�������Ă��鎞������
+ if (objectId != null) {
+ String returnType = Trace.getReturnType(methodExecution.getSignature());
+ if (objectId.equals(srcObject.getId())) {
+ trackingObj = srcObject;
+ trackingObj.setCalleeType(returnType);
+ } else if(objectId.equals(dstObject.getId())) {
+ trackingObj = dstObject;
+ trackingObj.setCalleeType(returnType);
+ } else {
+ trackingObj = new ObjectReference(objectId, null, returnType);
+ }
+
+ Reference r;
+ // �߂�l�ɒT���Ώۂ��܂܂�Ă����calleeSearch�Ăяo��
+ do {
+ if (!tracePoint.isValid()) break;
+ Statement statement = tracePoint.getStatement();
+ // ���ڎQ�Ƃ���уt�B�[���h�Q�Ƃ̒T��
+ if (statement instanceof FieldAccess) {
+ FieldAccess fs = (FieldAccess)statement;
+ if (objectId != null && objectId.equals(fs.getValueObjId())) {
+ String ownerObjectId = fs.getContainerObjId();
+ if (ownerObjectId.equals(thisObjectId)) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(thisObj, srcObject));
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(thisObj, dstObject));
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ } else {
+ // ���ڎQ�Ƃ̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(ownerObjectId, objectId,
+ fs.getContainerClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(ownerObjectId, objectId,
+ fs.getContainerClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(ownerObjectId, fs.getContainerClassName());
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(ownerObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = ownerObjectId;
+ objList.set(index, objectId);
+ }
+ isResolved = true;
+ }
+ } else if (statement instanceof ArrayAccess) {
+ ArrayAccess aa = (ArrayAccess)statement;
+ if (objectId != null && objectId.equals(aa.getValueObjectId())) {
+ // �z��A�N�Z�X�̏ꍇ
+ String arrayObjectId = aa.getArrayObjectId();
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(arrayObjectId, objectId,
+ aa.getArrayClassName(), srcObject.getActualType()));
+ srcObject = new ObjectReference(arrayObjectId, aa.getArrayClassName());
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(arrayObjectId, objectId,
+ aa.getArrayClassName(), dstObject.getActualType()));
+ dstObject = new ObjectReference(arrayObjectId, aa.getArrayClassName());
+ trackingObj = dstObject;
+ }
+ objectId = arrayObjectId;
+ objList.set(index, objectId);
+ isResolved = true;
+ }
+ } else if (statement instanceof ArrayCreate) {
+ ArrayCreate ac = (ArrayCreate)statement;
+ if (objectId != null && objectId.equals(ac.getArrayObjectId())) {
+ // �z���̏ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ eStructure.addSrcSide(new Reference(thisObj, srcObject));
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if(objectId.equals(dstObject.getId())) {
+ eStructure.addDstSide(new Reference(thisObj, dstObject));
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ }
+ } else if (statement instanceof MethodInvocation) {
+ // �߂�l
+ MethodExecution childMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ ObjectReference ret = childMethodExecution.getReturnValue();
+ if (ret != null && objectId != null && objectId.equals(ret.getId())) {
+ childMethodExecution.setAugmentation(new DeltaAugmentationInfo());
+ ((DeltaAugmentationInfo)childMethodExecution.getAugmentation()).setTraceObjectId(Integer.parseInt(objectId));
+ TracePoint childTracePoint = tracePoint.duplicate();
+ childTracePoint.stepBackNoReturn();
+ calleeSearch(trace, childTracePoint, objList, childMethodExecution.isStatic(), index); // �Ăяo���������ɒT��
+ if (childMethodExecution.isConstructor()) {
+ // �R���X�g���N�^�Ăяo���������ꍇ
+ if (objectId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCreation(true);
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCreation(true);
+ eStructure.addDstSide(r);
+ dstObject = thisObj;
+ trackingObj = dstObject;
+ }
+ if (Trace.isNull(thisObjectId)) objectId = null; // static�ϐ��̏ꍇ
+ else objectId = thisObjectId;
+ objList.set(index, objectId);
+ isResolved = true;
+ isLost = false;
+ continue;
+ }
+ objectId = objList.get(index);
+ if (objectId == null) {
+ // static�Ăяo���̖߂�l�������ꍇ�i���Ԃ�j
+ trackingObj = null;
+ isResolved = true;
+ } else if (objectId.equals(srcObject.getId())) {
+ trackingObj = srcObject;
+ } else if (objectId.equals(dstObject.getId())) {
+ trackingObj = dstObject;
+ }
+ if (isLost) {
+ checkList.add(objList.get(index));
+ isLost = false;
+ }
+ }
+ }
+ } while (tracePoint.stepBackOver());
+
+ //�����T��
+ if (argments.contains(new ObjectReference(objectId))) {
+ ((DeltaAugmentationInfo)methodExecution.getAugmentation()).setSetterSide(true); // �������K�v?
+ isResolved = true;
+ }
+ }
+
+ //�R���N�V�����^�Ή�
+ Reference r;
+ if (methodExecution.isCollectionType()) {
+ if (objectId != null) {
+ // �R���N�V�����^�̏ꍇ�A�����ŌX�̗v�f�ڕێ����Ă���Ɖ��肷��
+ if (objectId.equals(srcObject.getId())) {
+ r = new Reference(thisObj, srcObject);
+ r.setCollection(true);
+ eStructure.addSrcSide(r);
+ srcObject = thisObj;
+ } else if(objectId.equals(dstObject.getId())) {
+ r = new Reference(thisObj, dstObject);
+ r.setCollection(true);
+ eStructure.addDstSide(r);
+ dstObject =thisObj;
+ }
+ }
+ objList.set(index, methodExecution.getThisObjId());
+ isResolved = true; // �K�v�Ȃ̂ł�?
+ }
+
+ if (objectId == null && isResolved && !isStatic) { // static �Ăяo������̖߂�l��Ԃ��Ă���ꍇ
+ objList.set(index, thisObjectId); // ������ǐՂ�����
+ if (Trace.isNull(srcObject.getId())) {
+ srcObject = thisObj;
+ } else if (Trace.isNull(dstObject.getId())) {
+ dstObject = thisObj;
+ }
+ }
+
+ if (isStatic && !isResolved) { // ���͋N���肦�Ȃ�?(get�|�C���g�J�b�g���擾����悤�ɂ�������)
+ objList.set(index, null);
+ }
+ if(!isStatic && !isResolved){
+ isLost = true; // final�ϐ�������N���X�ŎQ�Ƃ��Ă���\�������邪�AcalleeSearch()�͕K���Ăяo�����ɕ��A���Ă����̂ŁA�����ł͉������Ȃ�
+ }
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/ExtractedStructure.java b/src/org/ntlab/traceDebugger/analyzerProvider/ExtractedStructure.java
new file mode 100644
index 0000000..9f0a275
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/ExtractedStructure.java
@@ -0,0 +1,68 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+
+
+public class ExtractedStructure {
+
+ private Delta delta = new Delta();
+ private MethodExecution coordinator = null;
+ private MethodExecution parent = null;
+ private MethodExecution creationCallTree;
+
+ public Delta getDelta() {
+ return delta;
+ }
+
+ public MethodExecution getCoordinator() {
+ return coordinator;
+ }
+
+ /**
+ * ������ ������ɍ폜���邱��
+ * @param coordinator
+ */
+ public void setCoordinator(MethodExecution coordinator) {
+ this.coordinator = coordinator;
+ }
+
+ public void createParent(MethodExecution methodExecution) {
+ coordinator = methodExecution;
+ parent = null;
+ }
+
+// public void addParent(MethodExecution callTree) {
+// if (parent == null)
+// coordinator.addChild(parent = callTree);
+// else
+// parent.addChild(parent = callTree);
+// }
+//
+// public void addChild(MethodExecution callTree) {
+// if (parent == null)
+// coordinator.addChild(callTree);
+// else
+// parent.addChild(callTree);
+// }
+//
+ public void addSrcSide(Reference reference) {
+ delta.addSrcSide(reference);
+ }
+
+ public void addDstSide(Reference reference) {
+ delta.addDstSide(reference);
+ }
+
+ public void changeParent() {
+ }
+
+ public void setCreationMethodExecution(MethodExecution callTree) {
+ creationCallTree = callTree;
+ }
+
+ public MethodExecution getCreationCallTree() {
+ return creationCallTree;
+ }
+
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.java b/src/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.java
new file mode 100644
index 0000000..468a23c
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.java
@@ -0,0 +1,237 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayCreate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ArrayUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldAccess;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.ObjectReference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+
+public class ObjectFlowAnalyzer extends AbstractAnalyzer {
+ private static ObjectFlowAnalyzer getInstance = null;
+
+ public ObjectFlowAnalyzer(Trace trace) {
+ super(trace);
+ }
+
+ private static ObjectFlowAnalyzer getInstance() {
+ if (getInstance == null) {
+ getInstance = new ObjectFlowAnalyzer(TraceJSON.getInstance());
+ }
+ return getInstance;
+ }
+
+ public static ArrayList findAllSeedAliasesStatic(MethodExecution me) {
+ return getInstance().findAllSeedAliases(me);
+ }
+
+ public ArrayList findAllSeedAliases(MethodExecution me) {
+ ArrayList seedAliasList = new ArrayList<>();
+ List statements = me.getStatements();
+ String[] primitives = {"byte", "short", "int", "long", "float", "double", "char", "boolean"};
+ List primitiveList = Arrays.asList(primitives);
+ for (int i = 0; i < statements.size(); i++) {
+ TracePoint tp = me.getTracePoint(i);
+ Statement statement = statements.get(i);
+ if (statement instanceof FieldAccess) {
+ FieldAccess fa = (FieldAccess)statement;
+ String objId = fa.getContainerObjId();
+ if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fa.getContainerClassName()))) {
+ seedAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_CONTAINER));
+ }
+ objId = fa.getValueObjId();
+ if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fa.getValueClassName()))) {
+ seedAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_FIELD));
+ }
+ } else if (statement instanceof FieldUpdate) {
+ FieldUpdate fu = (FieldUpdate)statement;
+ String objId = fu.getContainerObjId();
+ if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fu.getContainerClassName()))) {
+ seedAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_CONTAINER));
+ }
+ objId = fu.getValueObjId();
+ if (objId != null && !(objId.equals("0")) && !(primitiveList.contains(fu.getValueClassName()))) {
+ seedAliasList.add(new Alias(objId, tp, Alias.OCCURRENCE_EXP_FIELD));
+ }
+ } else if (statement instanceof ArrayAccess) {
+ ArrayAccess aa = (ArrayAccess)statement;
+ String valueObjId = aa.getValueObjectId();
+ if (valueObjId != null && !(valueObjId.equals("0")) && !(primitiveList.contains(aa.getValueClassName()))) {
+ seedAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_ARRAY));
+ }
+ } else if (statement instanceof ArrayUpdate) {
+ ArrayUpdate au = (ArrayUpdate)statement;
+ String valueObjId = au.getValueObjectId();
+ if (valueObjId != null && !(valueObjId.equals("0")) && !(primitiveList.contains(au.getValueClassName()))) {
+ seedAliasList.add(new Alias(valueObjId, tp, Alias.OCCURRENCE_EXP_ARRAY));
+ }
+ } else if (statement instanceof ArrayCreate) {
+ ArrayCreate ac = (ArrayCreate)statement;
+ String arrayObjId = ac.getArrayObjectId();
+ if (arrayObjId != null && !(arrayObjId.equals("0")) && !(primitiveList.contains(ac.getArrayClassName()))) {
+ seedAliasList.add(new Alias(arrayObjId, tp, Alias.OCCURRENCE_EXP_RETURN));
+ }
+ } else if (statement instanceof MethodInvocation) {
+ MethodExecution calledMe = ((MethodInvocation)statement).getCalledMethodExecution();
+ String thisObjId = calledMe.getThisObjId();
+ if (thisObjId != null && !(thisObjId.equals("0"))) {
+ seedAliasList.add(new Alias(thisObjId, tp, Alias.OCCURRENCE_EXP_RECEIVER));
+ }
+ List args = calledMe.getArguments();
+ for (int j = 0; j < args.size(); j++) {
+ ObjectReference arg = args.get(j);
+ String argValueId = arg.getId();
+ if (argValueId != null && !(argValueId.equals("0")) && !(primitiveList.contains(arg.getActualType()))) {
+ seedAliasList.add(new Alias(argValueId, tp, (j + Alias.OCCURRENCE_EXP_FIRST_ARG)));
+ }
+ }
+ ObjectReference returnValue = calledMe.getReturnValue();
+ if (returnValue != null) {
+ String returnValueId = returnValue.getId();
+ if (returnValueId != null && !(returnValueId.equals("0") && !(primitiveList.contains(returnValue.getActualType())))) {
+ seedAliasList.add(new Alias(returnValueId, tp, Alias.OCCURRENCE_EXP_RETURN));
+ }
+ }
+ }
+ }
+ return seedAliasList;
+ }
+
+ private TracePoint getRecentlyFieldUpdate(TracePoint tp) {
+ Statement statement = tp.getStatement();
+ if (statement instanceof FieldAccess) {
+ FieldAccess fa = (FieldAccess)statement;
+ return trace.getFieldUpdateTracePoint(fa.getReference(), tp);
+ }
+ return null;
+ }
+
+ private TracePoint getRecentlyArrayUpdate(TracePoint tp) {
+ Statement statement = tp.getStatement();
+ if (statement instanceof ArrayAccess) {
+ ArrayAccess aa = (ArrayAccess)statement;
+ // aa.getReference()���Ȃ��̂ʼn��ɂ�����ۂ�Reference������ēn��
+ return trace.getArraySetTracePoint(new Reference(aa.getArrayObjectId(), aa.getValueObjectId(), aa.getArrayClassName(), aa.getValueClassName()), tp);
+ }
+ return null;
+ }
+
+ public static ArrayList> getObjectFlowStatic(Alias startAlias) {
+ return getInstance().getObjectFlow(startAlias);
+ }
+
+ public ArrayList> getObjectFlow(Alias startAlias) {
+ ArrayList> aliasLists = new ArrayList<>();
+ ArrayList aliasList = new ArrayList<>();
+ aliasLists.add(aliasList);
+// aliasList.add(alias);
+ String objId = startAlias.getObjectId();
+ TracePoint tp = startAlias.getOccurrencePoint().duplicate();
+ ArrayList> resultLists = getObjectFlow(aliasLists, objId, tp, 0);
+ return resultLists;
+ }
+
+ private ArrayList> getObjectFlow(ArrayList> aliasLists,
+ String objId, TracePoint tp, int side) {
+ ArrayList aliasList = aliasLists.get(aliasLists.size() - 1); // ����getObjectFlow���\�b�h���s���Ō��������G�C���A�X�����Ă������X�g
+ do {
+ Statement statement = tp.getStatement();
+ if (statement instanceof FieldAccess) {
+ // �t�B�[���h�Q�Ƃ̏ꍇ
+ FieldAccess fa = (FieldAccess)statement;
+ if (fa.getValueObjId().equals(objId)) {
+ // ���Y�n�_�ł̃G�C���A�X�����X�g�ɒlj��������, �t�B�[���h�ŏI�X�V�ɔ�ԃp�^�[���Ƃ��̂܂ܑk��p�^�[���Ƃŕ���
+ aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_FIELD));
+ aliasList = new ArrayList<>(aliasList); // ���X�g���̂��f�B�[�v�R�s�[���Ă���(�t�B�[���h�ŏI�X�V�ɔ�ԍċA�����I�����, ���̂܂ܑk��p�^�[���ŗp����)
+ TracePoint fieldUpdateTp = getRecentlyFieldUpdate(tp);
+ aliasLists = getObjectFlow(aliasLists, objId, fieldUpdateTp, 0);
+ aliasLists.add(aliasList); // �ċA�����ɓ���O�Ƀf�B�[�v�R�s�[���Ă������X�g���Ō���ɒlj� (�ȍ~�̑k��ɂ���Č������G�C���A�X�͂��̃��X�g�ɓ������)
+ }
+ } else if (statement instanceof ArrayAccess) {
+ // �z��v�f�Q�Ƃ̏ꍇ
+ ArrayAccess aa = (ArrayAccess)statement;
+ if (aa.getValueObjectId().equals(objId)) {
+ aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_ARRAY));
+ aliasList = new ArrayList<>(aliasList);
+ TracePoint arrayUpdateTp = getRecentlyArrayUpdate(tp);
+ aliasLists = getObjectFlow(aliasLists, objId, arrayUpdateTp, 0);
+ aliasLists.add(aliasList);
+ }
+ } else if (statement instanceof FieldUpdate) {
+ // �t�B�[���h�X�V�̏ꍇ
+ FieldUpdate fu = (FieldUpdate)statement;
+ if (fu.getValueObjId().equals(objId)) {
+ aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_FIELD));
+ }
+ } else if (statement instanceof ArrayUpdate) {
+ // �z��v�f�X�V�̏ꍇ
+ ArrayUpdate au = (ArrayUpdate)statement;
+ if (au.getValueObjectId().equals(objId)) {
+ aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_ARRAY));
+ }
+ } else if (statement instanceof ArrayCreate) {
+ // �z���̏ꍇ
+ ArrayCreate ac = (ArrayCreate)statement;
+ if (ac.getArrayObjectId().equals(objId)) {
+ aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_RETURN)); // �z���� new �^��[] �̖߂�l
+ return aliasLists; // �z���ӏ��̓G�C���A�X�̋N���Ȃ̂ł���ȑO�ɂ͂����Ȃ��͂�
+ }
+ } else if (statement instanceof MethodInvocation) {
+ // ���\�b�h�Ăяo���̏ꍇ
+ MethodExecution calledMethodExecution = ((MethodInvocation)statement).getCalledMethodExecution();
+ ObjectReference returnValue = calledMethodExecution.getReturnValue();
+ if (returnValue.getId().equals(objId)) {
+ // �߂�l�ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ
+ ArrayList aliasListBeforeMethodBackEntry = new ArrayList<>(aliasList); // �Ăяo����̃��\�b�h���s�ɐ���O�̃G�C���A�X���X�g���R�s�[���Ă���
+ aliasList.add(new Alias(objId, tp.duplicate(), Alias.OCCURRENCE_EXP_RETURN));
+ if (calledMethodExecution.isConstructor()) {
+ return aliasLists; // �R���X�g���N�^�Ăяo���ӏ��̓G�C���A�X�̋N���Ȃ̂ł���ȑO�ɂ͂����Ȃ��͂�
+ }
+ TracePoint exitTp = calledMethodExecution.getExitPoint(); // �Ăяo�����\�b�h���s�̍ŏI�X�e�[�g�����g���w��tp���擾
+ aliasLists = getObjectFlow(aliasLists, objId, exitTp, side + 1); // �Ăяo����̃��\�b�h���s�ɐ���
+ aliasList = aliasLists.get(aliasLists.size() - 1);
+ if (aliasList.get(aliasList.size() - 1).isOrigin()) {
+ // �Ăяo����̃��\�b�h���s�ɐ�������ł��̃I�u�W�F�N�g�̋N��(�R���X�g���N�^or�z��)�ɓ��B���Ă����ꍇ, �Ăяo����̃��\�b�h���s�ɐ���O�̃��X�g��p���ĐV�K�ɒǐՂs����
+ aliasLists.add(aliasListBeforeMethodBackEntry);
+ aliasList = aliasListBeforeMethodBackEntry;
+ }
+ }
+ }
+ } while (tp.stepBackOver()); // �Ăяo�����ɖ߂邩����ȏ�H��Ȃ��Ȃ�܂Ń��[�v
+ if (!tp.isValid()) {
+ return aliasLists; // ����ȏチ�\�b�h���s��k��Ȃ��ꍇ(main���\�b�h�̂���ɑO�Ȃ�)�͂��̎��_�ŏI��
+ }
+ // --- ���̎��_�� tracePoint�� �Ăяo�������w���Ă��� (���O�܂ők���Ă������\�b�h���s�ɂ��Ẵ��\�b�h�Ăяo�����w���Ă���) ---
+ MethodExecution calledMethodExecution = ((MethodInvocation)tp.getStatement()).getCalledMethodExecution();
+ ArrayList args = calledMethodExecution.getArguments();
+ boolean isExistingInArgs = false;
+ for (int i = 0; i < args.size(); i++) {
+ if (args.get(i).getId().equals(objId)) {
+ // ���\�b�h�Ăяo���̎������ɃG�C���A�X�̃I�u�W�F�N�gID����v�����ꍇ
+ aliasList.add(new Alias(objId, tp.duplicate(), (i + Alias.OCCURRENCE_EXP_FIRST_ARG)));
+ isExistingInArgs = true;
+ if (side == 0) {
+ // �T���J�n���\�b�h���s�܂��̓t�B�[���h��z��v�f�̍ŏI�X�V�T���Ŕ��̃��\�b�h���s����, �X�^�b�N�g���[�X�ł��ǂ��S���\�b�h���s�̏ꍇ
+ TracePoint previousTp = tp.duplicate();
+ previousTp.stepBackOver();
+ aliasLists = getObjectFlow(aliasLists, objId, previousTp, 0); // �Ăяo�����̃��\�b�h���s�ɖ߂�
+ }
+ }
+ }
+ if (!isExistingInArgs) {
+ aliasLists.remove(aliasLists.size() - 1); // �����ɃG�C���A�X���Ȃ������ꍇ�͂��̉�̒ǐՃG�C���A�X���X�g���폜����
+ }
+ return aliasLists;
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzerLaunchConfiguration.java b/src/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzerLaunchConfiguration.java
new file mode 100644
index 0000000..d48312e
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzerLaunchConfiguration.java
@@ -0,0 +1,28 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.ntlab.traceAnalysisPlatform.IAdditionalLaunchConfiguration;
+
+public class ObjectFlowAnalyzerLaunchConfiguration implements IAdditionalLaunchConfiguration {
+ public static final String ANALYZER_PATH = "org/ntlab/traceDebugger/analyzerProvider/ObjectFlowAnalyzer.class";
+ public static final String ANALYZER_PACKAGE = "org.ntlab.traceDebugger.analyzerProvider";
+ public static final String ANALYZER_CLASS = "ObjectFlowAnalyzer";
+
+ @Override
+ public String[] getAdditionalClasspaths() {
+ try {
+ List classPathList = new ArrayList<>();
+ String tracerClassPath = FileLocator.resolve(this.getClass().getClassLoader().getResource(ANALYZER_PATH)).getPath();
+ String classPath = tracerClassPath.substring(0, tracerClassPath.length() - ANALYZER_PATH.length());
+ classPathList.add(classPath);
+ return classPathList.toArray(new String[classPathList.size()]);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ throw new IllegalStateException();
+ }
+}
diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/ReferencePoint.java b/src/org/ntlab/traceDebugger/analyzerProvider/ReferencePoint.java
new file mode 100644
index 0000000..f416d50
--- /dev/null
+++ b/src/org/ntlab/traceDebugger/analyzerProvider/ReferencePoint.java
@@ -0,0 +1,90 @@
+package org.ntlab.traceDebugger.analyzerProvider;
+
+import java.util.List;
+
+import org.ntlab.traceAnalysisPlatform.tracer.trace.FieldUpdate;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodExecution;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.MethodInvocation;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Reference;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.Statement;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TraceJSON;
+import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint;
+import org.ntlab.traceDebugger.TraceBreakPoint;
+
+public class ReferencePoint {
+ private Reference reference;
+ private MethodExecution methodExecution;
+ private Statement statement;
+
+ public ReferencePoint(Reference reference, MethodExecution methodExecution, long beforeTime) {
+ this.reference = reference;
+ this.methodExecution = methodExecution;
+ findFieldUpdate(beforeTime);
+ }
+
+ public ReferencePoint(Reference reference, MethodExecution methodExecution, Statement statement) {
+ this.reference = reference;
+ this.methodExecution = methodExecution;
+ this.statement = statement;
+ }
+
+ private void findFieldUpdate(long beforeTime) {
+ List statements = methodExecution.getStatements();
+ for (int i = statements.size() - 1; i >= 0; i--) {
+ Statement statement = statements.get(i);
+ if (!(statement instanceof FieldUpdate)) continue;
+ if (statement.getTimeStamp() > beforeTime) continue;
+ FieldUpdate fu = (FieldUpdate)statement;
+ if (fu.getContainerObjId().equals(reference.getSrcObjectId())
+ && fu.getValueObjId().equals(reference.getDstObjectId())) {
+ this.statement = fu;
+ return;
+ }
+ }
+ }
+
+ public Reference getReference() {
+ return reference;
+ }
+
+ public MethodExecution getMethodExecution() {
+ return methodExecution;
+ }
+
+ public int getLineNo() {
+ return (statement != null) ? statement.getLineNo() : -1;
+ }
+
+ public long getTime() {
+ if (statement instanceof MethodInvocation) {
+ return ((MethodInvocation)statement).getCalledMethodExecution().getEntryTime();
+ }
+ return statement.getTimeStamp();
+ }
+
+ public TracePoint getTracePoint() {
+ int order = 0;
+ for (Statement statement : methodExecution.getStatements()) {
+ if (statement.equals(this.statement)) break;
+ order++;
+ }
+ return new TracePoint(methodExecution, order);
+ }
+
+ public String getReferenceMessage() {
+ if (reference == null) return "";
+ StringBuilder ref = new StringBuilder();
+ ref.append(reference.getSrcClassName() + "(" + reference.getSrcObjectId() + ")");
+ ref.append(" -> ");
+ ref.append(reference.getDstClassName() + "(" + reference.getDstObjectId() + ")");
+ return ref.toString();
+ }
+
+ @Override
+ public String toString() {
+ int lineNo = getLineNo();
+ String location = methodExecution.getSignature() + " line: " + lineNo;
+ String ref = getReferenceMessage();
+ return String.format("%-50s %s", location, ref);
+ }
+}
\ No newline at end of file