From 7e682ec832af486677290ff6671c34c579ceaf9b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 27 Oct 2015 18:06:12 +0100 Subject: [PATCH] IDEA-141563 GWT: breakpoints stop working after recompile --- .../jetbrains/debugger/BreakpointManager.kt | 3 + .../debugger/LineBreakpointManager.kt | 61 +++++++++++++++---- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt index 6e12dd246663..62372480254d 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt @@ -65,4 +65,7 @@ interface BreakpointListener : EventListener { fun resolved(breakpoint: Breakpoint) fun errorOccurred(breakpoint: Breakpoint, errorMessage: String?) + + fun nonProvisionalBreakpointRemoved(breakpoint: Breakpoint) { + } } \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt index cc9be4138e8f..ff8175839ba5 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt @@ -17,7 +17,6 @@ package org.jetbrains.debugger import com.intellij.icons.AllIcons import com.intellij.util.SmartList -import com.intellij.util.containers.MultiMap import com.intellij.xdebugger.XSourcePosition import com.intellij.xdebugger.breakpoints.XLineBreakpoint import gnu.trove.THashMap @@ -28,7 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl<*>) { private val ideToVmBreakpoints = THashMap, MutableList>() - protected val vmToIdeBreakpoint: MultiMap> = MultiMap.createSmart() + protected val vmToIdeBreakpoints = THashMap>>() private val runToLocationBreakpoints = THashSet() private val lock = Object() @@ -74,7 +73,7 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< vmBreakpoints = list while (iterator.hasNext()) { val vmBreakpoint = iterator.next() - if (vmToIdeBreakpoint.get(vmBreakpoint).size > 1) { + if ((vmToIdeBreakpoints.get(vmBreakpoint)?.size ?: -1) > 1) { // we must not disable vm breakpoint - it is used for another ide breakpoints iterator.remove() } @@ -84,8 +83,8 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< vmBreakpoints = ideToVmBreakpoints.remove(breakpoint) ?: return resolvedPromise() if (!vmBreakpoints.isEmpty()) { for (vmBreakpoint in vmBreakpoints) { - vmToIdeBreakpoint.remove(vmBreakpoint, breakpoint) - if (vmToIdeBreakpoint.containsKey(vmBreakpoint)) { + vmToIdeBreakpoints.remove(vmBreakpoint, breakpoint) + if (vmToIdeBreakpoints.containsKey(vmBreakpoint)) { // we must not remove vm breakpoint - it is used for another ide breakpoints return resolvedPromise() } @@ -126,7 +125,7 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< synchronized (lock) { ideToVmBreakpoints.put(breakpoint, vmBreakpoints) for (vmBreakpoint in vmBreakpoints) { - vmToIdeBreakpoint.putValue(vmBreakpoint, breakpoint) + vmToIdeBreakpoints.putValue(vmBreakpoint, breakpoint) } } } @@ -135,9 +134,10 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< if (breakpointResolvedListenerAdded.compareAndSet(false, true)) { breakpointManager.addBreakpointListener(object : BreakpointListener { override fun resolved(breakpoint: Breakpoint) { - var breakpoints = synchronized (lock) { vmToIdeBreakpoint.get(breakpoint) } - for (ideBreakpoint in breakpoints) { - debugProcess.session.updateBreakpointPresentation(ideBreakpoint, AllIcons.Debugger.Db_verified_breakpoint, null) + synchronized (lock) { vmToIdeBreakpoints.get(breakpoint) }?.let { + for (ideBreakpoint in it) { + debugProcess.session.updateBreakpointPresentation(ideBreakpoint, AllIcons.Debugger.Db_verified_breakpoint, null) + } } } @@ -151,11 +151,28 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< return } - var breakpoints = synchronized (lock) { vmToIdeBreakpoint.get(breakpoint) } - for (ideBreakpoint in breakpoints) { - debugProcess.session.updateBreakpointPresentation(ideBreakpoint, AllIcons.Debugger.Db_invalid_breakpoint, errorMessage) + synchronized (lock) { vmToIdeBreakpoints.get(breakpoint) }?.let { + for (ideBreakpoint in it) { + debugProcess.session.updateBreakpointPresentation(ideBreakpoint, AllIcons.Debugger.Db_invalid_breakpoint, errorMessage) + } } } + + override fun nonProvisionalBreakpointRemoved(breakpoint: Breakpoint) { + synchronized (lock) { + vmToIdeBreakpoints.remove(breakpoint)?.let { + for (ideBreakpoint in it) { + ideToVmBreakpoints.remove(ideBreakpoint, breakpoint) + } + it + } + } + ?.let { + for (ideBreakpoint in it) { + setBreakpoint(ideBreakpoint, debugProcess.getLocationsForBreakpoint(ideBreakpoint, false)) + } + } + } }) } @@ -198,7 +215,7 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< fun removeAllBreakpoints(): org.jetbrains.concurrency.Promise<*> { synchronized (lock) { ideToVmBreakpoints.clear() - vmToIdeBreakpoint.clear() + vmToIdeBreakpoints.clear() runToLocationBreakpoints.clear() } return breakpointManager.removeAll() @@ -219,4 +236,22 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< breakpointManager.remove(breakpoint) } } +} + +internal fun MutableMap>.remove(key: K, value: V) { + var list = get(key) + if (list != null && list.remove(value) && list.isEmpty()) { + remove(key) + } +} + +internal fun MutableMap>.putValue(key: K, value: V) { + var list = get(key) + if (list == null) { + list = SmartList(value) + put(key, list) + } + else { + list.add(value) + } } \ No newline at end of file