diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 12a8a36a030..a20598ccd35 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -386,6 +386,7 @@
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt b/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt
new file mode 100644
index 00000000000..ad52b721093
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2010-2015 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
+
+import com.intellij.debugger.engine
+import com.intellij.debugger.engine.SuspendContext
+import org.jetbrains.kotlin.idea.debugger.JetPositionManager
+import com.sun.jdi.Location
+import org.jetbrains.kotlin.idea.util.application.runReadAction
+import com.intellij.debugger.NoDataException
+import com.sun.jdi.request.StepRequest
+import java.util.regex.Pattern
+import java.util.WeakHashMap
+import com.intellij.openapi.extensions.Extensions
+import com.intellij.ui.classFilter.DebuggerClassFilterProvider
+import com.intellij.debugger.settings.DebuggerSettings
+
+public class ExtraSteppingFilter : engine.ExtraSteppingFilter {
+
+ override fun isApplicable(context: SuspendContext?): Boolean {
+ if (context == null) {
+ return false;
+ }
+
+ val debugProcess = context.getDebugProcess()
+ val positionManager = JetPositionManager(debugProcess)
+ val location = context.getFrameProxy().location()
+ return runReadAction {
+ shouldFilter(positionManager, location)
+ }
+ }
+
+
+ private fun shouldFilter(positionManager: JetPositionManager, location: Location): Boolean {
+ val defaultStrata = location.declaringType().defaultStratum()
+ if ("Kotlin" != defaultStrata) {
+ return false;
+ }
+
+ val sourcePosition =
+ try {
+ positionManager.getSourcePosition(location)
+ }
+ catch(e: NoDataException) {
+ return false
+ }
+
+ if (sourcePosition == null) return false
+
+ val className = positionManager.classNameForPosition(sourcePosition)?.replace('/', '.') ?: return false
+
+ val settings = DebuggerSettings.getInstance()
+ if (settings.TRACING_FILTERS_ENABLED) {
+ for (filter in settings.getSteppingFilters()) {
+ if (filter.isEnabled()) {
+ if (filter.matches(className)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ override fun getStepRequestDepth(context: SuspendContext?): Int {
+ return StepRequest.STEP_INTO
+ }
+}
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt
index f1f183fe96e..86478452b3f 100644
--- a/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt
@@ -119,7 +119,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
continue
}
- val internalClassName = getClassNameForElement(literal.getFirstChild(), typeMapper, file, isInLibrary).className
+ val internalClassName = getInternalClassNameForElement(literal.getFirstChild(), typeMapper, file, isInLibrary).className
if (internalClassName == currentLocationClassName) {
return functionLiteral
}
@@ -191,7 +191,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
return result;
}
- private fun classNameForPosition(sourcePosition: SourcePosition): String? {
+ public fun classNameForPosition(sourcePosition: SourcePosition): String? {
val psiElement = sourcePosition.getElementAt()
if (psiElement == null) {
return null
@@ -204,7 +204,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
val file = element.getContainingFile() as JetFile
val isInLibrary = LibraryUtil.findLibraryEntry(file.getVirtualFile(), file.getProject()) != null
val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(element, file)
- getClassNameForElement(element, typeMapper, file, isInLibrary).className
+ getInternalClassNameForElement(element, typeMapper, file, isInLibrary).className
}
}
@@ -293,13 +293,13 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
return state.getTypeMapper()
}
- public fun getClassNameForElement(notPositionedElement: PsiElement?, typeMapper: JetTypeMapper, file: JetFile, isInLibrary: Boolean): PositionedElement {
+ public fun getInternalClassNameForElement(notPositionedElement: PsiElement?, typeMapper: JetTypeMapper, file: JetFile, isInLibrary: Boolean): PositionedElement {
val element = getElementToCalculateClassName(notPositionedElement)
when {
element is JetClassOrObject -> return PositionedElement(getJvmInternalNameForImpl(typeMapper, element), element)
element is JetFunctionLiteral -> {
if (isInlinedLambda(element, typeMapper.getBindingContext())) {
- return getClassNameForElement(element.getParent(), typeMapper, file, isInLibrary)
+ return getInternalClassNameForElement(element.getParent(), typeMapper, file, isInLibrary)
}
else {
val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.getBindingContext(), element)
@@ -310,9 +310,9 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
val parent = getElementToCalculateClassName(element.getParent())
// Class-object initializer
if (parent is JetObjectDeclaration && parent.isDefault()) {
- return PositionedElement(getClassNameForElement(parent.getParent(), typeMapper, file, isInLibrary).className, parent)
+ return PositionedElement(getInternalClassNameForElement(parent.getParent(), typeMapper, file, isInLibrary).className, parent)
}
- return getClassNameForElement(element, typeMapper, file, isInLibrary)
+ return getInternalClassNameForElement(element, typeMapper, file, isInLibrary)
}
element is JetProperty && (!element.isTopLevel() || !isInLibrary) -> {
if (isInPropertyAccessor(notPositionedElement)) {
@@ -324,7 +324,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
if (descriptor !is PropertyDescriptor) {
- return getClassNameForElement(element.getParent(), typeMapper, file, isInLibrary)
+ return getInternalClassNameForElement(element.getParent(), typeMapper, file, isInLibrary)
}
return PositionedElement(getJvmInternalNameForPropertyOwner(typeMapper, descriptor), element)
@@ -441,7 +441,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
if (element != null && jetFile is JetFile) {
val isInLibrary = LibraryUtil.findLibraryEntry(jetFile.getVirtualFile(), jetFile.getProject()) != null
val typeMapper = if (!isInLibrary) prepareTypeMapper(jetFile) else createTypeMapperForLibraryFile(element, jetFile)
- val psiElement = getClassNameForElement(element, typeMapper, jetFile, isInLibrary).element;
+ val psiElement = getInternalClassNameForElement(element, typeMapper, jetFile, isInLibrary).element;
if (psiElement is JetNamedFunction) {
val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement)