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