diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java index c5051f493207..c81a6b7289db 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java @@ -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 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(); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/ClassInstanceMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/ClassInstanceMethodFilter.java index edb104f78f7d..da5a9f8a904e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/ClassInstanceMethodFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/ClassInstanceMethodFilter.java @@ -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); - } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index b976ddc41eb3..ce4f9d6bbf6b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -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 " + ((NamedMethodFilter)methodFilter).getMethodName() + "() 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); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index e3c59d1e30a7..0016ffef947e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -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> action) { + static boolean isPositionFiltered(Location location) { List 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(); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/LambdaAsyncMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/LambdaAsyncMethodFilter.java index 580ae0ffbabd..c5dbfec9bdf8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/LambdaAsyncMethodFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/LambdaAsyncMethodFilter.java @@ -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; } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java b/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java index 315d6241b752..2a29f51a6ebd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java @@ -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); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/StepIntoMethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/engine/StepIntoMethodBreakpoint.java new file mode 100644 index 000000000000..9adaa9da82f0 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/StepIntoMethodBreakpoint.java @@ -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; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SyntheticMethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/engine/SyntheticMethodBreakpoint.java new file mode 100644 index 000000000000..be21fd12c70f --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SyntheticMethodBreakpoint.java @@ -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 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) { + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index 69a9a236394f..95e0cd6366c1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -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

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); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java index 48b0fad108ff..bf42a4c97254 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java @@ -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; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java index 2c6534f28422..c8cff79efacc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java @@ -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>> 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 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 bpts = debugProcess.getUserData(CAPTURE_BREAKPOINTS); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java index ca804ac51762..24a984acb2ed 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java @@ -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; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/SteppingBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/SteppingBreakpoint.java new file mode 100644 index 000000000000..a085af423365 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/SteppingBreakpoint.java @@ -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); +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/overhead/OverheadProducer.java b/java/debugger/impl/src/com/intellij/debugger/ui/overhead/OverheadProducer.java index b0c031fc64c6..2508a27b93f9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/overhead/OverheadProducer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/overhead/OverheadProducer.java @@ -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; + } }