diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java index 5d8281e5c20b..c04893cff86b 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java @@ -222,6 +222,14 @@ public abstract class XLineBreakpointType
exten
@Nullable
public abstract TextRange getHighlightRange();
+ /**
+ * The priority is considered when several breakpoint variants can be set on the same line,
+ * in this case we choose the variant with the highest priority.
+ */
+ public int getPriority(@NotNull Project project) {
+ return getType().getPriority();
+ }
+
/**
* @return true iff this variant corresponds to breakpoint hitting at all line locations
* (i.e., "all", "line and all lambdas")
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
index 452dbcf4fa90..cd6f8347b07a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
@@ -308,30 +308,43 @@ public class XDebuggerUtilImpl extends XDebuggerUtil {
if (areInlineBreakpointsEnabled(file)) {
return variantsAsync.then(variantsWithAll -> {
var variants = variantsWithAll.stream().filter(v -> !v.isMultiVariant()).toList();
-
- var breakpointOrVariant = getBestMatchingBreakpoint(selectVariantByPositionColumn ? position.getOffset() : 0,
- Stream.concat(
- types.stream().flatMap(t -> breakpointManager.findBreakpointsAtLine(t, file, line).stream()),
- variants.stream()).iterator(),
- o ->
- o instanceof XLineBreakpoint b
- ? b.getType().getHighlightRange(b)
- : ((XLineBreakpointType.XLineBreakpointVariant)o).getHighlightRange());
-
- if (breakpointOrVariant instanceof XLineBreakpoint existingBreakpoint) {
- if (!temporary && canRemove) {
- removeBreakpointWithConfirmation(project, existingBreakpoint);
- }
+ if (variants.isEmpty()) {
+ LOG.error("Unexpected empty variants");
return null;
}
- if (breakpointOrVariant instanceof XLineBreakpointType.XLineBreakpointVariant variant) {
- return addLineBreakpoint(breakpointManager, variant, file, line, temporary);
+ var breakpoints = types.stream().flatMap(t -> breakpointManager.findBreakpointsAtLine(t, file, line).stream()).toList();
+
+ XLineBreakpointType.XLineBreakpointVariant variant;
+ if (selectVariantByPositionColumn) {
+ var breakpointOrVariant = getBestMatchingBreakpoint(position.getOffset(),
+ Stream.concat(breakpoints.stream(), variants.stream()).iterator(),
+ o ->
+ o instanceof XLineBreakpoint b
+ ? b.getType().getHighlightRange(b)
+ : ((XLineBreakpointType.XLineBreakpointVariant)o).getHighlightRange());
+
+ if (breakpointOrVariant instanceof XLineBreakpoint existingBreakpoint) {
+ if (!temporary && canRemove) {
+ removeBreakpointWithConfirmation(project, existingBreakpoint);
+ }
+ return null;
+ }
+
+ variant = (XLineBreakpointType.XLineBreakpointVariant)breakpointOrVariant;
+ }
+ else {
+ if (!breakpoints.isEmpty()) {
+ if (!temporary && canRemove) {
+ removeBreakpointsWithConfirmation(project, breakpoints);
+ }
+ return null;
+ }
+
+ variant = variants.stream().max(Comparator.comparing(v -> v.getPriority(project))).get();
}
- assert !variants.isEmpty();
- LOG.error("Unexpected breakpoint toggle state, any variant would be considered as the best one");
- return null;
+ return addLineBreakpoint(breakpointManager, variant, file, line, temporary);
});
}
@@ -503,6 +516,21 @@ public class XDebuggerUtilImpl extends XDebuggerUtil {
return removeBreakpointWithConfirmation(breakpoint.getProject(), breakpoint);
}
+ public static > void removeBreakpointsWithConfirmation(final Project project, final List breakpoints) {
+ // FIXME[inline-bp]: support multiple breakpoints restore
+ // FIXME[inline-bp]: Reconsider this, maybe we should have single confirmation for all breakpoints.
+ for (XBreakpoint> b : breakpoints) {
+ removeBreakpointWithConfirmation(project, b);
+ }
+ }
+
+ public static > void removeBreakpointsWithConfirmation(final List breakpoints) {
+ if (breakpoints.isEmpty()) return;
+ var project = breakpoints.get(0).getProject();
+ LOG.assertTrue(ContainerUtil.and(breakpoints, b -> b.getProject().equals(project)));
+ removeBreakpointsWithConfirmation(project, breakpoints);
+ }
+
public static void reshowInlayRunToCursor(@NotNull AnActionEvent e) {
if (!(e.getInputEvent() instanceof MouseEvent)) {
return;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
index f5e5e2245381..29f3004d4a71 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
@@ -695,11 +695,7 @@ public class XBreakpointBase