IDEA-220181 Debugger ignores stepping filters when using new directed step-into

GitOrigin-RevId: 6f9af20ad5eed3f679e211d487699a9a80ce856b
This commit is contained in:
Egor Ushakov
2019-09-25 15:04:22 +00:00
committed by intellij-monorepo-bot
parent daa8137392
commit 1b50dc6b57
14 changed files with 271 additions and 145 deletions
@@ -21,7 +21,7 @@ import java.util.List;
*/
public class BasicStepMethodFilter implements NamedMethodFilter {
private static final Logger LOG = Logger.getInstance(BasicStepMethodFilter.class);
private static final String PROXY_CALL_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;";
private static final String PROXY_CALL_SIGNATURE_POSTFIX = "Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;";
@NotNull
protected final JVMName myDeclaringClassName;
@@ -86,7 +86,7 @@ public class BasicStepMethodFilter implements NamedMethodFilter {
Method method = location.method();
String name = method.name();
if (!myTargetMethodName.equals(name)) {
if (isLambdaCall(process, name, location) || isProxyCall(process, method, stackFrame)) {
if (isLambdaCall(process, name, location)) {
return true;
}
if (!caller && myCheckCaller) {
@@ -138,9 +138,31 @@ public class BasicStepMethodFilter implements NamedMethodFilter {
return false;
}
public boolean proxyCheck(Location location, SuspendContextImpl context, RequestHint hint) {
DebugProcessImpl debugProcess = context.getDebugProcess();
if (isProxyCall(debugProcess, location.method(), context.getFrameProxy())) {
if (!DebugProcessImpl.isPositionFiltered(location)) {
return true;
}
try {
StepIntoMethodBreakpoint breakpoint =
new StepIntoMethodBreakpoint(myDeclaringClassName.getName(debugProcess),
myTargetMethodName,
myTargetMethodSignature != null ? myTargetMethodSignature.getName(debugProcess) : null,
debugProcess.getProject());
DebugProcessImpl.prepareAndSetSteppingBreakpoint(context, breakpoint, hint, false);
}
catch (EvaluateException e) {
LOG.error(e);
}
}
return false;
}
private boolean isProxyCall(DebugProcessImpl process, Method method, @Nullable StackFrameProxyImpl stackFrame) {
try {
if (stackFrame != null && PROXY_CALL_SIGNATURE.equals(method.signature())) {
String signature = method.signature();
if (stackFrame != null && signature != null && signature.endsWith(PROXY_CALL_SIGNATURE_POSTFIX)) {
if ("invoke".equals(method.name())) {
ReferenceType type = method.declaringType();
if (!(type instanceof ClassType) ||
@@ -152,12 +174,13 @@ public class BasicStepMethodFilter implements NamedMethodFilter {
return false;
}
List<Value> argumentValues = stackFrame.getArgumentValues();
if (argumentValues.size() == 3) {
Value proxyValue = argumentValues.get(0);
int size = argumentValues.size();
if (size >= 3) {
Value proxyValue = argumentValues.get(size - 3);
if (proxyValue != null) {
Type proxyType = proxyValue.type();
if (proxyType instanceof ReferenceType && DebuggerUtilsEx.isAssignableFrom(myDeclaringClassName.getName(process), proxyType)) {
Value methodValue = argumentValues.get(1);
Value methodValue = argumentValues.get(size - 2);
if (methodValue instanceof ObjectReference) {
// TODO: no signature check for now
ReferenceType methodType = ((ObjectReference)methodValue).referenceType();
@@ -1,31 +1,13 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.debugger.ui.breakpoints.StepIntoBreakpoint;
import com.intellij.psi.PsiMethod;
import com.intellij.util.Range;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.request.EventRequest;
import org.jetbrains.annotations.NotNull;
/**
* @author egor
@@ -50,7 +32,7 @@ public class ClassInstanceMethodFilter extends ConstructorStepMethodFilter {
if (breakpoint != null) {
breakpoint.addInstanceFilter(reference.uniqueID());
breakpoint.setInstanceFiltersEnabled(true);
setUpStepIntoBreakpoint(context, breakpoint, hint);
DebugProcessImpl.prepareAndSetSteppingBreakpoint(context, breakpoint, hint, true);
return RequestHint.RESUME;
}
}
@@ -60,15 +42,4 @@ public class ClassInstanceMethodFilter extends ConstructorStepMethodFilter {
}
return RequestHint.STOP;
}
static void setUpStepIntoBreakpoint(SuspendContextImpl context, @NotNull StepIntoBreakpoint breakpoint, RequestHint hint) {
DebugProcessImpl debugProcess = context.getDebugProcess();
BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(debugProcess.getProject()).getBreakpointManager();
breakpointManager.applyThreadFilter(debugProcess, null); // clear the filter on resume
breakpoint.setSuspendPolicy(
context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD ? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
breakpoint.createRequest(debugProcess);
breakpoint.setRequestHint(hint);
debugProcess.setRunToCursorBreakpoint(breakpoint);
}
}
@@ -16,10 +16,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.memory.agent.MemoryAgentUtil;
import com.intellij.debugger.requests.Requestor;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.debugger.ui.breakpoints.InstrumentationTracker;
import com.intellij.debugger.ui.breakpoints.RunToCursorBreakpoint;
import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint;
import com.intellij.debugger.ui.breakpoints.*;
import com.intellij.debugger.ui.overhead.OverheadProducer;
import com.intellij.debugger.ui.overhead.OverheadTimings;
import com.intellij.openapi.application.ApplicationManager;
@@ -483,8 +480,8 @@ public class DebugProcessEvents extends DebugProcessImpl {
final String message = "Method <b>" + ((NamedMethodFilter)methodFilter).getMethodName() + "()</b> has not been called";
XDebuggerManagerImpl.NOTIFICATION_GROUP.createNotification(message, MessageType.INFO).notify(project);
}
if (hint.wasStepTargetMethodMatched() && hint.isResetIgnoreFilters()) {
checkPositionNotFiltered(suspendContext.getThread(), filters -> mySession.resetIgnoreStepFiltersFlag());
if (hint.wasStepTargetMethodMatched()) {
suspendContext.getDebugProcess().resetIgnoreSteppingFilters(event.location(), hint);
}
}
}
@@ -519,7 +516,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
boolean resumePreferred = requestor != null && DebuggerSettings.SUSPEND_NONE.equals(requestor.getSuspendPolicy());
boolean requestHit = false;
long start = requestor instanceof OverheadProducer && !(requestor instanceof RunToCursorBreakpoint) ? System.currentTimeMillis() : 0;
long start = requestor instanceof OverheadProducer && ((OverheadProducer)requestor).track() ? System.currentTimeMillis() : 0;
try {
requestHit = (requestor != null) && requestor.processLocatableEvent(this, event);
}
@@ -21,10 +21,7 @@ import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.debugger.ui.breakpoints.RunToCursorBreakpoint;
import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint;
import com.intellij.debugger.ui.breakpoints.StepIntoBreakpoint;
import com.intellij.debugger.ui.breakpoints.*;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.render.ArrayRenderer;
import com.intellij.debugger.ui.tree.render.ClassRenderer;
@@ -61,7 +58,6 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.ui.classFilter.DebuggerClassFilterProvider;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.EventDispatcher;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
@@ -368,8 +364,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
deleteStepRequests(stepThreadReference);
EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager();
StepRequest stepRequest = requestManager.createStepRequest(stepThreadReference, size, depth);
if (!(hint != null && hint.isIgnoreFilters()) /*&& depth == StepRequest.STEP_INTO*/) {
checkPositionNotFiltered(stepThread, filters -> filters.forEach(f -> stepRequest.addClassExclusionFilter(f.getPattern())));
if (!(hint != null && hint.isIgnoreFilters()) && !isPositionFiltered(getLocation(stepThread))) {
getActiveFilters().forEach(f -> stepRequest.addClassExclusionFilter(f.getPattern()));
}
// suspend policy to match the suspend policy of the context:
@@ -387,7 +383,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
try {
stepRequest.enable();
} catch (IllegalThreadStateException e) { // thread is already dead
}
catch (IllegalThreadStateException e) { // thread is already dead
requestManager.deleteEventRequest(stepRequest);
}
}
@@ -396,14 +393,16 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
}
public void checkPositionNotFiltered(ThreadReferenceProxyImpl thread, Consumer<? super List<ClassFilter>> action) {
static boolean isPositionFiltered(Location location) {
List<ClassFilter> activeFilters = getActiveFilters();
if (!activeFilters.isEmpty()) {
String currentClassName = getCurrentClassName(thread);
if (currentClassName == null || !DebuggerUtilsEx.isFiltered(currentClassName, activeFilters)) {
action.consume(activeFilters);
ReferenceType referenceType = location != null ? location.declaringType() : null;
if (referenceType != null) {
String currentClassName = referenceType.name();
return currentClassName != null && DebuggerUtilsEx.isFiltered(currentClassName, activeFilters);
}
}
return false;
}
@NotNull
@@ -437,16 +436,12 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
@Nullable
static String getCurrentClassName(ThreadReferenceProxyImpl thread) {
private static Location getLocation(@Nullable ThreadReferenceProxyImpl thread) {
try {
if (thread != null && thread.frameCount() > 0) {
StackFrameProxyImpl stackFrame = thread.frame(0);
if (stackFrame != null) {
Location location = stackFrame.location();
ReferenceType referenceType = location == null ? null : location.declaringType();
if (referenceType != null) {
return referenceType.name();
}
return stackFrame.location();
}
}
}
@@ -776,17 +771,25 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
myPositionManager.appendPositionManager(positionManager);
}
private volatile RunToCursorBreakpoint myRunToCursorBreakpoint;
private volatile SteppingBreakpoint mySteppingBreakpoint;
public void setSteppingBreakpoint(@Nullable SteppingBreakpoint breakpoint) {
mySteppingBreakpoint = breakpoint;
}
/**
* @deprecated use {@link #setSteppingBreakpoint(SteppingBreakpoint)}
*/
@Deprecated
public void setRunToCursorBreakpoint(@Nullable RunToCursorBreakpoint breakpoint) {
myRunToCursorBreakpoint = breakpoint;
mySteppingBreakpoint = breakpoint;
}
public void cancelRunToCursorBreakpoint() {
DebuggerManagerThreadImpl.assertIsManagerThread();
final RunToCursorBreakpoint runToCursorBreakpoint = myRunToCursorBreakpoint;
final SteppingBreakpoint runToCursorBreakpoint = mySteppingBreakpoint;
if (runToCursorBreakpoint != null) {
setRunToCursorBreakpoint(null);
setSteppingBreakpoint(null);
getRequestsManager().deleteRequest(runToCursorBreakpoint);
if (runToCursorBreakpoint.isRestoreBreakpoints()) {
DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().enableBreakpoints(this);
@@ -794,6 +797,28 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
}
static void prepareAndSetSteppingBreakpoint(SuspendContextImpl context,
@NotNull SteppingBreakpoint breakpoint,
RequestHint hint,
boolean resetThreadFilter) {
DebugProcessImpl debugProcess = context.getDebugProcess();
if (resetThreadFilter) {
BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(debugProcess.getProject()).getBreakpointManager();
breakpointManager.applyThreadFilter(debugProcess, null); // clear the filter on resume
}
breakpoint.setSuspendPolicy(
context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD ? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
breakpoint.createRequest(debugProcess);
breakpoint.setRequestHint(hint);
debugProcess.setSteppingBreakpoint(breakpoint);
}
public void resetIgnoreSteppingFilters(@Nullable Location location, @Nullable RequestHint hint) {
if (hint != null && hint.isResetIgnoreFilters() && location != null && !isPositionFiltered(location)) {
getSession().resetIgnoreStepFiltersFlag();
}
}
protected void closeProcess(boolean closedByUser) {
DebuggerManagerThreadImpl.assertIsManagerThread();
@@ -1579,10 +1604,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
hint.setIgnoreFilters(myForcedIgnoreFilters || mySession.shouldIgnoreSteppingFilters());
applyThreadFilter(stepThread);
if (myBreakpoint != null) {
myBreakpoint.setSuspendPolicy(suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
myBreakpoint.createRequest(suspendContext.getDebugProcess());
myBreakpoint.setRequestHint(hint);
setRunToCursorBreakpoint(myBreakpoint);
prepareAndSetSteppingBreakpoint(suspendContext, myBreakpoint, hint, false);
}
doStep(suspendContext, stepThread, myStepSize, StepRequest.STEP_INTO, hint);
super.contextAction();
@@ -1671,10 +1693,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
}
applyThreadFilter(getContextThread());
final SuspendContextImpl context = getSuspendContext();
myRunToCursorBreakpoint.setSuspendPolicy(context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
prepareAndSetSteppingBreakpoint(context, myRunToCursorBreakpoint, null, false);
final DebugProcessImpl debugProcess = context.getDebugProcess();
myRunToCursorBreakpoint.createRequest(debugProcess);
setRunToCursorBreakpoint(myRunToCursorBreakpoint);
if (debugProcess.getRequestsManager().getWarning(myRunToCursorBreakpoint) == null) {
super.contextAction();
@@ -58,7 +58,7 @@ public class LambdaAsyncMethodFilter extends BasicStepMethodFilter {
Project project = context.getDebugProcess().getProject();
long lambdaId = ((ObjectReference)lambdaReference).uniqueID();
StepIntoBreakpoint breakpoint = new LambdaInstanceBreakpoint(project, lambdaId, pos, myMethodFilter);
ClassInstanceMethodFilter.setUpStepIntoBreakpoint(context, breakpoint, hint);
DebugProcessImpl.prepareAndSetSteppingBreakpoint(context, breakpoint, hint, true);
return RequestHint.RESUME;
}
}
@@ -9,20 +9,16 @@ import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.jdi.StackFrameProxy;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.util.Range;
import com.intellij.util.containers.ContainerUtil;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.request.StepRequest;
import one.util.streamex.StreamEx;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -204,7 +200,9 @@ public class RequestHint {
if (isProxyMethod(location.method())) { // step into bridge and proxy methods
return StepRequest.STEP_INTO;
}
if (myMethodFilter.locationMatches(context.getDebugProcess(), location, context.getFrameProxy())) {
boolean proxyMatch =
(myMethodFilter instanceof BasicStepMethodFilter && ((BasicStepMethodFilter)myMethodFilter).proxyCheck(location, context, this));
if (proxyMatch || myMethodFilter.locationMatches(context.getDebugProcess(), location, context.getFrameProxy())) {
if (myMethodFilter.getSkipCount() <= myFilterMatchedCount++) {
myTargetMethodMatched = true;
return myMethodFilter.onReached(context, this);
@@ -0,0 +1,43 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.engine;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.ui.breakpoints.SteppingBreakpoint;
import com.intellij.openapi.project.Project;
import com.sun.jdi.event.LocatableEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class StepIntoMethodBreakpoint extends SyntheticMethodBreakpoint implements SteppingBreakpoint {
private RequestHint myHint;
public StepIntoMethodBreakpoint(String className, String methodName, @Nullable String signature, Project project) {
super(className, methodName, signature, project);
}
@Override
public boolean isRestoreBreakpoints() {
return true;
}
@Override
public void setRequestHint(RequestHint hint) {
myHint = hint;
}
@Override
public boolean processLocatableEvent(@NotNull SuspendContextCommandImpl action, LocatableEvent event)
throws EventProcessingException {
boolean res = super.processLocatableEvent(action, event);
SuspendContextImpl context = action.getSuspendContext();
if (res && context != null) {
context.getDebugProcess().resetIgnoreSteppingFilters(event.location(), myHint);
}
return res;
}
@Override
public boolean track() {
return false;
}
}
@@ -0,0 +1,93 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.engine;
import com.intellij.debugger.ui.breakpoints.WildcardMethodBreakpoint;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.sun.jdi.Method;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
public class SyntheticMethodBreakpoint extends WildcardMethodBreakpoint {
private final JavaMethodBreakpointProperties myProperties = new JavaMethodBreakpointProperties();
private final String mySignature;
private String mySuspendPolicy;
public SyntheticMethodBreakpoint(String className, String methodName, @Nullable String signature, Project project) {
super(project, null);
myProperties.EMULATED = true;
myProperties.WATCH_EXIT = false;
myProperties.myClassPattern = className;
myProperties.myMethodName = methodName;
mySignature = signature;
}
@Override
public StreamEx matchingMethods(StreamEx<Method> methods, DebugProcessImpl debugProcess) {
String methodName = getMethodName();
return methods
.filter(m -> Comparing.equal(methodName, m.name()) && (mySignature == null || Comparing.equal(mySignature, m.signature())))
.limit(1);
}
@NotNull
@Override
protected JavaMethodBreakpointProperties getProperties() {
return myProperties;
}
@Override
public boolean isCountFilterEnabled() {
return false;
}
@Override
public boolean isClassFiltersEnabled() {
return false;
}
@Override
public boolean isConditionEnabled() {
return false;
}
@Override
public String getSuspendPolicy() {
return mySuspendPolicy;
}
@Override
public void setSuspendPolicy(String policy) {
mySuspendPolicy = policy;
}
@Override
protected void fireBreakpointChanged() {
}
@Override
protected boolean isLogEnabled() {
return false;
}
@Override
protected boolean isLogExpressionEnabled() {
return false;
}
@Override
protected boolean isLogStack() {
return false;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public void setEnabled(boolean enabled) {
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* Class Breakpoint
@@ -244,7 +244,7 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
@Override
public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event) throws EventProcessingException {
public boolean processLocatableEvent(@NotNull SuspendContextCommandImpl action, LocatableEvent event) throws EventProcessingException {
SuspendContextImpl context = action.getSuspendContext();
if (!isValid()) {
context.getDebugProcess().getRequestsManager().deleteRequest(this);
@@ -1,8 +1,9 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.RequestHint;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -17,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Eugene Zhuravlev
*/
public class RunToCursorBreakpoint extends SyntheticLineBreakpoint {
public class RunToCursorBreakpoint extends SyntheticLineBreakpoint implements SteppingBreakpoint {
private final boolean myRestoreBreakpoints;
@NotNull
protected final SourcePosition myCustomPosition;
@@ -44,6 +45,7 @@ public class RunToCursorBreakpoint extends SyntheticLineBreakpoint {
return myCustomPosition.getFile().getName();
}
@Override
public boolean isRestoreBreakpoints() {
return myRestoreBreakpoints;
}
@@ -75,4 +77,13 @@ public class RunToCursorBreakpoint extends SyntheticLineBreakpoint {
}
return new RunToCursorBreakpoint(project, SourcePosition.createFromOffset(psiFile, position.getOffset()), restoreBreakpoints);
}
@Override
public void setRequestHint(RequestHint hint) {
}
@Override
public boolean track() {
return false;
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerBundle;
@@ -19,7 +19,6 @@ import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
@@ -29,10 +28,8 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FixedHashMap;
import com.sun.jdi.*;
import com.sun.jdi.event.LocatableEvent;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
import java.util.Collections;
import java.util.List;
@@ -42,11 +39,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author egor
*/
public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint {
public class StackCapturingLineBreakpoint extends SyntheticMethodBreakpoint {
private static final Logger LOG = Logger.getInstance(StackCapturingLineBreakpoint.class);
private final CapturePoint myCapturePoint;
private final String mySignature;
private final MyEvaluator myCaptureEvaluator;
private final MyEvaluator myInsertEvaluator;
@@ -55,34 +51,16 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint {
private static final Key<Map<Object, List<StackFrameItem>>> CAPTURED_STACKS = Key.create("CAPTURED_STACKS");
private static final int MAX_STORED_STACKS = 1000;
private final JavaMethodBreakpointProperties myProperties = new JavaMethodBreakpointProperties();
public StackCapturingLineBreakpoint(Project project, CapturePoint capturePoint) {
super(project, null);
super(capturePoint.myClassName, capturePoint.myMethodName, null, project);
myCapturePoint = capturePoint;
mySignature = null;
myProperties.EMULATED = true;
myProperties.WATCH_EXIT = false;
myProperties.myClassPattern = myCapturePoint.myClassName;
myProperties.myMethodName = myCapturePoint.myMethodName;
myCaptureEvaluator = new MyEvaluator(myCapturePoint.myCaptureKeyExpression);
myInsertEvaluator = new MyEvaluator(myCapturePoint.myInsertKeyExpression);
}
@NotNull
@Override
protected JavaMethodBreakpointProperties getProperties() {
return myProperties;
setSuspendPolicy(DebuggerSettings.SUSPEND_THREAD);
}
@Override
public String getSuspendPolicy() {
return DebuggerSettings.SUSPEND_THREAD;
}
@Override
public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event) {
public boolean processLocatableEvent(@NotNull SuspendContextCommandImpl action, LocatableEvent event) {
SuspendContextImpl suspendContext = action.getSuspendContext();
if (suspendContext != null) {
ThreadReferenceProxyImpl thread = suspendContext.getThread();
@@ -114,18 +92,6 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint {
return false;
}
@Override
protected void fireBreakpointChanged() {
}
@Override
public StreamEx matchingMethods(StreamEx<Method> methods, DebugProcessImpl debugProcess) {
String methodName = getMethodName();
return methods
.filter(m -> Comparing.equal(methodName, m.name()) && (mySignature == null || Comparing.equal(mySignature, m.signature())))
.limit(1);
}
public static void deleteAll(DebugProcessImpl debugProcess) {
DebuggerManagerThreadImpl.assertIsManagerThread();
List<StackCapturingLineBreakpoint> bpts = debugProcess.getUserData(CAPTURE_BREAKPOINTS);
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.SourcePosition;
@@ -130,19 +116,17 @@ public class StepIntoBreakpoint extends RunToCursorBreakpoint {
}
@Override
public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event)
public boolean processLocatableEvent(@NotNull SuspendContextCommandImpl action, LocatableEvent event)
throws EventProcessingException {
boolean res = super.processLocatableEvent(action, event);
if (res && myHint != null && myHint.isResetIgnoreFilters()) {
SuspendContextImpl context = action.getSuspendContext();
if (context != null) {
DebugProcessImpl process = context.getDebugProcess();
process.checkPositionNotFiltered(context.getThread(), f -> process.getSession().resetIgnoreStepFiltersFlag());
}
SuspendContextImpl context = action.getSuspendContext();
if (res && context != null) {
context.getDebugProcess().resetIgnoreSteppingFilters(event.location(), myHint);
}
return res;
}
@Override
public void setRequestHint(RequestHint hint) {
myHint = hint;
}
@@ -0,0 +1,16 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.RequestHint;
import com.intellij.debugger.requests.Requestor;
public interface SteppingBreakpoint extends Requestor {
boolean isRestoreBreakpoints();
void setRequestHint(RequestHint hint);
void setSuspendPolicy(String s);
void createRequest(DebugProcessImpl process);
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.ui.overhead;
import com.intellij.ui.SimpleColoredComponent;
@@ -14,4 +14,8 @@ public interface OverheadProducer {
default boolean isObsolete() {
return false;
}
default boolean track() {
return true;
}
}