diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF index 854112f49e0..d3faff212bb 100644 --- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.core; singleton:=true -Bundle-Version: 8.1.0.qualifier +Bundle-Version: 8.2.0.qualifier Bundle-Activator: org.eclipse.cdt.debug.core.CDebugCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java index 22850a291de..44429d76497 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java @@ -34,6 +34,8 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpoint2; +import org.eclipse.cdt.debug.core.model.ICBreakpointExtension; import org.eclipse.cdt.debug.core.model.ICBreakpointType; import org.eclipse.cdt.debug.core.model.ICDynamicPrintf; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; @@ -345,6 +347,7 @@ public class CDebugUtils { appendPrintfString((ICDynamicPrintf)breakpoint, label); } appendBreakpointType(breakpoint, label); + appendExtensionMessage(breakpoint, label); appendIgnoreCount(breakpoint, label); appendCondition(breakpoint, label); return label.toString(); @@ -360,6 +363,7 @@ public class CDebugUtils { appendWatchRange(wp2, label); } appendBreakpointType(watchpoint, label); + appendExtensionMessage(watchpoint, label); appendIgnoreCount(watchpoint, label); appendCondition(watchpoint, label); return label.toString(); @@ -373,6 +377,7 @@ public class CDebugUtils { appendPrintfString((ICDynamicPrintf)breakpoint, label); } appendBreakpointType(breakpoint, label); + appendExtensionMessage(breakpoint, label); appendIgnoreCount(breakpoint, label); appendCondition(breakpoint, label); return label.toString(); @@ -386,11 +391,33 @@ public class CDebugUtils { appendPrintfString((ICDynamicPrintf)breakpoint, label); } appendBreakpointType(breakpoint, label); + appendExtensionMessage(breakpoint, label); appendIgnoreCount(breakpoint, label); appendCondition(breakpoint, label); return label.toString(); } + /** + * Append the Breakpoint Extension message to the breakpoint text in buffer. + * + * @param breakpoint C Breakpoint + * @param buffer buffer to append message to + * @see {@link ICBreakpointExtension#getExtensionMessage() + * @since 8.2 + */ + protected static void appendExtensionMessage(ICBreakpoint breakpoint, StringBuffer buffer) { + if (breakpoint instanceof ICBreakpoint2) { + ICBreakpoint2 breakpoint2 = (ICBreakpoint2) breakpoint; + String message = breakpoint2.getExtensionMessage(); + if (message != null && !message.isEmpty()) { + if (buffer.length() > 0) { + buffer.append(' '); + } + buffer.append(message); + } + } + } + protected static StringBuffer appendSourceName(ICBreakpoint breakpoint, StringBuffer label, boolean qualified) throws CoreException { String handle = breakpoint.getSourceHandle(); if (!isEmpty(handle)) { diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint2.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint2.java index 0c2a784def7..3a35e9a9997 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint2.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint2.java @@ -41,4 +41,15 @@ public interface ICBreakpoint2 extends ICBreakpoint { * @return marker type ID */ public String getMarkerType(); + + /** + * Obtain the combined message from all installed extensions on the + * breakpoint. See {@link ICBreakpointExtension#getExtensionMessage} + * + * @return extension message, or empty-string ({@code ""}) for no message + * @since 8.2 + */ + default public String getExtensionMessage() { + return ""; //$NON-NLS-1$ + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java index 043d2373e84..2c7456f6d98 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java @@ -40,4 +40,15 @@ public interface ICBreakpointExtension { * marker. */ public void initialize(ICBreakpoint breakpoint) throws CoreException; + + /** + * Return the message associated with this breakpoint extension. This + * message will form part of the marker's message in the Eclipse UI. + * + * @return custom message, or empty-string ({@code ""}) for no message + * @since 8.2 + */ + default public String getExtensionMessage() { + return ""; //$NON-NLS-1$ + }; } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java index 26c00a67833..f31db999c1b 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java @@ -12,9 +12,11 @@ package org.eclipse.cdt.debug.internal.core.breakpoints; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; import org.eclipse.cdt.debug.core.CDIDebugModel; import org.eclipse.cdt.debug.core.CDebugCorePlugin; @@ -31,6 +33,7 @@ import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; @@ -48,8 +51,11 @@ public abstract class CBreakpoint extends Breakpoint implements ICBreakpoint2, I /** * Map of breakpoint extensions. The keys to the map are debug model IDs * and values are arrays of breakpoint extensions. + * + * This map is sorted to allow consistent iteration order so that extension + * message does not unexpectedly change order */ - private Map fExtensions = new HashMap(1); + private SortedMap fExtensions = new TreeMap(); /** * The number of debug targets the breakpoint is installed in. We don't use @@ -332,4 +338,29 @@ public abstract class CBreakpoint extends Breakpoint implements ICBreakpoint2, I IMarker marker = ensureMarker(); marker.setAttribute(IMarker.MESSAGE, getMarkerMessage()); } + + @Override + public String getExtensionMessage() { + Collection extensionLists; + synchronized (fExtensions) { + extensionLists = new ArrayList<>(fExtensions.values()); + } + + StringBuilder sb = new StringBuilder(); + for (ICBreakpointExtension[] extensions : extensionLists) { + for (ICBreakpointExtension extension : extensions) { + SafeRunner.run(() -> { + String message = extension.getExtensionMessage(); + if (message != null && !message.isEmpty()) { + if (sb.length() > 0) { + sb.append(' '); + } + sb.append(message); + } + }); + } + } + + return sb.toString(); + } }