mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
[debugger] Introduce a way to provide evaluationContext without converting it to pausedContext
GitOrigin-RevId: 0b640745949259f4054467cbf047201c97838bc5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b4a3c40497
commit
3edbfaa5d0
@@ -2,8 +2,10 @@
|
||||
package com.intellij.debugger.engine;
|
||||
|
||||
import com.intellij.debugger.*;
|
||||
import com.intellij.debugger.engine.evaluation.DebuggerImplicitEvaluationContextUtil;
|
||||
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.engine.jdi.ThreadReferenceProxy;
|
||||
import com.intellij.debugger.engine.requests.CustomProcessingLocatableEventRequestor;
|
||||
import com.intellij.debugger.engine.requests.LocatableEventRequestor;
|
||||
import com.intellij.debugger.engine.requests.MethodReturnValueWatcher;
|
||||
@@ -283,7 +285,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
||||
//((SuspendManagerImpl)getSuspendManager()).popContext(context);
|
||||
}
|
||||
else if (!DebuggerSession.enableBreakpointsDuringEvaluation()) {
|
||||
notifySkippedBreakpointInEvaluation(locatableEvent);
|
||||
notifySkippedBreakpointInEvaluation(locatableEvent, context);
|
||||
DebuggerUtilsAsync.resume(eventSet);
|
||||
return true;
|
||||
}
|
||||
@@ -642,7 +644,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
||||
if ((isEvaluationOnCurrentThread || mySuspendAllInvocation.get() > 0) &&
|
||||
!(requestor instanceof InstrumentationTracker.InstrumentationMethodBreakpoint) &&
|
||||
!DebuggerSession.enableBreakpointsDuringEvaluation()) {
|
||||
notifySkippedBreakpointInEvaluation(event);
|
||||
notifySkippedBreakpointInEvaluation(event, suspendContext);
|
||||
// is inside evaluation, so ignore any breakpoints
|
||||
suspendManager.voteResume(suspendContext);
|
||||
return;
|
||||
@@ -658,7 +660,10 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
||||
LightOrRealThreadInfo filter = getRequestsManager().getFilterThread();
|
||||
if (filter != null) {
|
||||
if (myPreparingToSuspendAll || !filter.checkSameThread(thread, suspendContext)) {
|
||||
notifySkippedBreakpoints(event, SkippedBreakpointReason.STEPPING);
|
||||
// notify only if the current session is not one with evaluations hidden from the user
|
||||
if (!checkContextIsFromImplicitThread(suspendContext)) {
|
||||
notifySkippedBreakpoints(event, SkippedBreakpointReason.STEPPING);
|
||||
}
|
||||
suspendManager.voteResume(suspendContext);
|
||||
return;
|
||||
}
|
||||
@@ -836,7 +841,12 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
||||
STEPPING, // Suspend-all stepping ignores breakpoints in other threads for the sake of ease-of-debug.
|
||||
}
|
||||
|
||||
private void notifySkippedBreakpointInEvaluation(@Nullable LocatableEvent event) {
|
||||
private void notifySkippedBreakpointInEvaluation(@Nullable LocatableEvent event, @NotNull SuspendContextImpl suspendContext) {
|
||||
// notify only if the current session is not one with evaluations hidden from the user
|
||||
if (checkContextIsFromImplicitThread(suspendContext)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkippedBreakpointReason reason = SkippedBreakpointReason.EVALUATION_IN_ANOTHER_THREAD;
|
||||
if (event != null) {
|
||||
ThreadReferenceProxyImpl proxy = getVirtualMachineProxy().getThreadReferenceProxy(event.thread());
|
||||
@@ -847,6 +857,25 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
||||
notifySkippedBreakpoints(event, reason);
|
||||
}
|
||||
|
||||
private boolean checkContextIsFromImplicitThread(@NotNull SuspendContextImpl eventContext) {
|
||||
DebugProcess debugProcess = eventContext.getDebugProcess();
|
||||
LightOrRealThreadInfo implicitThread = DebuggerImplicitEvaluationContextUtil.getImplicitEvaluationThread(debugProcess);
|
||||
LightOrRealThreadInfo filterThread = getRequestsManager().getFilterThread();
|
||||
ThreadReferenceProxy eventThread = eventContext.getThread();
|
||||
|
||||
if (implicitThread == null || eventThread == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Case 1: We have filter and implicit threads provided, they are different, hence, this skipped breakpoint is no use for the user
|
||||
if (filterThread != null && !implicitThread.checkSameThread(eventThread.getThreadReference(), eventContext)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Case 2: Implicit thread is provided, no filter thread, check correct hit
|
||||
return implicitThread.checkSameThread(eventThread.getThreadReference(), eventContext);
|
||||
}
|
||||
|
||||
private void notifySkippedBreakpoints(@Nullable LocatableEvent event, SkippedBreakpointReason reason) {
|
||||
if (event == null) return;
|
||||
|
||||
|
||||
@@ -2604,7 +2604,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
}
|
||||
|
||||
public boolean isEvaluationPossible() {
|
||||
return getSuspendManager().getPausedContext() != null;
|
||||
return getSuspendManager().getPausedContext() != null
|
||||
|| DebuggerImplicitEvaluationContextUtil.getImplicitEvaluationThread(this) != null;
|
||||
}
|
||||
|
||||
public boolean isEvaluationPossible(SuspendContextImpl suspendContext) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.debugger.engine.evaluation;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.LightOrRealThreadInfo;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* Utility class for providing an implicit evaluation-ready {@link LightOrRealThreadInfo} for a particular {@link DebugProcess}.
|
||||
* This might be useful to support evaluations in the current {@link com.intellij.debugger.impl.DebuggerSession},
|
||||
* but keeping any UI elements hidden.
|
||||
* <p>
|
||||
* {@link DebugProcessImpl#isEvaluationPossible()}
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public final class DebuggerImplicitEvaluationContextUtil {
|
||||
private static final Key<LightOrRealThreadInfo> IMPLICIT_EVALUATION_READY_THREAD_KEY = new Key<>("ImplicitEvaluationThread");
|
||||
|
||||
public static LightOrRealThreadInfo getImplicitEvaluationThread(DebugProcess process) {
|
||||
return process.getUserData(IMPLICIT_EVALUATION_READY_THREAD_KEY);
|
||||
}
|
||||
|
||||
public static void provideImplicitEvaluationThread(DebugProcess process, LightOrRealThreadInfo thread) {
|
||||
process.putUserData(IMPLICIT_EVALUATION_READY_THREAD_KEY, thread);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user