Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2008-05-22 18:55:32 +0000
committereutarass2008-05-22 18:55:32 +0000
commit363e284ad7141758ab5c0183ca5af6285a86c34e (patch)
tree4a903dc7e9a04295e44931fde1298830d70c55be /plugins
parenta14d5f1565f99ed710c8c65c24f2408519fe14eb (diff)
downloadorg.eclipse.tcf-363e284ad7141758ab5c0183ca5af6285a86c34e.tar.gz
org.eclipse.tcf-363e284ad7141758ab5c0183ca5af6285a86c34e.tar.xz
org.eclipse.tcf-363e284ad7141758ab5c0183ca5af6285a86c34e.zip
1. TCF Debugger: implemented source code lookup and display.
2. TCF Debugger: implemented instruction pointer editor annotations. 3. TCF Agent: fixed Run Control and Diagnostics terminate commands. 4. Improved tests. 5. Various minor bug fixes.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties7
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml44
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java47
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/adapters/TCFLaunchAdapterFactory.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java6
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java187
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationImageProvider.java21
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java381
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java187
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelPresentation.java214
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java3
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java5
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java34
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java2
17 files changed, 928 insertions, 223 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF
index 6380463c6..db9d6e2a9 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF
@@ -8,6 +8,9 @@ Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.text,
org.eclipse.debug.core,
org.eclipse.debug.ui,
org.eclipse.tm.tcf.debug,
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties
index 0c99bf9d4..052dc5e6c 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties
@@ -8,6 +8,9 @@
# Contributors:
# Wind River Systems - initial implementation
###############################################################################
-pluginName = TCF/Eclipse Debugger Integration UI
-providerName = Eclipse.org
+pluginName=TCF/Eclipse Debugger Integration UI
+providerName=Eclipse.org
+
+debugCurrentInstructionPointer=Debug Current Instruction Pointer
+debugCallStack=Debug Call Stack
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
index 57d19127c..b593b7cfe 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
@@ -83,4 +83,48 @@
</perspectiveExtension>
</extension>
+ <extension point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ name="org.eclipse.tm.tcf.debug.top_frame">
+ </type>
+ <type
+ name="org.eclipse.tm.tcf.debug.stack_frame">
+ </type>
+ </extension>
+
+ <extension point="org.eclipse.ui.editors.markerAnnotationSpecification">
+ <specification
+ annotationImageProvider="org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationImageProvider"
+ annotationType="org.eclipse.tm.tcf.debug.top_frame"
+ colorPreferenceKey="currentIPColor"
+ colorPreferenceValue="198,219,174"
+ highlightPreferenceKey="currentIPHighlight"
+ highlightPreferenceValue="true"
+ label="%debugCurrentInstructionPointer"
+ overviewRulerPreferenceKey="currentIPOverviewRuler"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="6"
+ textPreferenceKey="currentIPIndication"
+ textPreferenceValue="false"
+ verticalRulerPreferenceKey="currentIPVerticalRuler"
+ verticalRulerPreferenceValue="true">
+ </specification>
+ <specification
+ annotationImageProvider="org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationImageProvider"
+ annotationType="org.eclipse.tm.tcf.debug.stack_frame"
+ colorPreferenceKey="secondaryIPColor"
+ colorPreferenceValue="219,235,204"
+ highlightPreferenceKey="secondaryIPHighlight"
+ highlightPreferenceValue="true"
+ label="%debugCallStack"
+ overviewRulerPreferenceKey="secondaryIPOverviewRuler"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="6"
+ textPreferenceKey="secondaryIPIndication"
+ textPreferenceValue="false"
+ verticalRulerPreferenceKey="secondaryIPVerticalRuler"
+ verticalRulerPreferenceValue="true">
+ </specification>
+ </extension>
+
</plugin>
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
index ff1ae2792..50697c1dd 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
@@ -10,6 +10,9 @@
*******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationManager;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModelManager;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Bundle;
@@ -29,13 +32,20 @@ public class Activator extends AbstractUIPlugin {
// The shared instance
private static Activator plugin;
private static TCFModelManager model_manager;
+ private static TCFAnnotationManager annotation_manager;
private static final BundleListener bundle_listener = new BundleListener() {
public void bundleChanged(BundleEvent event) {
if (plugin != null && event.getBundle() == plugin.getBundle() &&
- plugin.getBundle().getState() != Bundle.ACTIVE && model_manager != null) {
- model_manager.dispose();
- model_manager = null;
+ plugin.getBundle().getState() != Bundle.ACTIVE) {
+ if (model_manager != null) {
+ model_manager.dispose();
+ model_manager = null;
+ }
+ if (annotation_manager != null) {
+ annotation_manager.dispose();
+ annotation_manager = null;
+ }
}
}
};
@@ -75,9 +85,9 @@ public class Activator extends AbstractUIPlugin {
}
/**
- * Returns the shared TCFModel instance
+ * Returns the shared TCFModelManager instance
*
- * @return the shared TCFModel instance
+ * @return the shared TCFModelManager instance
*/
public static TCFModelManager getModelManager() {
if (plugin != null && model_manager == null && plugin.getBundle().getState() == Bundle.ACTIVE) {
@@ -85,4 +95,31 @@ public class Activator extends AbstractUIPlugin {
}
return model_manager;
}
+
+ /**
+ * Returns the shared TCFAnnotationManager instance
+ *
+ * @return the shared TCFAnnotationManager instance
+ */
+ public static TCFAnnotationManager getAnnotationManager() {
+ if (plugin != null && annotation_manager == null && plugin.getBundle().getState() == Bundle.ACTIVE) {
+ annotation_manager = new TCFAnnotationManager();
+ }
+ return annotation_manager;
+ }
+
+ /**
+ * Send error message into Eclipse log.
+ * @param msg - error message test
+ * @param err - exception
+ */
+ public static void log(String msg, Throwable err) {
+ if (plugin == null || plugin.getLog() == null) {
+ err.printStackTrace();
+ }
+ else {
+ plugin.getLog().log(new Status(IStatus.ERROR,
+ plugin.getBundle().getSymbolicName(), IStatus.OK, msg, err));
+ }
+ }
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/adapters/TCFLaunchAdapterFactory.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/adapters/TCFLaunchAdapterFactory.java
index c68394991..bf444c43b 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/adapters/TCFLaunchAdapterFactory.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/adapters/TCFLaunchAdapterFactory.java
@@ -28,7 +28,7 @@ public class TCFLaunchAdapterFactory implements IAdapterFactory {
IElementContentProvider.class,
IElementLabelProvider.class,
IModelProxyFactory.class,
- ITerminateHandler.class
+ ITerminateHandler.class,
};
private final IElementLabelProvider launch_label_provider = new TCFLaunchLabelProvider();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
index c6113dab6..ce3998550 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
@@ -757,6 +757,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
private int last_count = 0;
private int last_total = 0;
public void progress(final String label_text, final int count_done, final int count_total) {
+ assert test[0] != null;
if ((label_text == null || last_text.equals(label_text)) &&
last_total == count_total &&
(count_done - last_count) / (float)count_total < 0.02f) return;
@@ -773,7 +774,8 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
});
}
public void done(final Collection<Throwable> errors) {
- final boolean b = test[0] == null ? false : test[0].isCanceled();
+ assert test[0] != null;
+ final boolean b = test[0].isCanceled();
test[0] = null;
display.asyncExec(new Runnable() {
public void run() {
@@ -782,7 +784,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
new TestErrorsDialog(getControl().getShell(),
getImage("icons/tcf.gif"), errors).open();
}
- else if (loop && !b) {
+ else if (loop && !b && display != null) {
runDiagnostics(item, true, test, shell, label, bar);
}
else {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java
index 561e5924c..79efc47e1 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java
@@ -81,7 +81,7 @@ class TCFSelfTest {
private interface Test {
}
- TCFSelfTest(IPeer peer, TestListener listener) throws IOException {
+ TCFSelfTest(final IPeer peer, TestListener listener) throws IOException {
this.listener = listener;
pending_tests.add(new Runnable() {
public void run() {
@@ -90,6 +90,11 @@ class TCFSelfTest {
});
pending_tests.add(new Runnable() {
public void run() {
+ for (IChannel channel : channels) new TestAttachTerminate(channel);
+ }
+ });
+ pending_tests.add(new Runnable() {
+ public void run() {
int i = 0;
for (IChannel channel : channels) new TestRCBP1(channel, i++);
}
@@ -102,16 +107,25 @@ class TCFSelfTest {
pending_tests.add(new Runnable() {
public void run() {
for (int i = 0; i < channels.length; i++) {
- switch (i % 3) {
+ switch (i % 4) {
case 0: new TestEcho(channels[i]); break;
- case 1: new TestRCBP1(channels[i], i); break;
- case 2: new TestFileSystem(channels[i]); break;
+ case 1: new TestAttachTerminate(channels[i]); break;
+ case 2: new TestRCBP1(channels[i], i); break;
+ case 3: new TestFileSystem(channels[i]); break;
}
}
}
});
count_total = NUM_CHANNELS * pending_tests.size() * 2;
channels = new IChannel[NUM_CHANNELS];
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ openChannels(peer);
+ }
+ });
+ }
+
+ private void openChannels(IPeer peer) {
listener.progress("Openning communication channels...", count_done, count_total);
for (int i = 0; i < channels.length; i++) {
final IChannel channel = channels[i] = peer.openChannel();
@@ -239,6 +253,168 @@ class TCFSelfTest {
}
}
+ private class TestAttachTerminate implements Test, IRunControl.RunControlListener {
+
+ private final IDiagnostics diag;
+ private final IRunControl rc;
+
+ private final HashMap<String,IRunControl.RunControlContext> map =
+ new HashMap<String,IRunControl.RunControlContext>();
+ private final HashSet<String> process_ids = new HashSet<String>();
+
+ private int cnt;
+ private int sync_cnt;
+
+ TestAttachTerminate(IChannel channel) {
+ diag = channel.getRemoteService(IDiagnostics.class);
+ rc = channel.getRemoteService(IRunControl.class);
+ active_tests.put(this, channel);
+ listener.progress("Running Debugger Attach/Terminate Test...", ++count_done, count_total);
+ if (diag == null) {
+ done(this);
+ }
+ else {
+ if (rc != null) rc.addListener(this);
+ diag.getTestList(new IDiagnostics.DoneGetTestList() {
+ public void doneGetTestList(IToken token, Throwable error, String[] list) {
+ assert active_tests.get(TestAttachTerminate.this) != null;
+ if (error != null) {
+ exit(error);
+ }
+ else {
+ for (int i = 0; i < list.length; i++) {
+ if (list[i].equals("RCBP1")) {
+ startProcess();
+ return;
+ }
+ }
+ }
+ exit(null);
+ }
+ });
+ }
+ }
+
+ private void startProcess() {
+ if (cancel || cnt == 4) {
+ if (!map.isEmpty()) {
+ Protocol.sync(new Runnable() {
+ public void run() {
+ sync_cnt++;
+ if (map.isEmpty()) {
+ exit(null);
+ }
+ else if (sync_cnt < 1000) {
+ Protocol.sync(this);
+ }
+ else {
+ exit(new Error("Missing 'contextRemoved' event for " + map.keySet()));
+ }
+ }
+ });
+ }
+ else {
+ exit(null);
+ }
+ return;
+ }
+ cnt++;
+ diag.runTest("RCBP1", new IDiagnostics.DoneRunTest() {
+ public void doneRunTest(IToken token, Throwable error, String context_id) {
+ if (error != null) {
+ exit(error);
+ }
+ else {
+ assert context_id != null;
+ if (rc != null && map.get(context_id) == null) {
+ exit(new Error("Missing 'contextAdded' event for context " + context_id));
+ }
+ process_ids.add(context_id);
+ diag.cancelTest(context_id, new IDiagnostics.DoneCancelTest() {
+ public void doneCancelTest(IToken token, Throwable error) {
+ if (error != null) {
+ exit(error);
+ }
+ else {
+ startProcess();
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+
+ private void exit(Throwable x) {
+ if (active_tests.get(this) == null) return;
+ if (x != null) errors.add(x);
+ if (rc != null) rc.removeListener(this);
+ done(this);
+ }
+
+ public void containerResumed(String[] context_ids) {
+ }
+
+ public void containerSuspended(String main_context, String pc,
+ String reason, Map<String, Object> params,
+ String[] suspended_ids) {
+ for (String context : suspended_ids) {
+ assert context != null;
+ IRunControl.RunControlContext ctx = map.get(context);
+ if (ctx == null) exit(new Error("Invalid 'contextSuspended' event for " + context));
+ if (process_ids.contains(context) || process_ids.contains(ctx.getParentID())) {
+ ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) exit(error);
+ }
+ });
+ }
+ }
+ }
+
+ public void contextAdded(RunControlContext[] contexts) {
+ for (RunControlContext ctx : contexts) {
+ if (map.get(ctx.getID()) != null) exit(new Error("Invalid 'contextAdded' event"));
+ map.put(ctx.getID(), ctx);
+ }
+ }
+
+ public void contextChanged(RunControlContext[] contexts) {
+ for (RunControlContext ctx : contexts) {
+ if (map.get(ctx.getID()) == null) exit(new Error("Invalid 'contextChanged' event"));
+ map.put(ctx.getID(), ctx);
+ }
+ }
+
+ public void contextException(String context, String msg) {
+ exit(new Error("Unexpected 'contextException' event for " + context + ": " + msg));
+ }
+
+ public void contextRemoved(String[] context_ids) {
+ for (String id : context_ids) {
+ if (map.get(id) == null) exit(new Error("Invalid 'contextRemoved' event"));
+ map.remove(id);
+ }
+ }
+
+ public void contextResumed(String context) {
+ }
+
+ public void contextSuspended(String context, String pc, String reason,
+ Map<String, Object> params) {
+ assert context != null;
+ IRunControl.RunControlContext ctx = map.get(context);
+ if (ctx == null) exit(new Error("Invalid 'contextSuspended' event for " + context));
+ if (process_ids.contains(context) || process_ids.contains(ctx.getParentID())) {
+ ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) exit(error);
+ }
+ });
+ }
+ }
+ }
+
private class TestRCBP1 implements Test,
IDiagnostics.DoneGetTestList, IDiagnostics.DoneRunTest,
IRunControl.DoneGetContext, IRunControl.DoneGetChildren,
@@ -640,9 +816,8 @@ class TCFSelfTest {
exit(new Exception("Invalid contextRemoved event"));
return;
}
- threads.remove(id);
running.remove(id);
- if (threads.isEmpty()) {
+ if (threads.remove(id) != null && threads.isEmpty()) {
if (bp_cnt != 30) {
exit(new Exception("Test main thread breakpoint count = " + bp_cnt + ", expected 30"));
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationImageProvider.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationImageProvider.java
new file mode 100644
index 000000000..8d8acd0e4
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationImageProvider.java
@@ -0,0 +1,21 @@
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.texteditor.IAnnotationImageProvider;
+
+public class TCFAnnotationImageProvider implements IAnnotationImageProvider {
+
+ public Image getManagedImage(Annotation annotation) {
+ return ((TCFAnnotationManager.TCFAnnotation)annotation).image;
+ }
+
+ public String getImageDescriptorId(Annotation annotation) {
+ return null;
+ }
+
+ public ImageDescriptor getImageDescriptor(String imageDescritporId) {
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java
new file mode 100644
index 000000000..a5e63d9d8
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFBreakpointListener;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpoint;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsStatus;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class TCFAnnotationManager {
+
+ class TCFAnnotation extends Annotation {
+
+ final TCFModel model;
+ final String exe_id;
+ final ITextEditor editor;
+ final Image image;
+
+ TCFAnnotation(TCFModel model, String exe_id, ITextEditor editor, Image image) {
+ this.model = model;
+ this.exe_id = exe_id;
+ this.editor = editor;
+ this.image = image;
+ }
+
+ protected Image getImage() {
+ return image;
+ }
+
+ void dispose() {
+ assert Thread.currentThread() == display.getThread();
+ IDocumentProvider doc_provider = editor.getDocumentProvider();
+ IEditorInput editor_input = editor.getEditorInput();
+ if (doc_provider != null) {
+ IAnnotationModel ann_model = doc_provider.getAnnotationModel(editor_input);
+ if (ann_model != null) ann_model.removeAnnotation(this);
+ }
+ }
+ }
+
+ private class WorkbenchWindowInfo {
+ final ArrayList<TCFAnnotation> annotations = new ArrayList<TCFAnnotation>();
+
+ void dispose() {
+ for (TCFAnnotation a : annotations) a.dispose();
+ annotations.clear();
+ }
+ }
+
+ private TCFLaunch active_launch;
+ private final HashMap<IWorkbenchWindow,WorkbenchWindowInfo> windows =
+ new HashMap<IWorkbenchWindow,WorkbenchWindowInfo>();
+
+ private final TCFLaunch.Listener launch_listener = new TCFLaunch.Listener() {
+
+ public void onConnected(final TCFLaunch launch) {
+ updateActiveLaunch();
+ launch.getBreakpointsStatus().addListener(new ITCFBreakpointListener() {
+
+ public void breakpointStatusChanged(String id) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (active_launch != launch) return;
+ refreshBreakpointView();
+ }
+ });
+ }
+
+ public void breakpointRemoved(String id) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (active_launch != launch) return;
+ refreshBreakpointView();
+ }
+ });
+ }
+ });
+ }
+
+ public void onDisconnected(final TCFLaunch launch) {
+ assert Protocol.isDispatchThread();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ for (WorkbenchWindowInfo info : windows.values()) {
+ for (Iterator<TCFAnnotation> i = info.annotations.iterator(); i.hasNext();) {
+ TCFAnnotation a = i.next();
+ if (a.model.getLaunch() == launch) {
+ i.remove();
+ a.dispose();
+ }
+ }
+ }
+ }
+ });
+ updateActiveLaunch();
+ }
+ };
+
+ private final ISelectionListener selection_listener = new ISelectionListener() {
+
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ updateActiveLaunch();
+ }
+ };
+
+ private final IWindowListener window_listener = new IWindowListener() {
+
+ public void windowActivated(IWorkbenchWindow window) {
+ updateActiveLaunch();
+ }
+
+ public void windowClosed(IWorkbenchWindow window) {
+ assert windows.get(window) != null;
+ window.getSelectionService().removeSelectionListener(
+ IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
+ windows.remove(window).dispose();
+ updateActiveLaunch();
+ }
+
+ public void windowDeactivated(IWorkbenchWindow window) {
+ updateActiveLaunch();
+ }
+
+ public void windowOpened(IWorkbenchWindow window) {
+ if (windows.get(window) != null) return;
+ window.getSelectionService().addSelectionListener(
+ IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
+ windows.put(window, new WorkbenchWindowInfo());
+ updateActiveLaunch();
+ }
+ };
+
+ private final Display display = Display.getDefault();
+ private int refresh_breakpoint_view_cnt = 0;
+ private int update_active_launch_cnt = 0;
+ private boolean disposed;
+
+ public TCFAnnotationManager() {
+ assert Thread.currentThread() == display.getThread();
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ TCFLaunch.addListener(launch_listener);
+ }
+ });
+ for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+ window_listener.windowOpened(window);
+ }
+ PlatformUI.getWorkbench().addWindowListener(window_listener);
+ IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (w != null) window_listener.windowActivated(w);
+ display.addListener(SWT.Dispose, new Listener() {
+ public void handleEvent(Event event) {
+ dispose();
+ }
+ });
+ }
+
+ public void dispose() {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ disposed = true;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ TCFLaunch.removeListener(launch_listener);
+ }
+ });
+ PlatformUI.getWorkbench().removeWindowListener(window_listener);
+ for (IWorkbenchWindow window : windows.keySet()) {
+ window.getSelectionService().removeSelectionListener(
+ IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
+ windows.get(window).dispose();
+ }
+ windows.clear();
+ }
+
+ private void updateActiveLaunch() {
+ assert !disposed;
+ final int cnt = ++update_active_launch_cnt;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (cnt != update_active_launch_cnt) return;
+ TCFLaunch launch = null;
+ IAdaptable adaptable = DebugUITools.getDebugContext();
+ if (adaptable != null) {
+ ILaunch x = (ILaunch)adaptable.getAdapter(ILaunch.class);
+ if (x instanceof TCFLaunch) {
+ final TCFLaunch l = (TCFLaunch)x;
+ final boolean[] b = new boolean[1];
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ IChannel channel = l.getChannel();
+ b[0] = channel != null && channel.getState() == IChannel.STATE_OPEN;
+ }
+ });
+ if (b[0]) launch = l;
+ }
+ }
+ if (active_launch != launch) {
+ active_launch = launch;
+ refreshBreakpointView();
+ }
+ }
+ });
+ }
+
+ private void refreshBreakpointView() {
+ assert !disposed;
+ final int cnt = ++refresh_breakpoint_view_cnt;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (cnt != refresh_breakpoint_view_cnt) return;
+ for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+ IDebugView view = (IDebugView)window.getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW);
+ if (view != null) view.getViewer().refresh();
+ }
+ }
+ });
+ }
+
+ String getBreakpointStatus(final TCFBreakpoint breakpoint) {
+ if (disposed) return "";
+ assert Thread.currentThread() == display.getThread();
+ final TCFLaunch launch = active_launch;
+ final String[] text = new String[1];
+ text[0] = breakpoint.getText();
+ if (launch != null) {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ TCFBreakpointsStatus bs = launch.getBreakpointsStatus();
+ if (bs != null) {
+ Map<String,Object> map = bs.getStatus(breakpoint);
+ if (map != null) {
+ String status = null;
+ String error = (String)map.get(IBreakpoints.STATUS_ERROR);
+ Object planted = map.get(IBreakpoints.STATUS_PLANTED);
+ if (error != null) status = error;
+ else if (planted != null) status = "Planted";
+ if (status != null) text[0] += " (" + status + ")";
+ }
+ }
+ }
+ });
+ }
+ return text[0];
+ }
+
+ void addStackFrameAnnotation(TCFModel model, String exe_id, boolean top_frame,
+ IWorkbenchPage page, ITextEditor editor, IRegion region) {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ TCFAnnotation annotation = null;
+ IAnnotationModel ann_model = null;
+
+ if (editor != null && region != null) {
+ IDocumentProvider doc_provider = editor.getDocumentProvider();
+ IEditorInput editor_input = editor.getEditorInput();
+ ann_model = doc_provider.getAnnotationModel(editor_input);
+ if (ann_model != null) {
+ String type;
+ String text;
+ Image image;
+ if (top_frame) {
+ type = "org.eclipse.tm.tcf.debug.top_frame"; //$NON-NLS-1$
+ text = "Debug Current Instruction Pointer"; //$NON-NLS-1$
+ image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
+ }
+ else {
+ type = "org.eclipse.tm.tcf.debug.stack_frame"; //$NON-NLS-1$
+ text = "Debug Stack Frame"; //$NON-NLS-1$
+ image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
+ }
+ annotation = new TCFAnnotation(model, exe_id, editor, image);
+ annotation.setType(type);
+ annotation.setText(text);
+ }
+ }
+
+ if (page != null) {
+ WorkbenchWindowInfo info = windows.get(page.getWorkbenchWindow());
+ for (TCFAnnotation a : info.annotations) a.dispose();
+ info.annotations.clear();
+ if (annotation != null) {
+ ann_model.addAnnotation(annotation, new Position(region.getOffset(), region.getLength()));
+ info.annotations.add(annotation);
+ }
+ }
+ }
+
+ void onContextResumed(final TCFModel model, String id) {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ for (WorkbenchWindowInfo info : windows.values()) {
+ for (Iterator<TCFAnnotation> i = info.annotations.iterator(); i.hasNext();) {
+ TCFAnnotation a = i.next();
+ if (a.model == model && a.exe_id.equals(id)) {
+ i.remove();
+ a.dispose();
+ }
+ }
+ }
+ }
+
+ void onContextSuspended(final TCFModel model, final String id) {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ final IAdaptable adaptable = DebugUITools.getDebugContext();
+ if (adaptable instanceof TCFNode) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ IRunControl.RunControlContext x = ((TCFNode)adaptable).getRunContext();
+ if (x != null && id.equals(x.getID())) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (w != null) {
+ IWorkbenchPage page = w.getActivePage();
+ if (page != null) model.displaySource(adaptable, page, true);
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+ }
+
+ void onContextRemoved(final TCFModel model, String id) {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ for (WorkbenchWindowInfo info : windows.values()) {
+ for (Iterator<TCFAnnotation> i = info.annotations.iterator(); i.hasNext();) {
+ TCFAnnotation a = i.next();
+ if (a.model == model && a.exe_id.equals(id)) {
+ i.remove();
+ a.dispose();
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
index f48adea2b..402c10a38 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
@@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.commands.IDisconnectHandler;
import org.eclipse.debug.core.commands.IResumeHandler;
import org.eclipse.debug.core.commands.IStepIntoHandler;
@@ -22,6 +23,8 @@ import org.eclipse.debug.core.commands.IStepOverHandler;
import org.eclipse.debug.core.commands.IStepReturnHandler;
import org.eclipse.debug.core.commands.ISuspendHandler;
import org.eclipse.debug.core.commands.ITerminateHandler;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
@@ -35,8 +38,16 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.ISourcePresentation;
+import org.eclipse.debug.ui.sourcelookup.CommonSourceNotFoundEditorInput;
+import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.commands.DisconnectCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.ResumeCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.StepIntoCommand;
@@ -44,14 +55,22 @@ import org.eclipse.tm.internal.tcf.debug.ui.commands.StepOverCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.StepReturnCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.SuspendCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.TerminateCommand;
+import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IMemory;
import org.eclipse.tm.tcf.services.IRegisters;
import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
public class TCFModel implements IElementContentProvider, IElementLabelProvider,
- IModelProxyFactory, IColumnPresentationFactory {
+ IModelProxyFactory, IColumnPresentationFactory, ISourceDisplay {
private final Display display;
private final TCFLaunch launch;
@@ -66,6 +85,8 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private boolean disposed;
private int future_task_cnt;
+
+ private int display_source_cnt;
private static class FutureTask implements Comparable<FutureTask>{
final int id;
@@ -145,9 +166,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
fireModelChanged();
}
- public void contextRemoved(String[] context_ids) {
- for (int i = 0; i < context_ids.length; i++) {
- TCFNode node = getNode(context_ids[i]);
+ public void contextRemoved(final String[] context_ids) {
+ for (String id : context_ids) {
+ TCFNode node = getNode(id);
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextRemoved();
}
@@ -225,30 +246,47 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
fireModelChanged();
}
- public void contextRemoved(String[] context_ids) {
- for (int i = 0; i < context_ids.length; i++) {
- TCFNode node = getNode(context_ids[i]);
+ public void contextRemoved(final String[] context_ids) {
+ for (String id : context_ids) {
+ TCFNode node = getNode(id);
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextRemoved();
}
}
fireModelChanged();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ for (String id : context_ids) {
+ Activator.getAnnotationManager().onContextRemoved(TCFModel.this, id);
+ }
+ }
+ });
}
- public void contextResumed(String context) {
+ public void contextResumed(final String context) {
TCFNode node = getNode(context);
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextResumed();
}
fireModelChanged();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ Activator.getAnnotationManager().onContextResumed(TCFModel.this, context);
+ }
+ });
}
- public void contextSuspended(String context, String pc, String reason, Map<String,Object> params) {
+ public void contextSuspended(final String context, String pc, String reason, Map<String,Object> params) {
TCFNode node = getNode(context);
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextSuspended(pc, reason, params);
}
fireModelChanged();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ Activator.getAnnotationManager().onContextSuspended(TCFModel.this, context);
+ }
+ });
}
};
@@ -478,4 +516,135 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
return null;
}
+
+ /**
+ * Reveal source code associated with given model element.
+ */
+ public void displaySource(Object element, final IWorkbenchPage page, boolean forceSourceLookup) {
+ if (element instanceof TCFNodeStackFrame) {
+ final TCFNodeStackFrame stack_frame = (TCFNodeStackFrame)element;
+ final int cnt = ++display_source_cnt;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (cnt != display_source_cnt) return;
+ IChannel channel = getLaunch().getChannel();
+ if (!disposed && channel.getState() == IChannel.STATE_OPEN && !stack_frame.disposed) {
+ TCFDataCache<TCFSourceRef> line_info = stack_frame.getLineInfo();
+ if (!line_info.validate()) {
+ line_info.wait(this);
+ }
+ else {
+ String editor_id = null;
+ IEditorInput editor_input = null;
+ Throwable error = line_info.getError();
+ TCFSourceRef src_ref = line_info.getData();
+ int line = 0;
+ if (error == null && src_ref != null) error = src_ref.error;
+ if (error != null) Activator.log("Error retrieving source mapping for a stack frame", error);
+ if (src_ref != null && src_ref.area != null) {
+ ISourceLocator locator = getLaunch().getSourceLocator();
+ Object source_element = null;
+ if (locator instanceof ISourceLookupDirector) {
+ source_element = ((ISourceLookupDirector)locator).getSourceElement(src_ref.area);
+ }
+ if (source_element == null) {
+ editor_input = new CommonSourceNotFoundEditorInput(src_ref.area);
+ editor_id = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR;
+ }
+ else {
+ ISourcePresentation presentation = TCFModelPresentation.getDefault();
+ if (presentation != null) {
+ editor_input = presentation.getEditorInput(source_element);
+ }
+ if (editor_input != null) {
+ editor_id = presentation.getEditorId(editor_input, source_element);
+ }
+ line = src_ref.area.start_line;
+ }
+ }
+ displaySource(cnt, editor_id, editor_input, page, stack_frame.getRunContext().getID(),
+ stack_frame.getFrameNo() == 0, line);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void displaySource(final int cnt,
+ final String id, final IEditorInput input, final IWorkbenchPage page,
+ final String exe_id, final boolean top_frame, final int line) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (cnt != display_source_cnt) return;
+ ITextEditor text_editor = null;
+ IRegion region = null;
+ if (input != null && id != null && page != null) {
+ IEditorPart editor = openEditor(input, id, page);
+ if (editor instanceof ITextEditor) {
+ text_editor = (ITextEditor)editor;
+ }
+ else {
+ text_editor = (ITextEditor)editor.getAdapter(ITextEditor.class);
+ }
+ }
+ if (text_editor != null) {
+ region = getLineInformation(text_editor, line);
+ if (region != null) text_editor.selectAndReveal(region.getOffset(), 0);
+ }
+ Activator.getAnnotationManager().addStackFrameAnnotation(TCFModel.this,
+ exe_id, top_frame, page, text_editor, region);
+ }
+ });
+ }
+
+ /**
+ * Open an editor for given editor input.
+ * @param input - IEditorInput representing a source file to be shown in the editor
+ * @param id - editor type ID
+ * @param page - workbench page that will contain the editor
+ * @return - IEditorPart if the editor was opened successfully, or null otherwise.
+ */
+ private IEditorPart openEditor(final IEditorInput input, final String id, final IWorkbenchPage page) {
+ final IEditorPart[] editor = new IEditorPart[]{ null };
+ Runnable r = new Runnable() {
+ public void run() {
+ if (!page.getWorkbenchWindow().getWorkbench().isClosing()) {
+ try {
+ editor[0] = page.openEditor(input, id, false, IWorkbenchPage.MATCH_ID|IWorkbenchPage.MATCH_INPUT);
+ }
+ catch (PartInitException e) {
+ Activator.log("Cannot open editor", e);
+ }
+ }
+ }
+ };
+ BusyIndicator.showWhile(display, r);
+ return editor[0];
+ }
+
+ /**
+ * Returns the line information for the given line in the given editor
+ */
+ private IRegion getLineInformation(ITextEditor editor, int lineNumber) {
+ IDocumentProvider provider = editor.getDocumentProvider();
+ IEditorInput input = editor.getEditorInput();
+ try {
+ provider.connect(input);
+ }
+ catch (CoreException e) {
+ return null;
+ }
+ try {
+ IDocument document = provider.getDocument(input);
+ if (document != null)
+ return document.getLineInformation(lineNumber);
+ }
+ catch (BadLocationException e) {
+ }
+ finally {
+ provider.disconnect(input);
+ }
+ return null;
+ }
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java
index c337ff1cf..7a4960b90 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelManager.java
@@ -99,6 +99,7 @@ public class TCFModelManager {
}
public TCFModel getModel(TCFLaunch launch) {
+ assert Protocol.isDispatchThread();
TCFModel model = models.get(launch);
if (model == null) {
model = new TCFModel(display, launch);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelPresentation.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelPresentation.java
index 5608f3b6f..b513350e3 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelPresentation.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelPresentation.java
@@ -12,164 +12,32 @@ package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.util.Collection;
import java.util.HashSet;
-import java.util.Map;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.debug.core.ILaunch;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IValue;
-import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
-import org.eclipse.debug.ui.IDebugUIConstants;
-import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.tm.internal.tcf.debug.model.ITCFBreakpointListener;
import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpoint;
-import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsStatus;
-import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
-import org.eclipse.tm.tcf.protocol.IChannel;
-import org.eclipse.tm.tcf.protocol.Protocol;
-import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.IWindowListener;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
public class TCFModelPresentation implements IDebugModelPresentation {
private final Collection<ILabelProviderListener> listeners = new HashSet<ILabelProviderListener>();
- private IWorkbenchWindow active_window;
- private TCFLaunch launch_selection;
+ private static final TCFModelPresentation default_instance = new TCFModelPresentation();
- private final TCFLaunch.Listener launch_listener = new TCFLaunch.Listener() {
-
- public void onConnected(TCFLaunch launch) {
- updateLaunchSelection();
- }
-
- public void onDisconnected(TCFLaunch launch) {
- updateLaunchSelection();
- }
- };
-
- private final ISelectionListener selection_listener = new ISelectionListener() {
-
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
- updateLaunchSelection();
- }
- };
-
- private final IWindowListener window_listener = new IWindowListener() {
-
- public void windowActivated(IWorkbenchWindow window) {
- if (active_window != null) {
- active_window.getSelectionService().removeSelectionListener(
- IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
- active_window = null;
- }
- window.getSelectionService().addSelectionListener(
- IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
- active_window = window;
- updateLaunchSelection();
- }
-
- public void windowClosed(IWorkbenchWindow window) {
- if (window == active_window) {
- active_window.getSelectionService().removeSelectionListener(
- IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
- active_window = null;
- }
- }
-
- public void windowDeactivated(IWorkbenchWindow window) {
- }
-
- public void windowOpened(IWorkbenchWindow window) {
- }
- };
-
- private final ITCFBreakpointListener breakpoint_status_listener = new ITCFBreakpointListener() {
-
- public void breakpointStatusChanged(String id) {
- refreshBreakpointView();
- }
-
- public void breakpointRemoved(String id) {
- refreshBreakpointView();
- }
- };
-
- public TCFModelPresentation() {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- TCFLaunch.addListener(launch_listener);
- }
- });
- PlatformUI.getWorkbench().addWindowListener(window_listener);
- IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- if (w != null) window_listener.windowActivated(w);
- }
-
- private void updateLaunchSelection() {
- Display.getDefault().asyncExec(new Runnable() {
- public void run() {
- TCFLaunch launch = null;
- IAdaptable adaptable = DebugUITools.getDebugContext();
- if (adaptable != null) {
- ILaunch x = (ILaunch)adaptable.getAdapter(ILaunch.class);
- if (x instanceof TCFLaunch) {
- final TCFLaunch l = (TCFLaunch)x;
- final boolean[] b = new boolean[1];
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- IChannel channel = l.getChannel();
- b[0] = channel != null && channel.getState() == IChannel.STATE_OPEN;
- }
- });
- if (b[0]) launch = l;
- }
- }
- if (launch_selection != launch) {
- setBreakpointStatusListener(launch_selection, launch);
- launch_selection = launch;
- refreshBreakpointView();
- }
- }
- });
- }
-
- private void refreshBreakpointView() {
- Display.getDefault().asyncExec(new Runnable() {
- public void run() {
- if (active_window != null) {
- final IDebugView view = (IDebugView)active_window.getActivePage().findView(
- IDebugUIConstants.ID_BREAKPOINT_VIEW);
- if (view != null) {
- view.getViewer().refresh();
- }
- }
- }
- });
- }
-
- private void setBreakpointStatusListener(final TCFLaunch prev, final TCFLaunch next) {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- if (prev != null && prev.getBreakpointsStatus() != null) {
- prev.getBreakpointsStatus().removeListener(breakpoint_status_listener);
- }
- if (next != null && next.getBreakpointsStatus() != null) {
- next.getBreakpointsStatus().addListener(breakpoint_status_listener);
- }
- }
- });
+ public static TCFModelPresentation getDefault() {
+ return default_instance;
}
public void addListener(ILabelProviderListener listener) {
@@ -181,21 +49,6 @@ public class TCFModelPresentation implements IDebugModelPresentation {
}
public void dispose() {
- if (launch_selection != null) {
- setBreakpointStatusListener(launch_selection, null);
- launch_selection = null;
- }
- if (active_window != null) {
- active_window.getSelectionService().removeSelectionListener(
- IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
- active_window = null;
- }
- PlatformUI.getWorkbench().removeWindowListener(window_listener);
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- TCFLaunch.removeListener(launch_listener);
- }
- });
}
public void computeDetail(IValue value, IValueDetailListener listener) {
@@ -206,32 +59,14 @@ public class TCFModelPresentation implements IDebugModelPresentation {
}
public String getText(Object element) {
+ String text = null;
if (element instanceof TCFBreakpoint) {
- final TCFBreakpoint breakpoint = (TCFBreakpoint)element;
- final TCFLaunch launch = launch_selection;
- final String[] text = new String[1];
- text[0] = breakpoint.getText();
- if (launch != null) {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- TCFBreakpointsStatus bs = launch.getBreakpointsStatus();
- if (bs != null) {
- Map<String,Object> map = bs.getStatus(breakpoint);
- if (map != null) {
- String status = null;
- String error = (String)map.get(IBreakpoints.STATUS_ERROR);
- Object planted = map.get(IBreakpoints.STATUS_PLANTED);
- if (error != null) status = error;
- else if (planted != null) status = "Planted";
- if (status != null) text[0] += " (" + status + ")";
- }
- }
- }
- });
- }
- return text[0];
+ TCFBreakpoint breakpoint = (TCFBreakpoint)element;
+ text = breakpoint.getText();
+ String status = Activator.getAnnotationManager().getBreakpointStatus(breakpoint);
+ if (status != null) text += " (" + status + ")";
}
- return null;
+ return text;
}
public void setAttribute(String attribute, Object value) {
@@ -242,10 +77,25 @@ public class TCFModelPresentation implements IDebugModelPresentation {
}
public String getEditorId(IEditorInput input, Object element) {
- return null;
+ String id = null;
+ if (input != null) {
+ IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
+ IEditorDescriptor descriptor = registry.getDefaultEditor(input.getName());
+ if (descriptor != null) id = descriptor.getId();
+ }
+ return id;
}
public IEditorInput getEditorInput(Object element) {
+ if (element instanceof ILineBreakpoint) {
+ element = ((ILineBreakpoint)element).getMarker();
+ }
+ if (element instanceof IMarker) {
+ element = ((IMarker)element).getResource();
+ }
+ if (element instanceof IFile) {
+ return new FileEditorInput((IFile)element);
+ }
return null;
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
index 3895affa7..10afd3ee6 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
@@ -26,6 +26,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
+import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.Protocol;
@@ -104,9 +105,9 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
if (adapter == IElementLabelProvider.class) return model;
if (adapter == IElementContentProvider.class) return model;
if (adapter == IColumnPresentationFactory.class) return model;
+ if (adapter == ISourceDisplay.class) return model;
Object o = model.getCommand(adapter);
if (o != null) return o;
- //System.err.println(adapter.getName());
return super.getAdapter(adapter);
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
index 84efbc5d6..017735dec 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
@@ -126,6 +126,7 @@ public class TCFNodeStackFrame extends TCFNode {
}
int getFrameNo() {
+ assert Protocol.isDispatchThread();
return frame_no;
}
@@ -133,6 +134,10 @@ public class TCFNodeStackFrame extends TCFNode {
assert this.frame_no != 0 && frame_no != 0;
this.frame_no = frame_no;
}
+
+ TCFDataCache<TCFSourceRef> getLineInfo() {
+ return line_info;
+ }
@Override
void dispose() {
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java
index b3bb64350..717af08e3 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java
@@ -12,14 +12,19 @@ package org.eclipse.tm.internal.tcf.debug.launch;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant;
+import org.eclipse.tm.tcf.services.ILineNumbers;
/**
- * The TCF source lookup participant knows how to translate a TCF stack frame
+ * The TCF source lookup participant knows how to translate a ILineNumbers.CodeArea
* into a source file name
*/
public class TCFSourceLookupParticipant extends AbstractSourceLookupParticipant {
public String getSourceName(Object object) throws CoreException {
+ if (object instanceof ILineNumbers.CodeArea) {
+ ILineNumbers.CodeArea area = (ILineNumbers.CodeArea)object;
+ return area.file;
+ }
return null;
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java
index 4a9d65cdb..357a0de94 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java
@@ -10,11 +10,18 @@
*******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.launch;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate;
+import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer;
+import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.WorkspaceSourceContainer;
/**
@@ -23,24 +30,25 @@ import org.eclipse.debug.core.sourcelookup.containers.WorkspaceSourceContainer;
* program being launched. If the program is not specified, the workspace is
* searched by default.
*/
-public class TCFSourcePathComputerDelegate implements
- ISourcePathComputerDelegate {
+public class TCFSourcePathComputerDelegate implements ISourcePathComputerDelegate {
public ISourceContainer[] computeSourceContainers(
ILaunchConfiguration configuration, IProgressMonitor monitor)
throws CoreException {
ISourceContainer sourceContainer = null;
- /*
- * String path =
- * configuration.getAttribute(IPDAConstants.ATTR_PDA_PROGRAM,
- * (String)null); if (path != null) { IResource resource =
- * ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(path));
- * if (resource != null) { IContainer container = resource.getParent();
- * if (container.getType() == IResource.PROJECT) { sourceContainer = new
- * ProjectSourceContainer((IProject)container, false); } else if
- * (container.getType() == IResource.FOLDER) { sourceContainer = new
- * FolderSourceContainer(container, false); } } }
- */
+ String path = configuration.getAttribute(TCFLaunchDelegate.ATTR_PROGRAM_FILE, (String)null);
+ if (path != null) {
+ IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(path));
+ if (resource != null) {
+ IContainer container = resource.getParent();
+ if (container.getType() == IResource.PROJECT) {
+ sourceContainer = new ProjectSourceContainer((IProject)container, false);
+ }
+ else if (container.getType() == IResource.FOLDER) {
+ sourceContainer = new FolderSourceContainer(container, false);
+ }
+ }
+ }
if (sourceContainer == null) {
sourceContainer = new WorkspaceSourceContainer();
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java
index 1b5cf3edc..fdc82faf4 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java
@@ -159,7 +159,7 @@ public abstract class AbstractChannel implements IChannel {
for (;;) {
int n = read();
if (n == end) break;
- if (n < 0) error();
+ if (n < 0) throw new IOException("Communication channel is closed by remote peer");
if (len >= buf.length) {
byte[] tmp = new byte[buf.length * 2];
System.arraycopy(buf, 0, tmp, 0, len);

Back to the top