diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt new file mode 100644 index 00000000000..6ee092de721 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2016 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. + */ + +package org.jetbrains.kotlin.idea.debugger.stepping + +import com.intellij.debugger.engine.DebugProcessImpl +import com.intellij.debugger.engine.SuspendContextImpl +import com.intellij.util.Range +import com.sun.jdi.LocalVariable +import com.sun.jdi.Location + +class KotlinStepOverInlineFilter(val stepOverLines: Set, val fromLine: Int, + val inlineFunRangeVariables: List) : KotlinMethodFilter { + override fun locationMatches(context: SuspendContextImpl, location: Location): Boolean { + val frameProxy = context.frameProxy + if (frameProxy == null) return true + + val currentLine = location.lineNumber() + + if (!(stepOverLines.contains(location.lineNumber()))) { + return currentLine != fromLine + } + + val visibleInlineVariables = getInlineRangeLocalVariables(frameProxy) + + // Our ranges check missed exit from inline function. This is when breakpoint was in last statement of inline functions. + // This can be observed by inline local range-variables. Absence of any means step out was done. + return inlineFunRangeVariables.any { !visibleInlineVariables.contains(it) } + } + + override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean { + throw IllegalStateException() // Should not be called from Kotlin hint + } + + override fun getCallingExpressionLines(): Range? { + throw IllegalStateException() // Should not be called from Kotlin hint + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt index 1fd68882cbf..6348630bdb6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt @@ -296,34 +296,6 @@ interface KotlinMethodFilter: MethodFilter { fun locationMatches(context: SuspendContextImpl, location: Location): Boolean } -class KotlinStepOverInlineFilter(val stepOverLines: Set, val fromLine: Int, - val inlineFunRangeVariables: List) : KotlinMethodFilter { - override fun locationMatches(context: SuspendContextImpl, location: Location): Boolean { - val frameProxy = context.frameProxy - if (frameProxy == null) return true - - val currentLine = location.lineNumber() - - if (!(stepOverLines.contains(location.lineNumber()))) { - return currentLine != fromLine - } - - val visibleInlineVariables = getInlineRangeLocalVariables(frameProxy) - - // Our ranges check missed exit from inline function. This is when breakpoint was in last statement of inline functions. - // This can be observed by inline local range-variables. Absence of any means step out was done. - return inlineFunRangeVariables.any { !visibleInlineVariables.contains(it) } - } - - override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean { - throw IllegalStateException() // Should not be called from Kotlin hint - } - - override fun getCallingExpressionLines(): Range? { - throw IllegalStateException() // Should not be called from Kotlin hint - } -} - fun getStepOverAction( location: Location, kotlinSourcePosition: KotlinSteppingCommandProvider.KotlinSourcePosition, @@ -496,7 +468,7 @@ private fun SuspendContextImpl.getNextPositionWithFilter( return null } -private fun getInlineRangeLocalVariables(stackFrame: StackFrameProxyImpl): List { +fun getInlineRangeLocalVariables(stackFrame: StackFrameProxyImpl): List { return stackFrame.visibleVariables() .filter { val name = it.name()