Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Pazderski2020-05-23 00:31:41 +0000
committerPaul Pazderski2020-06-29 21:00:02 +0000
commit4c211278c0d0edf4fb86da00b36eac39edd348d1 (patch)
treeca9d7620053d4d8af8e72fdd8f6985e3aab946da
parent00d93c9a6e6af649b84604baa0c0866c4d3511e5 (diff)
downloadeclipse.platform.debug-4c211278c0d0edf4fb86da00b36eac39edd348d1.tar.gz
eclipse.platform.debug-4c211278c0d0edf4fb86da00b36eac39edd348d1.tar.xz
eclipse.platform.debug-4c211278c0d0edf4fb86da00b36eac39edd348d1.zip
Bug 404990 - [breakpoints] Delete breakpoint, undo, redo, undo. Gone.
The issue is located in both, the redo and the second undo operation. Delete breakpoint and redo of this operation have the (for this issue relevant) difference that the first set a 'breakpoint deleted' attribute on the marker while the redo does not set/update this attribute. The simple fix is to move the "mark deleted" into the delete marker operation which is executed from an 'initial' delete as well as from a redo. After fixing that a breakpoint is restored but the view does not updated. BreakpointManager does not properly send added notifications. Most of the time it works because an added breakpoint will be registered and the registration will trigger the added notification. However for the add of the second undo the registered attribute is already set, the setRegister(true) which normally triggers the add notification is not executed. Change-Id: Ib509ec9c8116ac4a7bb3f8bcf38dc470e0b90b8b Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
-rw-r--r--org.eclipse.debug.core/core/org/eclipse/debug/internal/core/BreakpointManager.java2
-rwxr-xr-xorg.eclipse.debug.tests/plugin.properties3
-rw-r--r--org.eclipse.debug.tests/plugin.xml30
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java2
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointOrderingTests.java112
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointTests.java134
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/TestBreakpoint.java78
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/viewer/model/DebugTestModelPresentation.java56
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/breakpoints/DeleteBreakpointMarkersOperation.java55
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java9
10 files changed, 356 insertions, 125 deletions
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/BreakpointManager.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/BreakpointManager.java
index db02ab649..6d8539d66 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/BreakpointManager.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/BreakpointManager.java
@@ -763,7 +763,7 @@ public class BreakpointManager implements IBreakpointManager, IResourceChangeLis
}
};
getWorkspace().run(runnable, null, 0, null);
- addBreakpoints(fAdded.toArray(new IBreakpoint[fAdded.size()]), false);
+ addBreakpoints(fAdded.toArray(new IBreakpoint[fAdded.size()]), true);
} catch (CoreException e) {
DebugPlugin.log(e);
}
diff --git a/org.eclipse.debug.tests/plugin.properties b/org.eclipse.debug.tests/plugin.properties
index 2643d02af..8fcb3b9f3 100755
--- a/org.eclipse.debug.tests/plugin.properties
+++ b/org.eclipse.debug.tests/plugin.properties
@@ -20,4 +20,5 @@ renderingType.name.0 = Rendering Two
renderingType.name.1 = Rendering Default
launchConfigurationType.name = Test Launch Type
extension.name = Debug File System
-launchConfigurationType.name.0 = Cancelling Launch Type \ No newline at end of file
+launchConfigurationType.name.0 = Cancelling Launch Type
+testBreakpoint.name = Test Breakpoint \ No newline at end of file
diff --git a/org.eclipse.debug.tests/plugin.xml b/org.eclipse.debug.tests/plugin.xml
index b697fbdca..ab1d612ec 100644
--- a/org.eclipse.debug.tests/plugin.xml
+++ b/org.eclipse.debug.tests/plugin.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<!--
- Copyright (c) 2009 IBM Corporation and others.
+ Copyright (c) 2009, 2020 IBM Corporation and others.
This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
@@ -31,7 +31,7 @@
id="rendering_type_3"
name="%renderingType.name.1"
class="org.eclipse.debug.tests.view.memory.RenderingTypeDelegate">
- </renderingType>
+ </renderingType>
<renderingBindings
primaryId="rendering_type_1">
<enablement>
@@ -55,7 +55,7 @@
<enablement>
<instanceof value="org.eclipse.debug.tests.view.memory.MemoryBlockDynamic"/>
</enablement>
- </renderingBindings>
+ </renderingBindings>
</extension>
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
@@ -111,5 +111,27 @@
class="org.eclipse.debug.tests.stepfilters.TestStepFilter"
modelIdentifier="com.example.debug.model">
</stepFilter>
- </extension>
+ </extension>
+ <extension point="org.eclipse.debug.core.breakpoints">
+ <breakpoint
+ id="org.eclipse.debug.tests.testBreakpoint"
+ class="org.eclipse.debug.tests.breakpoint.TestBreakpoint"
+ markerType="org.eclipse.debug.core.breakpointMarker">
+ </breakpoint>
+ </extension>
+ <extension
+ id="org.eclipse.debug.tests.testBreakpointMarker"
+ name="%testBreakpoint.name"
+ point="org.eclipse.core.resources.markers">
+ <super
+ type="org.eclipse.debug.core.breakpointMarker">
+ </super>
+ </extension>
+ <extension
+ point="org.eclipse.debug.ui.debugModelPresentations">
+ <debugModelPresentation
+ class="org.eclipse.debug.tests.viewer.model.DebugTestModelPresentation"
+ id="org.eclipse.debug.tests">
+ </debugModelPresentation>
+ </extension>
</plugin>
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java
index 627fd312d..84c55755d 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java
@@ -16,6 +16,7 @@
package org.eclipse.debug.tests;
import org.eclipse.debug.tests.breakpoint.BreakpointOrderingTests;
+import org.eclipse.debug.tests.breakpoint.BreakpointTests;
import org.eclipse.debug.tests.console.ConsoleDocumentAdapterTests;
import org.eclipse.debug.tests.console.ConsoleManagerTests;
import org.eclipse.debug.tests.console.ConsoleTests;
@@ -65,6 +66,7 @@ import org.junit.runners.Suite;
SourceLookupFacilityTests.class,
// BP tests
BreakpointOrderingTests.class,
+ BreakpointTests.class,
// Note: jface viewer tests were moved out of nightly tests
// due to frequent problems on nightly build machines.
// (Bug 343308).
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointOrderingTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointOrderingTests.java
index c70242f79..91a3d9318 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointOrderingTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointOrderingTests.java
@@ -19,20 +19,12 @@ import static org.junit.Assert.fail;
import java.util.List;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
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.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsComparator;
import org.eclipse.debug.tests.AbstractDebugTest;
-import org.eclipse.debug.tests.TestsPlugin;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jface.viewers.IBaseLabelProvider;
@@ -52,110 +44,6 @@ import org.junit.Test;
public class BreakpointOrderingTests extends AbstractDebugTest {
/**
- * Test only implementation of IBreakpoint.
- */
- static class TestBreakpoint implements IBreakpoint {
-
- private final String fText;
- private IMarker fMarker = null;
-
- TestBreakpoint(String text) {
- this(text, IBreakpoint.BREAKPOINT_MARKER);
- }
-
- TestBreakpoint(String text, final String markerType) {
- fText = text;
- final IResource resource = ResourcesPlugin.getWorkspace().getRoot();
- IWorkspaceRunnable wr = new IWorkspaceRunnable() {
-
- @Override
- public void run( IProgressMonitor monitor ) throws CoreException {
- // create the marker
- setMarker(resource.createMarker(markerType));
- }
- };
- try {
- ResourcesPlugin.getWorkspace().run( wr, null );
- }
- catch ( CoreException e ) {
- fail("Unexpected exception: " + e); //$NON-NLS-1$
- }
-
- }
-
- void ReportFailure(String msg) throws CoreException {
- throw new CoreException(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID, msg));
- }
-
-
- String getText() {
- return fText;
- }
-
- @Override
- public void delete() throws CoreException {
- fMarker.delete();
- }
-
- @Override
- public IMarker getMarker() {
- return fMarker;
- }
-
- @Override
- public String getModelIdentifier() {
- return "Test"; //$NON-NLS-1$
- }
-
- @Override
- public boolean isEnabled() throws CoreException {
- fail("not implemented in test"); //$NON-NLS-1$
- return false;
- }
-
- @Override
- public boolean isPersisted() throws CoreException {
- fail("not implemented in test"); //$NON-NLS-1$
- return false;
- }
-
- @Override
- public boolean isRegistered() throws CoreException {
- fail("not implemented in test"); //$NON-NLS-1$
- return false;
- }
-
- @Override
- public void setEnabled(boolean enabled) throws CoreException {
- fail("not implemented in test"); //$NON-NLS-1$
- }
-
- @Override
- public void setMarker(IMarker marker) throws CoreException {
- assertTrue(fMarker == null && marker != null);
- fMarker = marker;
- }
-
- @Override
- public void setPersisted(boolean registered) throws CoreException {
- fail("not implemented in test"); //$NON-NLS-1$
- }
-
- @Override
- public void setRegistered(boolean registered) throws CoreException {
- fail("not implemented in test"); //$NON-NLS-1$
-
- }
-
- @Override
- public <T> T getAdapter(Class<T> adapter) {
- fail("not implemented in test"); //$NON-NLS-1$
- return null;
- }
-
- }
-
- /**
* Test only implementation of ILineBreakpoint.
*/
static class TestLineBreakpoint extends TestBreakpoint implements ILineBreakpoint {
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointTests.java
new file mode 100644
index 000000000..60a62d5b3
--- /dev/null
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/BreakpointTests.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Paul Pazderski and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Paul Pazderski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.tests.breakpoint;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IOperationHistory;
+import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.internal.core.BreakpointManager;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView;
+import org.eclipse.debug.tests.AbstractDebugTest;
+import org.eclipse.debug.tests.TestUtil;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.PlatformUI;
+import org.junit.Test;
+
+public class BreakpointTests extends AbstractDebugTest {
+
+ private final IBreakpointManager bpm = DebugPlugin.getDefault().getBreakpointManager();
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+
+ for (IBreakpoint bp : getTestBreakpoints()) {
+ bp.delete();
+ }
+ }
+
+ /**
+ * Get all {@link TestBreakpoint}s known by the default
+ * {@link BreakpointManager}.
+ *
+ * @return {@link TestBreakpoint}s or empty list
+ */
+ private List<TestBreakpoint> getTestBreakpoints() {
+ List<TestBreakpoint> bps = new ArrayList<>();
+ for (IBreakpoint bp : bpm.getBreakpoints(TestBreakpoint.MODEL)) {
+ assertTrue(bp instanceof TestBreakpoint);
+ bps.add((TestBreakpoint) bp);
+ }
+ return bps;
+ }
+
+ /**
+ * Test for bug 424561 where a breakpoint is deleted and the sequence undo
+ * (recreate breakpoint), redo (delete again), undo (recreate breakpoint)
+ * does not recreate the breakpoint.
+ */
+ @Test
+ public void testBug424561_undoRedoUndoGone() throws Exception {
+ boolean viewVisible = true;
+ BreakpointsView view = ((BreakpointsView) DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW));
+ if (view == null) {
+ viewVisible = false;
+ view = ((BreakpointsView) DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().showView(IDebugUIConstants.ID_BREAKPOINT_VIEW));
+ }
+ assertNotNull("Failed to obtain breakpoint view.", view);
+
+ try {
+ String content = "Bug 424561";
+ TestBreakpoint bp = new TestBreakpoint(content);
+ IOperationHistory operationHistory = PlatformUI.getWorkbench().getOperationSupport().getOperationHistory();
+ IUndoContext context = DebugUITools.getBreakpointsUndoContext();
+
+ bpm.addBreakpoint(bp);
+ TestUtil.waitWhile(c -> c.getTestBreakpoints().size() == 0, this, testTimeout, c -> "Breakpoint is not created");
+ assertTrue("Breakpoint marker missing", bp.getMarker().exists());
+ assertTrue("Breakpoint not registered", bp.isRegistered());
+
+ DebugUITools.deleteBreakpoints(new IBreakpoint[] {
+ bp }, null, null);
+ assertTrue(operationHistory.canUndo(context));
+ TestUtil.waitWhile(c -> c.getTestBreakpoints().size() > 0, this, testTimeout, c -> "Breakpoint is not deleted");
+ assertFalse("Breakpoint marker not removed", bp.getMarker().exists());
+ assertFalse("Breakpoint still registered", bp.isRegistered());
+
+ operationHistory.undo(context, null, null);
+ assertTrue(operationHistory.canRedo(context));
+ TestUtil.waitWhile(c -> c.getTestBreakpoints().size() == 0, this, testTimeout, c -> "Breakpoint is not recreated");
+ bp = getTestBreakpoints().get(0);
+ assertEquals("Breakpoint attributes not correctly restored", content, bp.getText());
+ assertTrue("Breakpoint marker missing", bp.getMarker().exists());
+ assertTrue("Breakpoint not registered", bp.isRegistered());
+
+ operationHistory.redo(context, null, null);
+ assertTrue(operationHistory.canUndo(context));
+ TestUtil.waitWhile(c -> c.getTestBreakpoints().size() > 0, this, testTimeout, c -> "Breakpoint is not deleted");
+ assertFalse("Breakpoint marker not removed", bp.getMarker().exists());
+ assertFalse("Breakpoint still registered", bp.isRegistered());
+
+ operationHistory.undo(context, null, null);
+ assertTrue(operationHistory.canRedo(context));
+ TestUtil.waitWhile(c -> c.getTestBreakpoints().size() == 0, this, testTimeout, c -> "Breakpoint is not recreated");
+ bp = getTestBreakpoints().get(0);
+ assertEquals("Breakpoint attributes not correctly restored", content, bp.getText());
+ assertTrue("Breakpoint marker missing", bp.getMarker().exists());
+ assertTrue("Breakpoint not registered", bp.isRegistered());
+
+ final BreakpointsView finalView = view;
+ final TestBreakpoint finalBp = bp;
+ TestUtil.waitWhile(c -> {
+ TreeItem item = (TreeItem) finalView.getTreeModelViewer().testFindItem(finalBp);
+ return item == null || item.getText() == null || !item.getText().contains(content);
+ }, this, testTimeout, c -> "Breakpoint not restored in view");
+ } finally {
+ if (!viewVisible) {
+ view.dispose();
+ }
+ }
+ }
+}
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/TestBreakpoint.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/TestBreakpoint.java
new file mode 100644
index 000000000..2a1cc3289
--- /dev/null
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/breakpoint/TestBreakpoint.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Paul Pazderski and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Paul Pazderski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.tests.breakpoint;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.model.Breakpoint;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+/**
+ * Test only implementation of IBreakpoint.
+ */
+public class TestBreakpoint extends Breakpoint {
+
+ public static final String MODEL = "org.eclipse.debug.tests"; //$NON-NLS-1$
+ public static final String TEXT_ATTRIBUTE = "org.eclipse.debug.tests.breakpoint.TestBreakpoint.text"; //$NON-NLS-1$
+
+ public TestBreakpoint() {
+ super();
+ }
+
+ TestBreakpoint(String text) {
+ this(text, IBreakpoint.BREAKPOINT_MARKER);
+ }
+
+ TestBreakpoint(String text, final String markerType) {
+ final IResource resource = ResourcesPlugin.getWorkspace().getRoot();
+ IWorkspaceRunnable wr = new IWorkspaceRunnable() {
+ @Override
+ public void run(IProgressMonitor monitor) throws CoreException {
+ // create the marker
+ setMarker(resource.createMarker(markerType));
+ ensureMarker().setAttribute(ID, getModelIdentifier());
+ ensureMarker().setAttribute(TEXT_ATTRIBUTE, text);
+ }
+ };
+ try {
+ ResourcesPlugin.getWorkspace().run(wr, null);
+ } catch (CoreException e) {
+ fail("Unexpected exception: " + e); //$NON-NLS-1$
+ }
+
+ }
+
+ public String getText() {
+ return getMarker().getAttribute(TEXT_ATTRIBUTE, null);
+ }
+
+ @Override
+ public String getModelIdentifier() {
+ return MODEL;
+ }
+
+ @Override
+ public void setMarker(IMarker marker) throws CoreException {
+ assertTrue(getMarker() == null && marker != null);
+ super.setMarker(marker);
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/viewer/model/DebugTestModelPresentation.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/viewer/model/DebugTestModelPresentation.java
new file mode 100644
index 000000000..110af5f13
--- /dev/null
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/viewer/model/DebugTestModelPresentation.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Paul Pazderski and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Paul Pazderski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.tests.viewer.model;
+
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.tests.breakpoint.TestBreakpoint;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.IValueDetailListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * Model presentation to show the text attribute of {@link TestBreakpoint}s in
+ * Breakpoint View.
+ */
+public class DebugTestModelPresentation extends LabelProvider implements IDebugModelPresentation {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof TestBreakpoint) {
+ return "TestBreakpoint: " + ((TestBreakpoint) element).getText();
+ }
+ return super.getText(element);
+ }
+
+ @Override
+ public IEditorInput getEditorInput(Object element) {
+ return null;
+ }
+
+ @Override
+ public String getEditorId(IEditorInput input, Object element) {
+ return null;
+ }
+
+ @Override
+ public void setAttribute(String attribute, Object value) {
+ }
+
+ @Override
+ public void computeDetail(IValue value, IValueDetailListener listener) {
+ listener.detailComputed(value, null);
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/breakpoints/DeleteBreakpointMarkersOperation.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/breakpoints/DeleteBreakpointMarkersOperation.java
new file mode 100644
index 000000000..1a1b87589
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/breakpoints/DeleteBreakpointMarkersOperation.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Paul Pazderski and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Paul Pazderski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.internal.ui.views.breakpoints;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.ui.ide.undo.DeleteMarkersOperation;
+
+/**
+ * Extension of the default undoable delete marker operation to additional
+ * update the 'breakpointIsDeleted' attribute.
+ */
+public class DeleteBreakpointMarkersOperation extends DeleteMarkersOperation {
+
+ /**
+ * Create an undoable operation that can delete the specified markers.
+ *
+ * @param markers the markers to be deleted
+ * @param name the name used to describe the operation that deletes the
+ * markers
+ */
+ public DeleteBreakpointMarkersOperation(IMarker[] markers, String name) {
+ super(markers, name);
+ }
+
+ @Override
+ protected void doExecute(IProgressMonitor monitor, org.eclipse.core.runtime.IAdaptable info) throws CoreException {
+ IMarker[] markers = getMarkers();
+ if (markers != null) {
+ for (IMarker marker : markers) {
+ marker.setAttribute(DebugPlugin.ATTR_BREAKPOINT_IS_DELETED, true);
+ }
+ }
+
+ super.doExecute(monitor, info);
+ }
+
+ // Note: do not update 'breakpointIsDeleted' on doUndo (i.e. don't set
+ // breakpointIsDeleted=false on undo). It is important that the recreated
+ // breakpoint has breakpointIsDeleted=true to recognize the recreation in later
+ // code.
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
index e934f3b93..f24c1c9f9 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
@@ -72,6 +72,7 @@ import org.eclipse.debug.internal.ui.memory.MemoryRenderingManager;
import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility;
import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupUIUtils;
import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
+import org.eclipse.debug.internal.ui.views.breakpoints.DeleteBreakpointMarkersOperation;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetManager;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextManager;
@@ -101,7 +102,6 @@ import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.handlers.HandlerUtil;
-import org.eclipse.ui.ide.undo.DeleteMarkersOperation;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
@@ -326,11 +326,6 @@ public class DebugUITools {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoints(breakpoints, !allowUndo);
if (allowUndo) {
-
- for (IMarker marker : markers) {
- marker.setAttribute(DebugPlugin.ATTR_BREAKPOINT_IS_DELETED, true);
- }
-
IAdaptable context= null;
if (shell != null) {
context= new IAdaptable() {
@@ -346,7 +341,7 @@ public class DebugUITools {
}
String operationName= markers.length == 1 ? ActionMessages.DeleteBreakpointOperationName : ActionMessages.DeleteBreakpointsOperationName;
- IUndoableOperation deleteMarkerOperation= new DeleteMarkersOperation(markers, operationName);
+ IUndoableOperation deleteMarkerOperation = new DeleteBreakpointMarkersOperation(markers, operationName);
deleteMarkerOperation.removeContext(WorkspaceUndoUtil.getWorkspaceUndoContext());
deleteMarkerOperation.addContext(DebugUITools.getBreakpointsUndoContext());
IOperationHistory operationHistory= PlatformUI.getWorkbench().getOperationSupport().getOperationHistory();

Back to the top