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 92fbca934720..4e23d5a93f97 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -23,6 +23,7 @@ import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.engine.requests.LocatableEventRequestor; import com.intellij.debugger.engine.requests.MethodReturnValueWatcher; import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.requests.Requestor; @@ -38,6 +39,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; +import com.intellij.ui.classFilter.ClassFilter; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.impl.XDebugSessionImpl; @@ -51,6 +53,8 @@ import com.sun.jdi.request.EventRequestManager; import com.sun.jdi.request.ThreadDeathRequest; import com.sun.jdi.request.ThreadStartRequest; +import java.util.List; + /** * @author lex */ @@ -407,6 +411,13 @@ public class DebugProcessEvents extends DebugProcessImpl { final String message = "Method " + ((NamedMethodFilter)methodFilter).getMethodName() + "() has not been called"; XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(message, MessageType.INFO).notify(project); } + if (hint.wasStepTargetMethodMatched() && hint.isResetIgnoreFilters()) { + List activeFilters = getActiveFilters(); + String currentClassName = getCurrentClassName(suspendContext.getThread()); + if (currentClassName == null || !DebuggerUtilsEx.isFiltered(currentClassName, activeFilters)) { + mySession.resetIgnoreStepFiltersFlag(); + } + } } } } 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 557d630ef8e9..85514282eeeb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -390,22 +390,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager(); StepRequest stepRequest = requestManager.createStepRequest(stepThreadReference, size, depth); if (!(hint != null && hint.isIgnoreFilters()) /*&& depth == StepRequest.STEP_INTO*/) { - final List activeFilters = new ArrayList(); - DebuggerSettings settings = DebuggerSettings.getInstance(); - if (settings.TRACING_FILTERS_ENABLED) { - for (ClassFilter filter : settings.getSteppingFilters()) { - if (filter.isEnabled()) { - activeFilters.add(filter); - } - } - } - for (DebuggerClassFilterProvider provider : Extensions.getExtensions(DebuggerClassFilterProvider.EP_NAME)) { - for (ClassFilter filter : provider.getFilters()) { - if (filter.isEnabled()) { - activeFilters.add(filter); - } - } - } + List activeFilters = getActiveFilters(); if (!activeFilters.isEmpty()) { final String currentClassName = getCurrentClassName(stepThread); @@ -434,6 +419,27 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } } + @NotNull + static List getActiveFilters() { + List activeFilters = new ArrayList(); + DebuggerSettings settings = DebuggerSettings.getInstance(); + if (settings.TRACING_FILTERS_ENABLED) { + for (ClassFilter filter : settings.getSteppingFilters()) { + if (filter.isEnabled()) { + activeFilters.add(filter); + } + } + } + for (DebuggerClassFilterProvider provider : Extensions.getExtensions(DebuggerClassFilterProvider.EP_NAME)) { + for (ClassFilter filter : provider.getFilters()) { + if (filter.isEnabled()) { + activeFilters.add(filter); + } + } + } + return activeFilters; + } + void deleteStepRequests(@Nullable final ThreadReference stepThread) { EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager(); List stepRequests = requestManager.stepRequests(); @@ -456,7 +462,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } @Nullable - private static String getCurrentClassName(ThreadReferenceProxyImpl thread) { + static String getCurrentClassName(ThreadReferenceProxyImpl thread) { try { if (thread != null && thread.frameCount() > 0) { StackFrameProxyImpl stackFrame = thread.frame(0); @@ -1507,6 +1513,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb final RequestHint hint = mySmartStepFilter != null? new RequestHint(stepThread, suspendContext, mySmartStepFilter) : new RequestHint(stepThread, suspendContext, StepRequest.STEP_INTO); + hint.setResetIgnoreFilters(mySmartStepFilter != null && !mySession.shouldIgnoreSteppingFilters()); if (myForcedIgnoreFilters) { try { mySession.setIgnoreStepFiltersFlag(stepThread.frameCount()); 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 735f941aaa6b..af98a79a9862 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java @@ -55,6 +55,7 @@ public class RequestHint { private boolean myTargetMethodMatched = false; private boolean myIgnoreFilters = false; + private boolean myResetIgnoreFilters = false; private boolean myRestoreBreakpoints = false; public RequestHint(final ThreadReferenceProxyImpl stepThread, final SuspendContextImpl suspendContext, @NotNull MethodFilter methodFilter) { @@ -111,6 +112,14 @@ public class RequestHint { myIgnoreFilters = ignoreFilters; } + public void setResetIgnoreFilters(boolean resetIgnoreFilters) { + myResetIgnoreFilters = resetIgnoreFilters; + } + + public boolean isResetIgnoreFilters() { + return myResetIgnoreFilters; + } + public void setRestoreBreakpoints(boolean restoreBreakpoints) { myRestoreBreakpoints = restoreBreakpoints; } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java index cf471b99592d..6346d831943f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -41,7 +41,6 @@ import com.intellij.idea.ActionsBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; @@ -322,12 +321,17 @@ public class DebuggerSession implements AbstractDebuggerSession { } } - private void resetIgnoreStepFiltersFlag() { + public void resetIgnoreStepFiltersFlag() { myIgnoreFiltersFrameCountThreshold = 0; } public void setIgnoreStepFiltersFlag(int currentStackFrameCount) { - myIgnoreFiltersFrameCountThreshold = currentStackFrameCount; + if (myIgnoreFiltersFrameCountThreshold <= 0) { + myIgnoreFiltersFrameCountThreshold = currentStackFrameCount; + } + else { + myIgnoreFiltersFrameCountThreshold = Math.min(myIgnoreFiltersFrameCountThreshold, currentStackFrameCount); + } } public boolean shouldIgnoreSteppingFilters() { diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java index b776bcad7349..d190ca1d672f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -235,12 +235,12 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils { return false; } - public static boolean isFiltered(String qName, ClassFilter[] classFilters) { + public static boolean isFiltered(@NotNull String qName, ClassFilter[] classFilters) { return isFiltered(qName, Arrays.asList(classFilters)); } - public static boolean isFiltered(String qName, List classFilters) { - if(qName.indexOf('[') != -1) { + public static boolean isFiltered(@NotNull String qName, List classFilters) { + if (qName.indexOf('[') != -1) { return false; //is array } diff --git a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java index 653a11879d00..5c4ba6b9baed 100644 --- a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java @@ -90,6 +90,11 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa debugProcess.getManagerThread().schedule(debugProcess.createResumeCommand(context, PrioritizedTask.Priority.LOW)); } + protected void stepInto(SuspendContextImpl context) { + DebugProcessImpl debugProcess = context.getDebugProcess(); + debugProcess.getManagerThread().schedule(debugProcess.createStepIntoCommand(context, false, null)); + } + protected void waitBreakpoints() { myScriptRunnablesSema.down(); waitFor(new Runnable() {