diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties
index c8eb4361f4e..2e5b286f705 100644
--- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties
+++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties
@@ -338,3 +338,4 @@ kotlin.compiler.js.option.output.copy.dir=O&utput directory for library &runtime
# Debugger
debugger.filter.ignore.internal.classes=Do not step into specific Kotlin classes
debugger.data.view.delegated.properties=Calculate values of delegated properties (may affect program execution)
+debugger.field.watchpoints.tab.title=Kotlin Field Watchpoints
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index e93e6e49357..18d34b72cbd 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -406,7 +406,9 @@
+
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/breakpoints/KotlinBreakpointHandlerFactory.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/breakpoints/KotlinBreakpointHandlerFactory.kt
new file mode 100644
index 00000000000..7645f437e85
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/debugger/breakpoints/KotlinBreakpointHandlerFactory.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.debugger.breakpoints
+
+import com.intellij.debugger.engine.DebugProcessImpl
+import com.intellij.debugger.engine.JavaBreakpointHandler
+import com.intellij.debugger.engine.JavaBreakpointHandlerFactory
+import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType
+
+public class KotlinBreakpointHandlerFactory: JavaBreakpointHandlerFactory {
+ override fun createHandler(process: DebugProcessImpl): JavaBreakpointHandler? {
+ return KotlinFieldBreakpointHandler(process)
+ }
+}
+
+public class KotlinFieldBreakpointHandler(process: DebugProcessImpl) : JavaBreakpointHandler(javaClass(), process)
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/breakpoints/KotlinFieldBreakpointType.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/breakpoints/KotlinFieldBreakpointType.kt
new file mode 100644
index 00000000000..1d838acf268
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/debugger/breakpoints/KotlinFieldBreakpointType.kt
@@ -0,0 +1,224 @@
+/*
+ * 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.debugger.breakpoints
+
+import com.intellij.debugger.SourcePosition
+import com.intellij.debugger.impl.PositionUtil
+import com.intellij.debugger.ui.breakpoints.*
+import com.intellij.openapi.fileEditor.FileDocumentManager
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.*
+import com.intellij.psi.util.PsiTreeUtil
+import com.intellij.xdebugger.XDebuggerUtil
+import com.intellij.xdebugger.breakpoints.XBreakpoint
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint
+import com.intellij.xdebugger.breakpoints.XLineBreakpointType
+import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
+import org.jetbrains.annotations.TestOnly
+import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties
+import org.jetbrains.kotlin.descriptors.PropertyDescriptor
+import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
+import org.jetbrains.kotlin.idea.JetBundle
+import org.jetbrains.kotlin.idea.JetFileType
+import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
+import org.jetbrains.kotlin.idea.util.application.runReadAction
+import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.resolve.BindingContext
+import javax.swing.Icon
+import javax.swing.JComponent
+
+public class KotlinFieldBreakpointType : JavaBreakpointType, XLineBreakpointType(
+ "kotlin-field", JetBundle.message("debugger.field.watchpoints.tab.title")
+) {
+ private val delegate = JavaFieldBreakpointType()
+
+ override fun createJavaBreakpoint(project: Project, breakpoint: XBreakpoint): Breakpoint<*> {
+ return KotlinFieldBreakpoint(project, breakpoint)
+ }
+
+ override fun canPutAt(file: VirtualFile, line: Int, project: Project): Boolean {
+ val psiFile = PsiManager.getInstance(project).findFile(file)
+
+ if (psiFile == null || psiFile.getVirtualFile().getFileType() != JetFileType.INSTANCE) {
+ return false
+ }
+
+ val document = FileDocumentManager.getInstance().getDocument(file) ?: return false
+
+ var canPutAt = false
+ XDebuggerUtil.getInstance().iterateLine(project, document, line, fun (el: PsiElement): Boolean {
+ // avoid comments
+ if (el is PsiWhiteSpace || PsiTreeUtil.getParentOfType(el, javaClass(), false) != null) {
+ return true
+ }
+
+ var element = el
+ var parent = element.getParent()
+ while (parent != null) {
+ val offset = parent.getTextOffset()
+ if (offset >= 0 && document.getLineNumber(offset) != line) break
+
+ element = parent
+ parent = element.getParent()
+ }
+
+ if (element is JetProperty || element is JetParameter) {
+ val bindingContext = (element as JetElement).analyzeAndGetResult().bindingContext
+ var descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
+ if (descriptor is ValueParameterDescriptor) {
+ descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor)
+ }
+ if (descriptor is PropertyDescriptor && bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor)) {
+ canPutAt = true
+ }
+ return false
+ }
+
+ return true
+ })
+
+ return canPutAt
+ }
+
+ override fun getPriority() = 120
+
+ override fun createBreakpointProperties(file: VirtualFile, line: Int): JavaFieldBreakpointProperties? {
+ return delegate.createBreakpointProperties(file, line)
+ }
+
+ override fun addBreakpoint(project: Project?, parentComponent: JComponent?): XLineBreakpoint? {
+ return delegate.addBreakpoint(project, parentComponent)
+ }
+
+ override fun isAddBreakpointButtonVisible(): Boolean {
+ return delegate.isAddBreakpointButtonVisible()
+ }
+
+ override fun getMutedEnabledIcon(): Icon {
+ return delegate.getMutedEnabledIcon()
+ }
+
+ override fun getDisabledIcon(): Icon {
+ return delegate.getDisabledIcon()
+ }
+
+ override fun getEnabledIcon(): Icon {
+ return delegate.getEnabledIcon()
+ }
+
+ override fun getMutedDisabledIcon(): Icon {
+ return delegate.getMutedDisabledIcon()
+ }
+
+ override fun canBeHitInOtherPlaces(): Boolean {
+ return delegate.canBeHitInOtherPlaces()
+ }
+
+ override fun getShortText(breakpoint: XLineBreakpoint?): String? {
+ return delegate.getShortText(breakpoint)
+ }
+
+ override fun createProperties(): JavaFieldBreakpointProperties? {
+ return delegate.createProperties()
+ }
+
+ override fun createCustomPropertiesPanel(): XBreakpointCustomPropertiesPanel>? {
+ return delegate.createCustomPropertiesPanel()
+ }
+
+ override fun getDisplayText(breakpoint: XLineBreakpoint?): String? {
+ return delegate.getDisplayText(breakpoint)
+ }
+
+ override fun getEditorsProvider(): XDebuggerEditorsProvider? {
+ return delegate.getEditorsProvider()
+ }
+
+ override fun createCustomRightPropertiesPanel(project: Project): XBreakpointCustomPropertiesPanel>? {
+ return delegate.createCustomRightPropertiesPanel(project)
+ }
+
+ override fun isSuspendThreadSupported(): Boolean {
+ return delegate.isSuspendThreadSupported()
+ }
+}
+
+class KotlinFieldBreakpoint(project: Project, breakpoint: XBreakpoint): FieldBreakpoint(project, breakpoint) {
+ override fun isValid(): Boolean {
+ if (!BreakpointWithHighlighter.isPositionValid(getXBreakpoint().getSourcePosition())) return false
+
+ return runReadAction {
+ val field = getField()
+ field != null && field.isValid()
+ }
+ }
+
+ public fun getField(): JetCallableDeclaration? {
+ val sourcePosition = getSourcePosition()
+ return getProperty(sourcePosition)
+ }
+
+ private fun getProperty(sourcePosition: SourcePosition?): JetCallableDeclaration? {
+ val property: JetProperty? = PositionUtil.getPsiElementAt(getProject(), javaClass(), sourcePosition)
+ if (property != null) {
+ return property
+ }
+ val parameter: JetParameter? = PositionUtil.getPsiElementAt(getProject(), javaClass(), sourcePosition)
+ if (parameter != null) {
+ return parameter
+ }
+ return null
+ }
+
+ override fun reload(psiFile: PsiFile?) {
+ val property = getProperty(getSourcePosition())
+ if (property != null) {
+ setFieldName(property.getName())
+
+ if (property is JetProperty && property.isTopLevel()) {
+ getProperties().myClassName = PackageClassUtils.getPackageClassFqName(property.getContainingJetFile().getPackageFqName()).asString()
+ }
+ else {
+ val jetClass: JetClassOrObject? = PsiTreeUtil.getParentOfType(property, javaClass())
+ if (jetClass is JetClassOrObject) {
+ val fqName = jetClass.getFqName()
+ if (fqName != null) {
+ getProperties().myClassName = fqName.asString()
+ }
+ }
+ }
+ setInstanceFiltersEnabled(false)
+ }
+ }
+
+ fun setFieldName(fieldName: String) {
+ getProperties().myFieldName = fieldName
+ }
+
+ @TestOnly
+ fun setWatchAccess(value: Boolean) {
+ getProperties().WATCH_ACCESS = value
+ }
+
+ @TestOnly
+ fun setWatchModification(value: Boolean) {
+ getProperties().WATCH_MODIFICATION = value
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/debugger/tinyApp/outs/fieldWatchpoints.out b/idea/testData/debugger/tinyApp/outs/fieldWatchpoints.out
new file mode 100644
index 00000000000..aa1bde9a489
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/outs/fieldWatchpoints.out
@@ -0,0 +1,44 @@
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:4
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:7
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:17
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:20
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:30
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:32
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:44
+KotlinFieldBreakpoint created at fieldWatchpoints.kt:47
+!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! fieldWatchpoints.FieldWatchpointsPackage
+Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+fieldWatchpoints.kt:18
+fieldWatchpoints.kt:21
+fieldWatchpoints.kt:59
+fieldWatchpoints.kt:5
+fieldWatchpoints.kt:8
+fieldWatchpoints.kt:59
+fieldWatchpoints.kt:11
+fieldWatchpoints.kt:12
+fieldWatchpoints.kt:13
+fieldWatchpoints.kt:60
+fieldWatchpoints.kt:24
+fieldWatchpoints.kt:25
+fieldWatchpoints.kt:26
+fieldWatchpoints.kt:61
+fieldWatchpoints.kt:0
+fieldWatchpoints.kt:0
+fieldWatchpoints.kt:61
+fieldWatchpoints.kt:36
+fieldWatchpoints.kt:37
+fieldWatchpoints.kt:38
+fieldWatchpoints.kt:62
+fieldWatchpoints.kt:45
+fieldWatchpoints.kt:48
+fieldWatchpoints.kt:62
+fieldWatchpoints.kt:44
+fieldWatchpoints.kt:51
+fieldWatchpoints.kt:47
+fieldWatchpoints.kt:52
+fieldWatchpoints.kt:47
+fieldWatchpoints.kt:54
+fieldWatchpoints.kt:63
+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/inapplicableFieldWatchpoints.out b/idea/testData/debugger/tinyApp/outs/inapplicableFieldWatchpoints.out
new file mode 100644
index 00000000000..9963536d281
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/outs/inapplicableFieldWatchpoints.out
@@ -0,0 +1,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! inapplicableFieldWatchpoints.InapplicableFieldWatchpointsPackage
+Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
+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/stepOut/fieldWatchpoints.kt b/idea/testData/debugger/tinyApp/src/stepOut/fieldWatchpoints.kt
new file mode 100644
index 00000000000..c1b709a5eff
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/src/stepOut/fieldWatchpoints.kt
@@ -0,0 +1,65 @@
+package fieldWatchpoints
+
+class A {
+ //FieldWatchpoint! (propVal)
+ val propVal = 1
+
+ //FieldWatchpoint! (propVar)
+ var propVar = 1
+
+ fun testPublicPropertyInClass() {
+ propVal
+ propVar
+ propVar = 2
+ }
+}
+
+//FieldWatchpoint! (topPropVal)
+val topPropVal = 1
+
+//FieldWatchpoint! (topPropVar)
+var topPropVar = 1
+
+fun testPublicTopLevelProperty() {
+ topPropVal
+ topPropVar
+ topPropVar = 2
+}
+
+class B(
+ //FieldWatchpoint! (bPropVal)
+ val bPropVal: Int,
+ //FieldWatchpoint! (bPropVar)
+ var bPropVar: Int
+) {
+ fun testConstructorProperty() {
+ bPropVal
+ bPropVar
+ bPropVar = 2
+ }
+}
+
+class AWithCompanion {
+ companion object {
+ //FieldWatchpoint! (compPropVal)
+ val compPropVal = 1
+
+ //FieldWatchpoint! (compPropVar)
+ var compPropVar = 1
+
+ fun testCompanionProperty() {
+ compPropVal
+ compPropVar
+ compPropVar = 2
+ }
+ }
+}
+
+fun main(args: Array) {
+ A().testPublicPropertyInClass()
+ testPublicTopLevelProperty()
+ B(1, 1).testConstructorProperty()
+ AWithCompanion.testCompanionProperty()
+}
+
+// STEP_OUT: 36
\ No newline at end of file
diff --git a/idea/testData/debugger/tinyApp/src/stepOut/inapplicableFieldWatchpoints.kt b/idea/testData/debugger/tinyApp/src/stepOut/inapplicableFieldWatchpoints.kt
new file mode 100644
index 00000000000..8111ecab697
--- /dev/null
+++ b/idea/testData/debugger/tinyApp/src/stepOut/inapplicableFieldWatchpoints.kt
@@ -0,0 +1,23 @@
+package inapplicableFieldWatchpoints
+
+class A {
+ //FieldWatchpoint! (propWithGet)
+ val propWithGet: Int get() = 1
+}
+
+interface T {
+ //FieldWatchpoint! (propInInterface)
+ val propInInterface: Int
+}
+
+fun main(args: Array) {
+ //FieldWatchpoint! (localVal)
+ val localVal = 1
+}
+
+fun foo(
+ //FieldWatchpoint! (funParam)
+ funParam: Int
+) {
+
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestBase.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestBase.kt
index 7ec63154a91..78ca3967e87 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestBase.kt
+++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestBase.kt
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.idea.debugger
+import com.intellij.debugger.DebuggerInvocationUtil
+import com.intellij.debugger.DebuggerManagerEx
import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.SuspendContextImpl
import com.intellij.debugger.engine.MethodFilter
@@ -33,6 +35,28 @@ import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
import kotlin.properties.Delegates
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.impl.DebuggerContextImpl
+import com.intellij.debugger.ui.breakpoints.BreakpointManager
+import com.intellij.debugger.ui.breakpoints.FieldBreakpoint
+import com.intellij.debugger.ui.breakpoints.JavaFieldBreakpointType
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.application.ModalityState
+import com.intellij.openapi.editor.Document
+import com.intellij.openapi.fileEditor.FileDocumentManager
+import com.intellij.openapi.util.Computable
+import com.intellij.psi.PsiDocumentManager
+import com.intellij.psi.PsiFile
+import com.intellij.psi.PsiManager
+import com.intellij.psi.search.FilenameIndex
+import com.intellij.xdebugger.XDebuggerManager
+import com.intellij.xdebugger.XDebuggerUtil
+import com.intellij.xdebugger.breakpoints.*
+import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties
+import org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpoint
+import org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointType
+import org.jetbrains.kotlin.idea.util.application.runWriteAction
+import org.jetbrains.kotlin.psi.JetFile
+import org.jetbrains.kotlin.test.InTextDirectivesUtils
+import javax.swing.SwingUtilities
abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
private var oldSettings: DebuggerSettings by Delegates.notNull()
@@ -154,4 +178,58 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
resume(this)
}
}
+
+ override fun createBreakpoints(file: PsiFile?) {
+ super.createBreakpoints(file)
+
+ if (file == null) return
+
+ val document = PsiDocumentManager.getInstance(myProject).getDocument(file) ?: return
+ val breakpointManager = XDebuggerManager.getInstance(myProject).getBreakpointManager()
+ val breakpointType = javaClass() as Class>, XBreakpointProperties<*>>>
+ val type = XDebuggerUtil.getInstance().findBreakpointType>>(breakpointType) as KotlinFieldBreakpointType
+ val virtualFile = file.getVirtualFile()
+
+ val runnable = {
+ var offset = -1;
+ while (true) {
+ offset = document.getText().indexOf("FieldWatchpoint!", offset + 1)
+ if (offset == -1) break
+
+ val commentLine = document.getLineNumber(offset)
+
+ val comment = document.getText().substring(document.getLineStartOffset(commentLine), document.getLineEndOffset(commentLine))
+
+ val lineIndex = commentLine + 1
+ val fieldName = comment.substringAfter("//FieldWatchpoint! (").substringBefore(")")
+
+ if (!type.canPutAt(virtualFile, lineIndex, myProject)) continue
+
+ val xBreakpoint = runWriteAction {
+ breakpointManager.addLineBreakpoint(
+ type as XLineBreakpointType>,
+ virtualFile.getUrl(),
+ lineIndex,
+ type.createBreakpointProperties(virtualFile, lineIndex)
+ )
+ }
+
+ val javaBreakpoint = BreakpointManager.getJavaBreakpoint(xBreakpoint)
+ if (javaBreakpoint is KotlinFieldBreakpoint) {
+ javaBreakpoint.setFieldName(fieldName)
+ javaBreakpoint.setWatchAccess(true)
+ javaBreakpoint.setWatchModification(true)
+ BreakpointManager.addBreakpoint(javaBreakpoint)
+ println("KotlinFieldBreakpoint created at ${file.getVirtualFile().getName()}:$lineIndex", ProcessOutputTypes.SYSTEM)
+ }
+ }
+ }
+
+ if (!SwingUtilities.isEventDispatchThread()) {
+ DebuggerInvocationUtil.invokeAndWait(myProject, runnable, ModalityState.defaultModalityState())
+ }
+ else {
+ runnable.invoke()
+ }
+ }
}
diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java
index 74ec07614cd..135a45385df 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java
@@ -272,6 +272,27 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
}
}
+ @TestMetadata("idea/testData/debugger/tinyApp/src/stepOut")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class StepOut extends AbstractKotlinSteppingTest {
+ public void testAllFilesPresentInStepOut() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepOut"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("fieldWatchpoints.kt")
+ public void testFieldWatchpoints() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepOut/fieldWatchpoints.kt");
+ doStepOutTest(fileName);
+ }
+
+ @TestMetadata("inapplicableFieldWatchpoints.kt")
+ public void testInapplicableFieldWatchpoints() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepOut/inapplicableFieldWatchpoints.kt");
+ doStepOutTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/debugger/tinyApp/src/filters")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)