Bug 487998: [breakpoints] Editing code while debug is active

Change-Id: I68361b490a1ba84f0530db37a2da7558c1b762c7
Also-by: Jonah Graham <jonah@kichwacoders.com>
Signed-off-by: Stefan Sprenger <stefan@sprenger.software>
Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICLineBreakpoint2.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICLineBreakpoint2.java
index b2f67e2..3eacf0c 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICLineBreakpoint2.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICLineBreakpoint2.java
@@ -58,6 +58,18 @@
     public static final String REQUESTED_SOURCE_HANDLE = "requestedSourceHandle"; //$NON-NLS-1$ 
 
     /**
+     * Breakpoint attribute which is set if the installed line number of a
+     * breakpoint is changed.
+     * 
+     * Triggers an update of the installed location, if set.
+     * 
+     * This attribute is a <code>Boolean</code>.
+     * 
+     * @since 8.0
+     */
+    public static final String RESET_INSTALLED_LOCATION = "resetInstalledLocation"; //$NON-NLS-1$
+
+    /**
      * Returns the line number where the breakpoint was set before it was relocated to a 
      * valid source line.  
      * 
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractLineBreakpoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractLineBreakpoint.java
index a27942b..bf20ec1 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractLineBreakpoint.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/AbstractLineBreakpoint.java
@@ -150,22 +150,29 @@
     @Override
     public void setRequestedSourceHandle(String fileName) throws CoreException {
         setAttribute( ICLineBreakpoint2.REQUESTED_SOURCE_HANDLE, fileName );
+        setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
     }
     
     @Override
     public synchronized int decrementInstallCount() throws CoreException {
         int count = super.decrementInstallCount();
+
         if (count == 0) {
-            resetInstalledLocation();
+            if (Boolean.TRUE.equals(this.getMarker().getAttribute(RESET_INSTALLED_LOCATION))) {
+                resetInstalledLocation();
+                setAttribute(RESET_INSTALLED_LOCATION, Boolean.FALSE);
+            }
         }
+
         return count;
     }
-    
+
     @Override
     public void setInstalledLineNumber(int line) throws CoreException {
         int existingValue = ensureMarker().getAttribute(IMarker.LINE_NUMBER, -1);
         if (line != existingValue) {
             setAttribute(IMarker.LINE_NUMBER, line);
+            setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
             setAttribute( IMarker.MESSAGE, getMarkerMessage() );
         }
     }
@@ -175,6 +182,7 @@
         int existingValue = ensureMarker().getAttribute(IMarker.CHAR_START, -1);
         if (charStart != existingValue) {
             setAttribute(IMarker.CHAR_START, charStart);
+            setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
             setAttribute( IMarker.MESSAGE, getMarkerMessage() );
         }
     }
@@ -184,6 +192,7 @@
         int existingValue = ensureMarker().getAttribute(IMarker.CHAR_END, -1);
         if (charEnd != existingValue) {
             setAttribute(IMarker.CHAR_END, charEnd);
+            setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
             setAttribute( IMarker.MESSAGE, getMarkerMessage() );
         }
     }
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineTracepoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineTracepoint.java
index b60c371..4d2f4c4 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineTracepoint.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CLineTracepoint.java
@@ -50,9 +50,14 @@
     @Override
     public synchronized int decrementInstallCount() throws CoreException {
         int count = super.decrementInstallCount();
-        if (count == 0) {
-            resetInstalledLocation();
+
+        if (Boolean.TRUE.equals(this.getMarker().getAttribute(RESET_INSTALLED_LOCATION))) {
+            if (count == 0) {
+                resetInstalledLocation();
+                setAttribute(RESET_INSTALLED_LOCATION, Boolean.FALSE);
+            }
         }
+
         return count;
     }
 
@@ -102,6 +107,7 @@
     @Override
     public void setRequestedSourceHandle(String fileName) throws CoreException {
         setAttribute( ICLineBreakpoint2.REQUESTED_SOURCE_HANDLE, fileName );
+        setAttribute(RESET_INSTALLED_LOCATION, Boolean.FALSE);
     }
 
     @Override
@@ -109,6 +115,7 @@
         int existingValue = ensureMarker().getAttribute(IMarker.LINE_NUMBER, -1);
         if (line != existingValue) {
             setAttribute(IMarker.LINE_NUMBER, line);
+            setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
             setAttribute( IMarker.MESSAGE, getMarkerMessage() );
         }
     }
@@ -118,6 +125,7 @@
         int existingValue = ensureMarker().getAttribute(IMarker.CHAR_START, -1);
         if (charStart != existingValue) {
             setAttribute(IMarker.CHAR_START, charStart);
+            setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
             setAttribute( IMarker.MESSAGE, getMarkerMessage() );
         }
     }
@@ -127,6 +135,7 @@
         int existingValue = ensureMarker().getAttribute(IMarker.CHAR_END, -1);
         if (charEnd != existingValue) {
             setAttribute(IMarker.CHAR_END, charEnd);
+            setAttribute(RESET_INSTALLED_LOCATION, Boolean.TRUE);
             setAttribute( IMarker.MESSAGE, getMarkerMessage() );
         }
     }
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java
index 20cf915..2477958 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPreferenceStore.java
@@ -200,10 +200,13 @@
 						}
 						else if ( property.equals( IMarker.LINE_NUMBER ) ) {
 							if (breakpoint instanceof ICLineBreakpoint2) {
-								// Must set the REQUESTED_LINE attribute first, or else the breakpoint
-								// message will be refreshed improperly
+								// refresh message and line number
+								// Note there are no API methods to set the line number of a Line Breakpoint, so we
+								// replicate what is done in CDIDebugModel.setLineBreakpointAttributes()
+								// to set the line number fields properly and then refresh the message if possible
 								((ICLineBreakpoint2)breakpoint).setRequestedLine(getInt(IMarker.LINE_NUMBER));
-								((ICLineBreakpoint2)breakpoint).setInstalledLineNumber(getInt(IMarker.LINE_NUMBER));
+								breakpoint.getMarker().setAttribute(IMarker.LINE_NUMBER, getInt(IMarker.LINE_NUMBER));
+								((ICBreakpoint2)breakpoint).refreshMessage();
 							} else {
 								// already workspace runnable, setting markers are safe
 								breakpoint.getMarker().setAttribute(IMarker.LINE_NUMBER, getInt(IMarker.LINE_NUMBER));