From f227a20bb8afb02aecb67d675ccc746d32051f17 Mon Sep 17 00:00:00 2001 From: Maksim Zuev Date: Tue, 30 Jul 2024 15:39:53 +0200 Subject: [PATCH] [debugger] IJPL-158332 Simplify java debugger notifications on hotswap failure * do not include session name * use balloon notification GitOrigin-RevId: f9492529682e0a78b621a4184045ab8a3312666c --- .../debugger/impl/ReloadClassesWorker.java | 6 +-- .../debugger/ui/HotSwapProgressImpl.java | 54 ++++++++++++------- .../intellij/debugger/ui/HotSwapUIImpl.java | 2 +- .../messages/JavaDebuggerBundle.properties | 2 +- .../messages/XDebuggerBundle.properties | 1 + .../resources/META-INF/xdebugger.xml | 1 + 6 files changed, 41 insertions(+), 25 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java index b0119f69f4b3..72fb9a394b61 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java @@ -45,10 +45,6 @@ class ReloadClassesWorker { } private void processException(@NotNull Throwable e) { - if (e.getMessage() != null) { - myProgress.addMessage(myDebuggerSession, MessageCategory.ERROR, e.getMessage()); - } - if (e instanceof ProcessCanceledException) { myProgress.addMessage(myDebuggerSession, MessageCategory.INFORMATION, JavaDebuggerBundle.message("error.operation.canceled")); return; @@ -56,7 +52,7 @@ class ReloadClassesWorker { String message = e instanceof UnsupportedOperationException - ? JavaDebuggerBundle.message("error.operation.not.supported.by.vm") + ? JavaDebuggerBundle.message("error.operation.not.supported.by.vm", e.getLocalizedMessage()) : e instanceof NoClassDefFoundError ? JavaDebuggerBundle.message("error.class.def.not.found", e.getLocalizedMessage()) : e instanceof VerifyError diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java index 2e966ddedf57..927262402e7c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapProgressImpl.java @@ -7,10 +7,7 @@ import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.impl.HotSwapProgress; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionUtil; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationAction; -import com.intellij.notification.NotificationGroup; -import com.intellij.notification.NotificationType; +import com.intellij.notification.*; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; @@ -19,7 +16,7 @@ import com.intellij.openapi.progress.util.ProgressWindow; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.NlsSafe; -import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.reference.SoftReference; import com.intellij.util.SmartList; @@ -31,19 +28,24 @@ import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.impl.XDebugSessionImpl; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.ints.IntIterator; import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; import java.awt.*; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; public final class HotSwapProgressImpl extends HotSwapProgress { - static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("HotSwap", ToolWindowId.DEBUG); + static final NotificationGroup NOTIFICATION_GROUP = Registry.is("debugger.hotswap.floating.toolbar") + ? NotificationGroupManager.getInstance().getNotificationGroup("HotSwap Messages") + : NotificationGroup.toolWindowGroup("HotSwap", ToolWindowId.DEBUG); - private final Int2ObjectMap> myMessages = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap>> myMessages = new Int2ObjectOpenHashMap<>(); private final ProgressWindow myProgressWindow; private @NlsContexts.ProgressTitle String myTitle = JavaDebuggerBundle.message("progress.hot.swap.title"); private final MergingUpdateQueue myUpdateQueue; @@ -81,8 +83,11 @@ public final class HotSwapProgressImpl extends HotSwapProgress { listener.onFinish(); } - List errors = getMessages(MessageCategory.ERROR); - List warnings = getMessages(MessageCategory.WARNING); + var debuggerSessions = myMessages.values().stream().flatMap(e -> e.keySet().stream()).collect(Collectors.toUnmodifiableSet()); + boolean addSessionName = debuggerSessions.size() > 1; + + List errors = getMessages(MessageCategory.ERROR, addSessionName); + List warnings = getMessages(MessageCategory.WARNING, addSessionName); if (!errors.isEmpty()) { notifyUser(JavaDebuggerBundle.message("status.hot.swap.completed.with.errors"), buildMessage(errors), true, NotificationType.ERROR); @@ -93,8 +98,8 @@ public final class HotSwapProgressImpl extends HotSwapProgress { } else if (!myMessages.isEmpty()) { List messages = new ArrayList<>(); - for (IntIterator iterator = myMessages.keySet().iterator(); iterator.hasNext(); ) { - messages.addAll(getMessages(iterator.nextInt())); + for (int key : myMessages.keySet()) { + messages.addAll(getMessages(key, addSessionName)); } notifyUser("", buildMessage(messages), false, NotificationType.INFORMATION); } @@ -118,22 +123,35 @@ public final class HotSwapProgressImpl extends HotSwapProgress { mySessionRef = new WeakReference<>(session.getXDebugSession()); } - List getMessages(int category) { - return ContainerUtil.notNullize(myMessages.get(category)); + private @NotNull @Unmodifiable List getMessages(int category, boolean addSessionName) { + var sessionMessages = ContainerUtil.notNullize(myMessages.get(category)); + return sessionMessages.entrySet().stream().flatMap(entry -> { + var stream = entry.getValue().stream(); + return addSessionName ? stream.map(message -> entry.getKey().getSessionName() + ": " + message) : stream; + }).toList(); + } + + boolean hasErrors() { + return !getMessages(MessageCategory.ERROR, false).isEmpty(); } private static @NlsSafe String buildMessage(List messages) { - return StreamEx.of(messages).map(m -> StringUtil.trimEnd(m, ';')).joining("\n"); + return StreamEx.of(messages).joining("\n"); } @Override public void addMessage(DebuggerSession session, final int type, final String text) { - List messages = myMessages.get(type); + Map> messages = myMessages.get(type); if (messages == null) { - messages = new SmartList<>(); + messages = new HashMap<>(); myMessages.put(type, messages); } - messages.add(session.getSessionName() + ": " + text + ";"); + List sessionMessages = messages.get(session); + if (sessionMessages == null) { + sessionMessages = new SmartList<>(); + messages.put(session, sessionMessages); + } + sessionMessages.add(text); } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java index 8d1d727f5d0b..d9a30f5f590b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java @@ -203,7 +203,7 @@ public final class HotSwapUIImpl extends HotSwapUI { @Override public void onFinish() { - if (progress.getMessages(MessageCategory.ERROR).isEmpty()) { + if (!progress.hasErrors()) { statusListener.onSuccess(sessions); } else { diff --git a/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties b/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties index d8b8bfb5947f..4cdc4ccb0697 100644 --- a/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties +++ b/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties @@ -168,7 +168,7 @@ progress.hotswap.scanning.path=Scanning: {0} progress.hotswap.scanning.classes=Scanning for classes to reload... progress.hotswap.reloading=Reloading classes... error.operation.canceled=Operation canceled -error.operation.not.supported.by.vm=Operation not supported by VM +error.operation.not.supported.by.vm=Operation not supported by VM : {0} error.class.def.not.found=Class definition not found : {0} error.verification.error=Verification error : {0} error.unsupported.class.version=Unsupported class version : {0} diff --git a/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties b/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties index 32cda4476d4d..a2196b4e9672 100644 --- a/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties +++ b/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties @@ -334,4 +334,5 @@ xdebugger.visualized.text.name.jwt=JWT xdebugger.visualized.text.name.url=URL (decoded) xdebugger.hotswap.code.changed=Code changed: +notification.group.debugger.hotswap.messages=Hotswap failed xdebugger.hotswap.status.success=Code has been reloaded diff --git a/platform/xdebugger-impl/resources/META-INF/xdebugger.xml b/platform/xdebugger-impl/resources/META-INF/xdebugger.xml index fbf4ac3839dd..9fc705079370 100644 --- a/platform/xdebugger-impl/resources/META-INF/xdebugger.xml +++ b/platform/xdebugger-impl/resources/META-INF/xdebugger.xml @@ -109,6 +109,7 @@ +