diff --git a/annotations/com/intellij/ui/classFilter/annotations.xml b/annotations/com/intellij/ui/classFilter/annotations.xml
new file mode 100644
index 00000000000..0fc23f66db4
--- /dev/null
+++ b/annotations/com/intellij/ui/classFilter/annotations.xml
@@ -0,0 +1,8 @@
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/xdebugger/settings/annotations.xml b/annotations/com/intellij/xdebugger/settings/annotations.xml
new file mode 100644
index 00000000000..c18942d0d39
--- /dev/null
+++ b/annotations/com/intellij/xdebugger/settings/annotations.xml
@@ -0,0 +1,9 @@
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/jet/plugin/JetBundle.properties
index 2829928802b..18788da21ac 100644
--- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/JetBundle.properties
+++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/JetBundle.properties
@@ -429,3 +429,6 @@ kotlin.compiler.js.option.output.prefix=Output file &prefix:
kotlin.compiler.js.option.output.postfix=Output file p&ostfix:
kotlin.compiler.js.option.output.prefix.browse.title=Choose output file prefix
kotlin.compiler.js.option.output.postfix.browse.title=Choose output file postfix
+
+# Debugger
+debugger.filter.ignore.internal.classes=Do not step into specific Kotlin classes
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 73e803dda25..9ada4b55fe0 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -334,6 +334,9 @@
+
+
+
diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/KotlinDebuggerSettings.kt b/idea/src/org/jetbrains/jet/plugin/debugger/KotlinDebuggerSettings.kt
new file mode 100644
index 00000000000..4e7f89e27df
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/debugger/KotlinDebuggerSettings.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010-2014 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.jet.plugin.debugger
+
+
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+import com.intellij.openapi.components.StoragePathMacros
+import com.intellij.openapi.options.Configurable
+import com.intellij.openapi.options.SimpleConfigurable
+import com.intellij.openapi.util.Getter
+import com.intellij.util.xmlb.XmlSerializerUtil
+import com.intellij.xdebugger.settings.DebuggerSettingsCategory
+import com.intellij.xdebugger.settings.XDebuggerSettings
+
+import com.intellij.xdebugger.XDebuggerUtil
+import com.intellij.ui.classFilter.ClassFilter
+import com.intellij.debugger.settings.DebuggerSettings
+import java.util.Arrays
+
+State(name = "KotlinDebuggerSettings", storages = array(Storage(file = StoragePathMacros.APP_CONFIG + "/kotlin_debug.xml")))
+public class KotlinDebuggerSettings : XDebuggerSettings("kotlin_debugger"), Getter {
+ public var DEBUG_DISABLE_KOTLIN_INTERNAL_CLASSES: Boolean = true
+
+ class object {
+ public fun getInstance(): KotlinDebuggerSettings {
+ return XDebuggerUtil.getInstance()?.getDebuggerSettings(javaClass())!!
+ }
+ }
+
+ override fun createConfigurables(category: DebuggerSettingsCategory): Collection {
+ return when (category) {
+ DebuggerSettingsCategory.STEPPING ->
+ listOf(SimpleConfigurable.create(
+ "reference.idesettings.debugger.kotlin",
+ "Kotlin",
+ javaClass(),
+ this))
+ else -> listOf()
+ }
+ }
+
+ override fun getState() = this
+ override fun get() = this
+
+ override fun loadState(state: KotlinDebuggerSettings?) {
+ if (state != null) XmlSerializerUtil.copyBean(state, this)
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/KotlinSteppingConfigurableUi.form b/idea/src/org/jetbrains/jet/plugin/debugger/KotlinSteppingConfigurableUi.form
new file mode 100644
index 00000000000..67eedf758a0
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/debugger/KotlinSteppingConfigurableUi.form
@@ -0,0 +1,27 @@
+
+
diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/KotlinSteppingConfigurableUi.java b/idea/src/org/jetbrains/jet/plugin/debugger/KotlinSteppingConfigurableUi.java
new file mode 100644
index 00000000000..5e674cfd6ca
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/debugger/KotlinSteppingConfigurableUi.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2014 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.jet.plugin.debugger;
+
+
+import com.intellij.openapi.options.ConfigurableUi;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+public class KotlinSteppingConfigurableUi implements ConfigurableUi {
+ private JCheckBox ignoreKotlinMethods;
+ private JPanel myPanel;
+
+ @Override
+ public void reset(@NotNull KotlinDebuggerSettings settings) {
+ boolean flag = settings.getDEBUG_DISABLE_KOTLIN_INTERNAL_CLASSES();
+ ignoreKotlinMethods.setSelected(flag);
+ }
+
+ @Override
+ public boolean isModified(@NotNull KotlinDebuggerSettings settings) {
+ return settings.getDEBUG_DISABLE_KOTLIN_INTERNAL_CLASSES() != ignoreKotlinMethods.isSelected();
+ }
+
+ @Override
+ public void apply(@NotNull KotlinDebuggerSettings settings) {
+ settings.setDEBUG_DISABLE_KOTLIN_INTERNAL_CLASSES(ignoreKotlinMethods.isSelected());
+ }
+
+ @NotNull
+ @Override
+ public JComponent getComponent() {
+ return myPanel;
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/filter/KotlinDebuggerInternalClassesFilterProvider.kt b/idea/src/org/jetbrains/jet/plugin/debugger/filter/KotlinDebuggerInternalClassesFilterProvider.kt
new file mode 100644
index 00000000000..0de948da62f
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/debugger/filter/KotlinDebuggerInternalClassesFilterProvider.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010-2014 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.jet.plugin.debugger.filter
+
+import com.intellij.ui.classFilter.DebuggerClassFilterProvider
+import com.intellij.ui.classFilter.ClassFilter
+import org.jetbrains.jet.plugin.debugger.KotlinDebuggerSettings
+
+private val FILTERS = listOf(
+ ClassFilter("kotlin.jvm*"),
+ ClassFilter("kotlin.reflect*"),
+ ClassFilter("kotlin.NoWhenBranchMatchedException"),
+ ClassFilter("kotlin.TypeCastException"),
+ ClassFilter("kotlin.KotlinNullPointerException")
+)
+
+public class KotlinDebuggerInternalClassesFilterProvider : DebuggerClassFilterProvider {
+ override fun getFilters(): List? {
+ return if (KotlinDebuggerSettings.getInstance().DEBUG_DISABLE_KOTLIN_INTERNAL_CLASSES) FILTERS else listOf()
+ }
+}
diff --git a/idea/testData/debugger/tinyApp/outs/allFilesPresentInFilters.out b/idea/testData/debugger/tinyApp/outs/allFilesPresentInFilters.out
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/idea/testData/debugger/tinyApp/outs/checkNotNull.out b/idea/testData/debugger/tinyApp/outs/checkNotNull.out
new file mode 100644
index 00000000000..291fbd5c16e
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/outs/checkNotNull.out
@@ -0,0 +1,10 @@
+LineBreakpoint created at checkNotNull.kt:8
+!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! checkNotNull.CheckNotNullPackage
+Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+checkNotNull.kt:7
+MyJavaClass.java:11
+checkNotNull.kt:7
+checkNotNull.kt:8
+Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+
+Process finished with exit code 0
diff --git a/idea/testData/debugger/tinyApp/outs/javaFun.out b/idea/testData/debugger/tinyApp/outs/javaFun.out
index 2f73ea18759..1b21f69a076 100644
--- a/idea/testData/debugger/tinyApp/outs/javaFun.out
+++ b/idea/testData/debugger/tinyApp/outs/javaFun.out
@@ -2,7 +2,7 @@ LineBreakpoint created at javaFun.kt:8
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! javaFun.JavaFunPackage
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
javaFun.kt:7
-MyJavaClass.java:4
+MyJavaClass.java:6
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
diff --git a/idea/testData/debugger/tinyApp/outs/npe.out b/idea/testData/debugger/tinyApp/outs/npe.out
new file mode 100644
index 00000000000..560f81c2ba2
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/outs/npe.out
@@ -0,0 +1,8 @@
+LineBreakpoint created at npe.kt:7
+!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! npe.NpePackage
+Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+npe.kt:6
+npe.kt:9
+Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+
+Process finished with exit code 0
diff --git a/idea/testData/debugger/tinyApp/outs/reflectKClass.out b/idea/testData/debugger/tinyApp/outs/reflectKClass.out
new file mode 100644
index 00000000000..65930a9e8bc
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/outs/reflectKClass.out
@@ -0,0 +1,8 @@
+LineBreakpoint created at reflectKClass.kt:5
+!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! reflectKClass.ReflectKClassPackage
+Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+reflectKClass.kt:4
+reflectKClass.kt:5
+Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+
+Process finished with exit code 0
diff --git a/idea/testData/debugger/tinyApp/src/filters/checkNotNull.kt b/idea/testData/debugger/tinyApp/src/filters/checkNotNull.kt
new file mode 100644
index 00000000000..bf5f5f7580e
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/src/filters/checkNotNull.kt
@@ -0,0 +1,12 @@
+package checkNotNull
+
+import stepInto.MyJavaClass
+
+fun main(args: Array) {
+ val myClass = MyJavaClass()
+ //Breakpoint!
+ val a: String = myClass.testNotNullFun()
+ val b = 1
+}
+
+// REPEAT: 3
diff --git a/idea/testData/debugger/tinyApp/src/filters/npe.kt b/idea/testData/debugger/tinyApp/src/filters/npe.kt
new file mode 100644
index 00000000000..88939f2771c
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/src/filters/npe.kt
@@ -0,0 +1,12 @@
+package npe
+
+fun main(args: Array) {
+ val a = null
+ try {
+ //Breakpoint!
+ a!!
+ }
+ catch (e: Exception) {
+ val b = 1
+ }
+}
diff --git a/idea/testData/debugger/tinyApp/src/filters/reflectKClass.kt b/idea/testData/debugger/tinyApp/src/filters/reflectKClass.kt
new file mode 100644
index 00000000000..88678fbde9e
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/src/filters/reflectKClass.kt
@@ -0,0 +1,9 @@
+package reflectKClass
+
+fun main(args: Array) {
+ //Breakpoint!
+ val a = A()
+ val b = 1
+}
+
+class A
diff --git a/idea/testData/debugger/tinyApp/src/stepInto/MyJavaClass.java b/idea/testData/debugger/tinyApp/src/stepInto/MyJavaClass.java
index df0ea610358..de970cae48f 100644
--- a/idea/testData/debugger/tinyApp/src/stepInto/MyJavaClass.java
+++ b/idea/testData/debugger/tinyApp/src/stepInto/MyJavaClass.java
@@ -1,7 +1,14 @@
package stepInto;
+import org.jetbrains.annotations.NotNull;
+
public class MyJavaClass {
public void testFun() {
int i = 1;
}
+
+ @NotNull
+ public String testNotNullFun() {
+ return "a";
+ }
}
diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/AbstractKotlinSteppingTest.kt b/idea/tests/org/jetbrains/jet/plugin/debugger/AbstractKotlinSteppingTest.kt
index e35194bd1b7..0b30488c8ff 100644
--- a/idea/tests/org/jetbrains/jet/plugin/debugger/AbstractKotlinSteppingTest.kt
+++ b/idea/tests/org/jetbrains/jet/plugin/debugger/AbstractKotlinSteppingTest.kt
@@ -51,7 +51,12 @@ public abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestCase() {
configureSettings(fileText)
createDebugProcess(path)
- onBreakpoint { stepInto() }
+ val count = findStringWithPrefixes(fileText, "// REPEAT: ")?.toInt() ?: 1
+
+ for (i in 1..count) {
+ onBreakpoint { stepInto() }
+ }
+
finish()
}
diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java
index 830e1b8aa65..f497675b75d 100644
--- a/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java
+++ b/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinSteppingTestGenerated.java
@@ -181,6 +181,21 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/filters"), Pattern.compile("^(.+)\\.kt$"), true);
}
+ @TestMetadata("checkNotNull.kt")
+ public void testCheckNotNull() throws Exception {
+ doStepIntoTest("idea/testData/debugger/tinyApp/src/filters/checkNotNull.kt");
+ }
+
+ @TestMetadata("npe.kt")
+ public void testNpe() throws Exception {
+ doStepIntoTest("idea/testData/debugger/tinyApp/src/filters/npe.kt");
+ }
+
+ @TestMetadata("reflectKClass.kt")
+ public void testReflectKClass() throws Exception {
+ doStepIntoTest("idea/testData/debugger/tinyApp/src/filters/reflectKClass.kt");
+ }
+
@TestMetadata("skipClassloader.kt")
public void testSkipClassloader() throws Exception {
doStepIntoTest("idea/testData/debugger/tinyApp/src/filters/skipClassloader.kt");