IDEA-364368, debugger: listener for breakpoint log messages

GitOrigin-RevId: 7ab775330d97cafff32ba15696b585a1c094c2a2
This commit is contained in:
Vladimir Parfinenko
2026-01-13 19:00:21 +00:00
committed by intellij-monorepo-bot
parent 278f59a2d0
commit 5e8f20e99e
3 changed files with 40 additions and 2 deletions
@@ -100,6 +100,10 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
return myProject;
}
private @NotNull BreakpointManager getBreakpointManager() {
return DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager();
}
protected @NotNull P getProperties() {
return myXBreakpoint.getProperties();
}
@@ -395,7 +399,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
buf.append("\n");
}
if (!buf.isEmpty()) {
debugProcess.printToConsole(buf.toString());
var msg = buf.toString();
getBreakpointManager().multicastLogMessage(this, msg, debugProcess);
debugProcess.printToConsole(msg);
}
}
if (isRemoveAfterHit()) {
@@ -623,7 +629,7 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
private void removeBreakpoint() {
AppUIUtil.invokeOnEdt(() -> DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(Breakpoint.this));
AppUIUtil.invokeOnEdt(() -> getBreakpointManager().removeBreakpoint(Breakpoint.this));
debugProcess.removeDebugProcessListener(this);
}
});
@@ -0,0 +1,14 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.ui.breakpoints
import com.intellij.debugger.engine.DebugProcessImpl
import org.jetbrains.annotations.ApiStatus
import java.util.EventListener
/**
* Listener for breakpoint messages: evaluate and log, stack trace, "breakpoint hit", etc.
*/
@ApiStatus.Internal
fun interface BreakpointLogMessageListener : EventListener {
fun onLogMessage(breakpoint: Breakpoint<*>, message: String, debugProcess: DebugProcessImpl)
}
@@ -14,6 +14,7 @@ import com.intellij.debugger.engine.LightOrRealThreadInfo;
import com.intellij.debugger.engine.RealThreadInfo;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.WriteAction;
@@ -33,6 +34,8 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiField;
import com.intellij.util.CoroutineScopeKt;
import com.intellij.util.EventDispatcher;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.concurrency.ThreadingAssertions;
import com.intellij.util.containers.ContainerUtil;
@@ -55,6 +58,7 @@ import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.InvalidRequestStateException;
import kotlinx.coroutines.CoroutineScope;
import one.util.streamex.StreamEx;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -86,6 +90,8 @@ public class BreakpointManager {
private final Project myProject;
private final Map<String, String> myUIProperties = new LinkedHashMap<>();
private final EventDispatcher<BreakpointLogMessageListener> myLogMessageDispatcher = EventDispatcher.create(BreakpointLogMessageListener.class);
public BreakpointManager(@NotNull Project project, @NotNull DebuggerManagerImpl debuggerManager) {
myProject = project;
debuggerManager.getContextManager().addListener(new DebuggerContextListener() {
@@ -665,4 +671,16 @@ public class BreakpointManager {
public String setProperty(String name, String value) {
return myUIProperties.put(name, value);
}
public void addLogMessageListener(CoroutineScope scope, BreakpointLogMessageListener listener) {
addLogMessageListener(listener, CoroutineScopeKt.asDisposable(scope));
}
private void addLogMessageListener(BreakpointLogMessageListener listener, Disposable parentDisposable) {
myLogMessageDispatcher.addListener(listener, parentDisposable);
}
void multicastLogMessage(Breakpoint<?> breakpoint, String message, DebugProcessImpl debugProcess) {
myLogMessageDispatcher.getMulticaster().onLogMessage(breakpoint, message, debugProcess);
}
}