Support filed breakpoints on properties without backing fields
This commit is contained in:
+150
-6
@@ -16,16 +16,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.debugger.breakpoints
|
package org.jetbrains.kotlin.idea.debugger.breakpoints
|
||||||
|
|
||||||
import com.intellij.CommonBundle
|
|
||||||
import com.intellij.debugger.DebuggerBundle
|
import com.intellij.debugger.DebuggerBundle
|
||||||
import com.intellij.debugger.SourcePosition
|
import com.intellij.debugger.SourcePosition
|
||||||
|
import com.intellij.debugger.engine.DebugProcessImpl
|
||||||
|
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||||
import com.intellij.debugger.impl.PositionUtil
|
import com.intellij.debugger.impl.PositionUtil
|
||||||
|
import com.intellij.debugger.requests.Requestor
|
||||||
import com.intellij.debugger.ui.breakpoints.*
|
import com.intellij.debugger.ui.breakpoints.*
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.Messages
|
import com.intellij.openapi.ui.Messages
|
||||||
import com.intellij.openapi.util.Ref
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
@@ -33,16 +34,22 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import com.intellij.xdebugger.XDebuggerManager
|
import com.intellij.xdebugger.XDebuggerManager
|
||||||
import com.intellij.xdebugger.XDebuggerUtil
|
import com.intellij.xdebugger.XDebuggerUtil
|
||||||
import com.intellij.xdebugger.breakpoints.XBreakpoint
|
import com.intellij.xdebugger.breakpoints.XBreakpoint
|
||||||
import com.intellij.xdebugger.breakpoints.XBreakpointProperties
|
|
||||||
import com.intellij.xdebugger.breakpoints.XLineBreakpoint
|
import com.intellij.xdebugger.breakpoints.XLineBreakpoint
|
||||||
import com.intellij.xdebugger.breakpoints.XLineBreakpointType
|
import com.intellij.xdebugger.breakpoints.XLineBreakpointType
|
||||||
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel
|
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel
|
||||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
|
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
|
||||||
|
import com.sun.jdi.Method
|
||||||
|
import com.sun.jdi.ObjectCollectedException
|
||||||
|
import com.sun.jdi.ReferenceType
|
||||||
|
import com.sun.jdi.event.*
|
||||||
|
import com.sun.jdi.request.EventRequest
|
||||||
|
import com.sun.jdi.request.MethodEntryRequest
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties
|
import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightClass
|
import org.jetbrains.kotlin.asJava.KotlinLightClass
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightClassForExplicitDeclaration
|
import org.jetbrains.kotlin.asJava.KotlinLightClassForExplicitDeclaration
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightClassForPackage
|
import org.jetbrains.kotlin.asJava.KotlinLightClassForPackage
|
||||||
|
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.idea.JetBundle
|
import org.jetbrains.kotlin.idea.JetBundle
|
||||||
@@ -51,6 +58,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
|||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
@@ -97,7 +105,7 @@ public class KotlinFieldBreakpointType : JavaBreakpointType<JavaFieldBreakpointP
|
|||||||
if (descriptor is ValueParameterDescriptor) {
|
if (descriptor is ValueParameterDescriptor) {
|
||||||
descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor)
|
descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor)
|
||||||
}
|
}
|
||||||
if (descriptor is PropertyDescriptor && bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor)) {
|
if (descriptor is PropertyDescriptor) {
|
||||||
canPutAt = true
|
canPutAt = true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -239,7 +247,34 @@ public class KotlinFieldBreakpointType : JavaBreakpointType<JavaFieldBreakpointP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinFieldBreakpoint(project: Project, breakpoint: XBreakpoint<JavaFieldBreakpointProperties>): FieldBreakpoint(project, breakpoint) {
|
class KotlinFieldBreakpoint(project: Project, breakpoint: XBreakpoint<JavaFieldBreakpointProperties>) : FieldBreakpoint(project, breakpoint) {
|
||||||
|
companion object {
|
||||||
|
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpoint")
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class BreakpointType {
|
||||||
|
FIELD,
|
||||||
|
METHOD
|
||||||
|
}
|
||||||
|
|
||||||
|
private val breakpointType: BreakpointType
|
||||||
|
|
||||||
|
init {
|
||||||
|
val element = getField()!!
|
||||||
|
val bindingContext = element.analyzeAndGetResult().bindingContext
|
||||||
|
var descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
|
||||||
|
if (descriptor is ValueParameterDescriptor) {
|
||||||
|
descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
breakpointType = if (bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor as PropertyDescriptor)) {
|
||||||
|
BreakpointType.FIELD
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BreakpointType.METHOD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun isValid(): Boolean {
|
override fun isValid(): Boolean {
|
||||||
if (!BreakpointWithHighlighter.isPositionValid(getXBreakpoint().getSourcePosition())) return false
|
if (!BreakpointWithHighlighter.isPositionValid(getXBreakpoint().getSourcePosition())) return false
|
||||||
|
|
||||||
@@ -287,6 +322,115 @@ class KotlinFieldBreakpoint(project: Project, breakpoint: XBreakpoint<JavaFieldB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createRequestForPreparedClass(debugProcess: DebugProcessImpl?, refType: ReferenceType?) {
|
||||||
|
if (debugProcess == null || refType == null) return
|
||||||
|
|
||||||
|
val vm = debugProcess.getVirtualMachineProxy()
|
||||||
|
try {
|
||||||
|
when (breakpointType) {
|
||||||
|
BreakpointType.FIELD -> {
|
||||||
|
val field = refType.fieldByName(getFieldName())
|
||||||
|
if (field != null) {
|
||||||
|
val manager = debugProcess.getRequestsManager()
|
||||||
|
if (getProperties().WATCH_MODIFICATION && vm.canWatchFieldModification()) {
|
||||||
|
val request = manager.createModificationWatchpointRequest(this, field)
|
||||||
|
debugProcess.getRequestsManager().enableRequest(request)
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Modification request added")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getProperties().WATCH_ACCESS && vm.canWatchFieldAccess()) {
|
||||||
|
val request = manager.createAccessWatchpointRequest(this, field)
|
||||||
|
debugProcess.getRequestsManager().enableRequest(request)
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Field access request added (field = ${field.name()}; refType = ${refType.name()})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BreakpointType.METHOD -> {
|
||||||
|
val propertyName = Name.identifier(getFieldName())
|
||||||
|
|
||||||
|
if (getProperties().WATCH_ACCESS) {
|
||||||
|
val getter = refType.methodsByName(PropertyCodegen.getterName(propertyName)).firstOrNull()
|
||||||
|
if (getter != null) {
|
||||||
|
createMethodBreakpoint(debugProcess, refType, getter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getProperties().WATCH_MODIFICATION) {
|
||||||
|
val setter = refType.methodsByName(PropertyCodegen.setterName(propertyName)).firstOrNull()
|
||||||
|
if (setter != null) {
|
||||||
|
createMethodBreakpoint(debugProcess, refType, setter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex: Exception) {
|
||||||
|
LOG.debug(ex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createMethodBreakpoint(debugProcess: DebugProcessImpl, refType: ReferenceType, accessor: Method) {
|
||||||
|
val manager = debugProcess.getRequestsManager()
|
||||||
|
val line = accessor.allLineLocations().firstOrNull()
|
||||||
|
if (line != null) {
|
||||||
|
val request = manager.createBreakpointRequest(this, line)
|
||||||
|
debugProcess.getRequestsManager().enableRequest(request)
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Breakpoint request added")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var entryRequest: MethodEntryRequest? = findRequest(debugProcess, javaClass(), this)
|
||||||
|
if (entryRequest == null) {
|
||||||
|
entryRequest = manager.createMethodEntryRequest(this)!!
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Method entry request added (method = ${accessor.name()}; refType = ${refType.name()})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entryRequest.disable()
|
||||||
|
}
|
||||||
|
entryRequest.addClassFilter(refType)
|
||||||
|
manager.enableRequest(entryRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : EventRequest> findRequest(debugProcess: DebugProcessImpl, requestClass: Class<T>, requestor: Requestor): T? {
|
||||||
|
val requests = debugProcess.getRequestsManager().findRequests(requestor)
|
||||||
|
for (eventRequest in requests) {
|
||||||
|
if (eventRequest.javaClass == requestClass) {
|
||||||
|
return eventRequest as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun evaluateCondition(context: EvaluationContextImpl, event: LocatableEvent): Boolean {
|
||||||
|
if (breakpointType == BreakpointType.METHOD && !matchesEvent(event)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return super.evaluateCondition(context, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun matchesEvent(event: LocatableEvent): Boolean {
|
||||||
|
val method = event.location().method()
|
||||||
|
// TODO check property type
|
||||||
|
return method != null && method.name() in getMethodsName()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMethodsName(): List<String> {
|
||||||
|
val propertyName = Name.identifier(getFieldName())
|
||||||
|
return arrayListOf(PropertyCodegen.getterName(propertyName), PropertyCodegen.setterName(propertyName))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getEventMessage(event: LocatableEvent?): String? {
|
||||||
|
return super.getEventMessage(event)
|
||||||
|
}
|
||||||
|
|
||||||
fun setFieldName(fieldName: String) {
|
fun setFieldName(fieldName: String) {
|
||||||
getProperties().myFieldName = fieldName
|
getProperties().myFieldName = fieldName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
KotlinFieldBreakpoint created at fwAbstractProperty.kt:5
|
||||||
|
KotlinFieldBreakpoint created at fwAbstractProperty.kt:8
|
||||||
|
KotlinFieldBreakpoint created at fwAbstractProperty.kt:42
|
||||||
|
KotlinFieldBreakpoint created at fwAbstractProperty.kt:45
|
||||||
|
!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! fwAbstractProperty.FwAbstractPropertyPackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
fwAbstractProperty.kt:57
|
||||||
|
fwAbstractProperty.kt:59
|
||||||
|
fwAbstractProperty.kt:61
|
||||||
|
fwAbstractProperty.kt:19
|
||||||
|
fwAbstractProperty.kt:20
|
||||||
|
fwAbstractProperty.kt:20
|
||||||
|
fwAbstractProperty.kt:19
|
||||||
|
fwAbstractProperty.kt:20
|
||||||
|
fwAbstractProperty.kt:20
|
||||||
|
fwAbstractProperty.kt:43
|
||||||
|
fwAbstractProperty.kt:46
|
||||||
|
fwAbstractProperty.kt:43
|
||||||
|
fwAbstractProperty.kt:46
|
||||||
|
fwAbstractProperty.kt:46
|
||||||
|
fwAbstractProperty.kt:43
|
||||||
|
fwAbstractProperty.kt:46
|
||||||
|
fwAbstractProperty.kt:46
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
KotlinFieldBreakpoint created at fwPropertyInInterface.kt:5
|
||||||
|
KotlinFieldBreakpoint created at fwPropertyInInterface.kt:8
|
||||||
|
KotlinFieldBreakpoint created at fwPropertyInInterface.kt:42
|
||||||
|
KotlinFieldBreakpoint created at fwPropertyInInterface.kt:45
|
||||||
|
!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! fwPropertyInInterface.FwPropertyInInterfacePackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
fwPropertyInInterface.kt:57
|
||||||
|
fwPropertyInInterface.kt:59
|
||||||
|
fwPropertyInInterface.kt:61
|
||||||
|
fwPropertyInInterface.kt:19
|
||||||
|
fwPropertyInInterface.kt:20
|
||||||
|
fwPropertyInInterface.kt:20
|
||||||
|
fwPropertyInInterface.kt:19
|
||||||
|
fwPropertyInInterface.kt:20
|
||||||
|
fwPropertyInInterface.kt:20
|
||||||
|
fwPropertyInInterface.kt:43
|
||||||
|
fwPropertyInInterface.kt:46
|
||||||
|
fwPropertyInInterface.kt:43
|
||||||
|
fwPropertyInInterface.kt:46
|
||||||
|
fwPropertyInInterface.kt:46
|
||||||
|
fwPropertyInInterface.kt:43
|
||||||
|
fwPropertyInInterface.kt:46
|
||||||
|
fwPropertyInInterface.kt:46
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package fwAbstractProperty
|
||||||
|
|
||||||
|
// Breakpoint at getter/setter
|
||||||
|
abstract class MyAbstractClass {
|
||||||
|
//FieldWatchpoint! (propVal)
|
||||||
|
abstract val propVal: Int
|
||||||
|
|
||||||
|
//FieldWatchpoint! (propVar)
|
||||||
|
abstract var propVar: Int
|
||||||
|
|
||||||
|
fun testPropertyInAbstractClass() {
|
||||||
|
propVal
|
||||||
|
propVar
|
||||||
|
propVar = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyAbstractClassImpl : MyAbstractClass() {
|
||||||
|
override val propVal = 1
|
||||||
|
override var propVar = 1
|
||||||
|
|
||||||
|
fun testPropertyInAbstractClassImpl() {
|
||||||
|
propVal
|
||||||
|
propVar
|
||||||
|
propVar = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MyAbstractClassWithoutBreakpoints {
|
||||||
|
abstract val propVal2: Int
|
||||||
|
abstract var propVar2: Int
|
||||||
|
|
||||||
|
fun testPropertyInAbstractClass() {
|
||||||
|
propVal2
|
||||||
|
propVar2
|
||||||
|
propVar2 = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Breakpoint at GETFILED/PUTFIELD
|
||||||
|
class MyAbstractClassImplWithBreakpoints : MyAbstractClassWithoutBreakpoints() {
|
||||||
|
//FieldWatchpoint! (propVal2)
|
||||||
|
override val propVal2 = 1
|
||||||
|
|
||||||
|
//FieldWatchpoint! (propVar2)
|
||||||
|
override var propVar2 = 1
|
||||||
|
|
||||||
|
fun testPropertyInAbstractClassImpl() {
|
||||||
|
propVal2
|
||||||
|
propVar2
|
||||||
|
propVar2 = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val mac = object: MyAbstractClass() {
|
||||||
|
override val propVal: Int get() = 1
|
||||||
|
override var propVar: Int
|
||||||
|
get() = 1
|
||||||
|
set(value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mac.testPropertyInAbstractClass()
|
||||||
|
|
||||||
|
val maci = MyAbstractClassImpl()
|
||||||
|
maci.testPropertyInAbstractClass()
|
||||||
|
maci.testPropertyInAbstractClassImpl()
|
||||||
|
|
||||||
|
val macwb = object: MyAbstractClassWithoutBreakpoints() {
|
||||||
|
override val propVal2: Int get() = 1
|
||||||
|
override var propVar2: Int
|
||||||
|
get() = 1
|
||||||
|
set(value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macwb.testPropertyInAbstractClass()
|
||||||
|
|
||||||
|
val macwbi = MyAbstractClassImplWithBreakpoints()
|
||||||
|
macwbi.testPropertyInAbstractClass()
|
||||||
|
macwbi.testPropertyInAbstractClassImpl()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RESUME: 17
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package fwPropertyInInterface
|
||||||
|
|
||||||
|
// Breakpoint at getter/setter
|
||||||
|
interface MyInterface {
|
||||||
|
//FieldWatchpoint! (propVal)
|
||||||
|
val propVal: Int
|
||||||
|
|
||||||
|
//FieldWatchpoint! (propVar)
|
||||||
|
var propVar: Int
|
||||||
|
|
||||||
|
fun testPropertyInInterface() {
|
||||||
|
propVal
|
||||||
|
propVar
|
||||||
|
propVar = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyInterfaceImpl : MyInterface {
|
||||||
|
override val propVal = 1
|
||||||
|
override var propVar = 1
|
||||||
|
|
||||||
|
fun testPropertyInInterfaceImpl() {
|
||||||
|
propVal
|
||||||
|
propVar
|
||||||
|
propVar = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MyInterfaceWithoutBreakpoints {
|
||||||
|
val propVal2: Int
|
||||||
|
var propVar2: Int
|
||||||
|
|
||||||
|
fun testPropertyInInterface() {
|
||||||
|
propVal2
|
||||||
|
propVar2
|
||||||
|
propVar2 = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Breakpoint at GETFILED/PUTFIELD
|
||||||
|
class MyInterfaceImplWithBreakpoints : MyInterfaceWithoutBreakpoints {
|
||||||
|
//FieldWatchpoint! (propVal2)
|
||||||
|
override val propVal2 = 1
|
||||||
|
|
||||||
|
//FieldWatchpoint! (propVar2)
|
||||||
|
override var propVar2 = 1
|
||||||
|
|
||||||
|
fun testPropertyInInterfaceImpl() {
|
||||||
|
propVal2
|
||||||
|
propVar2
|
||||||
|
propVar2 = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val mac = object: MyInterface {
|
||||||
|
override val propVal: Int get() = 1
|
||||||
|
override var propVar: Int
|
||||||
|
get() = 1
|
||||||
|
set(value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mac.testPropertyInInterface()
|
||||||
|
|
||||||
|
val maci = MyInterfaceImpl()
|
||||||
|
maci.testPropertyInInterface()
|
||||||
|
maci.testPropertyInInterfaceImpl()
|
||||||
|
|
||||||
|
val macwb = object: MyInterfaceWithoutBreakpoints {
|
||||||
|
override val propVal2: Int get() = 1
|
||||||
|
override var propVar2: Int
|
||||||
|
get() = 1
|
||||||
|
set(value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macwb.testPropertyInInterface()
|
||||||
|
|
||||||
|
val macwbi = MyInterfaceImplWithBreakpoints()
|
||||||
|
macwbi.testPropertyInInterface()
|
||||||
|
macwbi.testPropertyInInterfaceImpl()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RESUME: 17
|
||||||
-10
@@ -1,15 +1,5 @@
|
|||||||
package inapplicableFieldWatchpoints
|
package inapplicableFieldWatchpoints
|
||||||
|
|
||||||
class A {
|
|
||||||
//FieldWatchpoint! (propWithGet)
|
|
||||||
val propWithGet: Int get() = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
interface T {
|
|
||||||
//FieldWatchpoint! (propInInterface)
|
|
||||||
val propInInterface: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
//FieldWatchpoint! (localVal)
|
//FieldWatchpoint! (localVal)
|
||||||
val localVal = 1
|
val localVal = 1
|
||||||
|
|||||||
@@ -382,6 +382,18 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/custom"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/custom"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fwAbstractProperty.kt")
|
||||||
|
public void testFwAbstractProperty() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/fwAbstractProperty.kt");
|
||||||
|
doCustomTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fwPropertyInInterface.kt")
|
||||||
|
public void testFwPropertyInInterface() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/fwPropertyInInterface.kt");
|
||||||
|
doCustomTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("stepIntoStdlibInlineFun2step.kt")
|
@TestMetadata("stepIntoStdlibInlineFun2step.kt")
|
||||||
public void testStepIntoStdlibInlineFun2step() throws Exception {
|
public void testStepIntoStdlibInlineFun2step() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepIntoStdlibInlineFun2step.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepIntoStdlibInlineFun2step.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user