From 6856eb8f9fea18057ccb49306160f6ecf563d429 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 25 Sep 2008 03:20:15 +0000 Subject: Bug 212316 - Allow multiple debuggers to create breakpoints using the same editor. --- .../ui/pda/breakpoints/PDABreakpointAdapter.java | 45 +++--- .../breakpoints/PDAToggleWatchpointsTarget.java | 168 +++++++++++++++++++++ .../PDAToggleWatchpointsTargetFactory.java | 84 +++++++++++ 3 files changed, 278 insertions(+), 19 deletions(-) create mode 100644 org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTarget.java create mode 100644 org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTargetFactory.java (limited to 'org.eclipse.debug.examples.ui/src/org/eclipse') diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java index 38e8f8525..0f2639f7c 100644 --- a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java +++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation + * Wind River Systems - added support for IToggleBreakpointsTargetFactory *******************************************************************************/ package org.eclipse.debug.examples.ui.pda.breakpoints; @@ -110,23 +111,7 @@ public class PDABreakpointAdapter implements IToggleBreakpointsTargetExtension { IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); String var = variableAndFunctionName[0]; String fcn = variableAndFunctionName[1]; - // look for existing watchpoint to delete - IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(DebugCorePlugin.ID_PDA_DEBUG_MODEL); - for (int i = 0; i < breakpoints.length; i++) { - IBreakpoint breakpoint = breakpoints[i]; - if (breakpoint instanceof PDAWatchpoint && resource.equals(breakpoint.getMarker().getResource())) { - PDAWatchpoint watchpoint = (PDAWatchpoint)breakpoint; - String otherVar = watchpoint.getVariableName(); - String otherFcn = watchpoint.getFunctionName(); - if (otherVar.equals(var) && otherFcn.equals(fcn)) { - breakpoint.delete(); - return; - } - } - } - // create watchpoint - PDAWatchpoint watchpoint = new PDAWatchpoint(resource, lineNumber + 1, fcn, var, true, true); - DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(watchpoint); + toggleWatchpoint(resource, lineNumber, fcn, var, true, true); } } /* (non-Javadoc) @@ -136,6 +121,28 @@ public class PDABreakpointAdapter implements IToggleBreakpointsTargetExtension { return getVariableAndFunctionName(part, selection) != null; } + protected void toggleWatchpoint(IResource resource, int lineNumber, String fcn, String var, boolean access, + boolean modification) throws CoreException + { + // look for existing watchpoint to delete + IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(DebugCorePlugin.ID_PDA_DEBUG_MODEL); + for (int i = 0; i < breakpoints.length; i++) { + IBreakpoint breakpoint = breakpoints[i]; + if (breakpoint instanceof PDAWatchpoint && resource.equals(breakpoint.getMarker().getResource())) { + PDAWatchpoint watchpoint = (PDAWatchpoint)breakpoint; + String otherVar = watchpoint.getVariableName(); + String otherFcn = watchpoint.getFunctionName(); + if (otherVar.equals(var) && otherFcn.equals(fcn)) { + breakpoint.delete(); + return; + } + } + } + // create watchpoint + PDAWatchpoint watchpoint = new PDAWatchpoint(resource, lineNumber + 1, fcn, var, access, modification); + DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(watchpoint); + } + /** * Returns the variable and function names at the current line, or null if none. * @@ -144,7 +151,7 @@ public class PDABreakpointAdapter implements IToggleBreakpointsTargetExtension { * @return the variable and function names at the current line, or null if none. * The array has two elements, the first is the variable name, the second is the function name. */ - private String[] getVariableAndFunctionName(IWorkbenchPart part, ISelection selection) { + protected String[] getVariableAndFunctionName(IWorkbenchPart part, ISelection selection) { ITextEditor editor = getEditor(part); if (editor != null && selection instanceof ITextSelection) { ITextSelection textSelection = (ITextSelection) selection; diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTarget.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTarget.java new file mode 100644 index 000000000..4c51afeb9 --- /dev/null +++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTarget.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation 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.debug.examples.ui.pda.breakpoints; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.examples.core.pda.model.PDAStackFrame; +import org.eclipse.debug.examples.core.pda.model.PDAVariable; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.progress.WorkbenchJob; +import org.eclipse.ui.texteditor.ITextEditor; + + +/** + * Adapter to create specialized watchpoints in PDA files and the variables views. + */ +public class PDAToggleWatchpointsTarget extends PDABreakpointAdapter { + + final private boolean fAccessModeEnabled; + final private boolean fModificationModeEnabled; + + PDAToggleWatchpointsTarget(boolean access, boolean modification) { + fAccessModeEnabled = access; + fModificationModeEnabled = modification; + } + + public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { + if (super.canToggleWatchpoints(part, selection)) { + return true; + } else { + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection)selection; + return ss.getFirstElement() instanceof PDAVariable; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + String[] variableAndFunctionName = getVariableAndFunctionName(part, selection); + + if (variableAndFunctionName != null && part instanceof ITextEditor && selection instanceof ITextSelection) { + // Selection inside text editor. Create a watchpoint based on + // current source line. + ITextEditor editorPart = (ITextEditor)part; + int lineNumber = ((ITextSelection)selection).getStartLine(); + IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); + String var = variableAndFunctionName[0]; + String fcn = variableAndFunctionName[1]; + toggleWatchpoint(resource, lineNumber, fcn, var, fAccessModeEnabled, fModificationModeEnabled); + } else if (selection instanceof IStructuredSelection && + ((IStructuredSelection)selection).getFirstElement() instanceof PDAVariable ) + { + // Selection is inside a variables view. Create a watchpoint + // using information from the variable. Retrieving information + // from the model requires performing source lookup which should be + // done on a background thread. + final PDAVariable var = (PDAVariable)((IStructuredSelection)selection).getFirstElement(); + final PDAStackFrame frame = var.getStackFrame(); + final Shell shell = part.getSite().getShell(); + + new Job("Toggle PDA Watchpoint") { + { setSystem(true); } + + protected IStatus run(IProgressMonitor monitor) { + try { + IFile file = getResource(var.getStackFrame()); + String varName = var.getName(); + int line = findLine(file, varName); + toggleWatchpoint(file, line, frame.getName(), varName, + fAccessModeEnabled, fModificationModeEnabled); + } catch (final CoreException e) { + // Need to switch back to the UI thread to show the error + // dialog. + new WorkbenchJob(shell.getDisplay(), "Toggle PDA Watchpoint") { + { setSystem(true); } + + public IStatus runInUIThread(IProgressMonitor monitor) { + ErrorDialog.openError(shell, "Failed to create PDA watchpoint", "Failed to create PDA watchpoint.\n", e.getStatus()); + return Status.OK_STATUS; + } + }.schedule(); + } + return Status.OK_STATUS; + } + }.schedule(); + } + } + + private IFile getResource(PDAStackFrame frame) { + ISourceLocator locator = frame.getLaunch().getSourceLocator(); + Object sourceElement = locator.getSourceElement(frame); + if (sourceElement instanceof IFile) { + return (IFile)sourceElement; + } + return null; + } + + private int findLine(IFile file, String var) throws CoreException { + BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents())); + + int lineNum = 0; + try { + while(true) { + String line = reader.readLine().trim(); + if (line.startsWith("var")) { + String varName = line.substring("var".length()).trim(); + if (varName.equals(var)) { + break; + } + } + lineNum++; + } + } catch (IOException e) { + // end of file reached and line wasn't found + return -1; + } finally { + try { + reader.close(); + } catch (IOException e) {} + } + return lineNum; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#toggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { + if (canToggleWatchpoints(part, selection)) { + toggleWatchpoints(part, selection); + } else { + toggleLineBreakpoints(part, selection); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#canToggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) { + return canToggleLineBreakpoints(part, selection) || canToggleWatchpoints(part, selection); + } +} diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTargetFactory.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTargetFactory.java new file mode 100644 index 000000000..9c9ebd9cc --- /dev/null +++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAToggleWatchpointsTargetFactory.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems 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.debug.examples.ui.pda.breakpoints; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Toggle breakpoints target factory for creating PDA watchpoints. It allows the + * user the select the type of watchpoint that will be created when the watchpoint + * is toggles inside the editor or variables view. + */ +public class PDAToggleWatchpointsTargetFactory implements IToggleBreakpointsTargetFactory { + + private static final String TOGGLE_WATCHPOINT_TARGET_ACCESS = "org.eclipse.debug.examples.ui.pda.watchpoint_access"; + private static final String TOGGLE_WATCHPOINT_TARGET_MODIFICATION = "org.eclipse.debug.examples.ui.pda.watchpoint_modification"; + private static final String TOGGLE_WATCHPOINT_TARGET_BOTH = "org.eclipse.debug.examples.ui.pda.watchpoint_both"; + + private static Set TOGGLE_WATCHPOINTS_TARGETS = new LinkedHashSet(); + + private Map fToggleWatchpointTargets = new HashMap(3); + + static { + TOGGLE_WATCHPOINTS_TARGETS.add(TOGGLE_WATCHPOINT_TARGET_BOTH); + TOGGLE_WATCHPOINTS_TARGETS.add(TOGGLE_WATCHPOINT_TARGET_ACCESS); + TOGGLE_WATCHPOINTS_TARGETS.add(TOGGLE_WATCHPOINT_TARGET_MODIFICATION); + } + + public IToggleBreakpointsTarget createToggleTarget(String targetID) { + IToggleBreakpointsTarget target = (IToggleBreakpointsTarget)fToggleWatchpointTargets.get(targetID); + if (target == null) { + if (TOGGLE_WATCHPOINT_TARGET_BOTH.equals(targetID)) { + target = new PDAToggleWatchpointsTarget(true, true); + } else if (TOGGLE_WATCHPOINT_TARGET_ACCESS.equals(targetID)) { + target = new PDAToggleWatchpointsTarget(true, false); + } else if (TOGGLE_WATCHPOINT_TARGET_MODIFICATION.equals(targetID)) { + target = new PDAToggleWatchpointsTarget(false, true); + } else { + return null; + } + fToggleWatchpointTargets.put(targetID, target); + } + return target; + } + + public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) { + return TOGGLE_WATCHPOINT_TARGET_BOTH; + } + + public Set getToggleTargets(IWorkbenchPart part, ISelection selection) { + return TOGGLE_WATCHPOINTS_TARGETS; + } + + public String getToggleTargetName(String targetID) { + if (TOGGLE_WATCHPOINT_TARGET_BOTH.equals(targetID)) { + return "Watchpoints (Read/Write)"; + } else if (TOGGLE_WATCHPOINT_TARGET_ACCESS.equals(targetID)) { + return "Watchpoints (Read)"; + } else if (TOGGLE_WATCHPOINT_TARGET_MODIFICATION.equals(targetID)) { + return "Watchpoints (Write)"; + } else { + return null; + } + } + + public String getToggleTargetDescription(String targetID) { + return getToggleTargetName(targetID); + } +} -- cgit v1.2.3