Stepping: skip methods deleting to static method call of DefaultImpl.
Support smart step into interface methods with implementation #KT-4803 Fixed
This commit is contained in:
+62
@@ -18,9 +18,13 @@ package org.jetbrains.kotlin.idea.debugger.filter
|
|||||||
|
|
||||||
import com.intellij.debugger.engine.SyntheticTypeComponentProvider
|
import com.intellij.debugger.engine.SyntheticTypeComponentProvider
|
||||||
import com.sun.jdi.AbsentInformationException
|
import com.sun.jdi.AbsentInformationException
|
||||||
|
import com.sun.jdi.ClassType
|
||||||
import com.sun.jdi.Method
|
import com.sun.jdi.Method
|
||||||
import com.sun.jdi.TypeComponent
|
import com.sun.jdi.TypeComponent
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
import sun.tools.java.RuntimeConstants
|
||||||
|
|
||||||
public class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvider {
|
public class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvider {
|
||||||
override fun isSynthetic(typeComponent: TypeComponent?): Boolean {
|
override fun isSynthetic(typeComponent: TypeComponent?): Boolean {
|
||||||
@@ -30,6 +34,8 @@ public class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvide
|
|||||||
if (!FqNameUnsafe.isValid(typeName)) return false
|
if (!FqNameUnsafe.isValid(typeName)) return false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (typeComponent.isDelegateToDefaultInterfaceImpl()) return true
|
||||||
|
|
||||||
if (typeComponent.location().lineNumber() != 1) return false
|
if (typeComponent.location().lineNumber() != 1) return false
|
||||||
|
|
||||||
if (typeComponent.allLineLocations().any { it.lineNumber() != 1 }) {
|
if (typeComponent.allLineLocations().any { it.lineNumber() != 1 }) {
|
||||||
@@ -42,4 +48,60 @@ public class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvide
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Method.isDelegateToDefaultInterfaceImpl(): Boolean {
|
||||||
|
if (allLineLocations().size != 1) return false
|
||||||
|
|
||||||
|
if (!hasOnlyInvokeStatic(this)) return false
|
||||||
|
|
||||||
|
return hasInterfaceWithImplementation(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val LOAD_INSTRUCTIONS_WITH_INDEX = Opcodes.ILOAD.toByte()..Opcodes.ALOAD.toByte()
|
||||||
|
private val LOAD_INSTRUCTIONS = (Opcodes.ALOAD + 1).toByte()..(Opcodes.IALOAD - 1).toByte()
|
||||||
|
|
||||||
|
private val RETURN_INSTRUCTIONS = Opcodes.IRETURN.toByte()..Opcodes.RETURN.toByte()
|
||||||
|
|
||||||
|
// Check that method contains only load and invokeStatic instructions. Note that if after load goes ldc instruction it could be checkParametersNotNull method invocation
|
||||||
|
private fun hasOnlyInvokeStatic(m: Method): Boolean {
|
||||||
|
val bytecodes = m.bytecodes()
|
||||||
|
var i = 0
|
||||||
|
var isALoad0BeforeStaticCall = false
|
||||||
|
while (i < bytecodes.size) {
|
||||||
|
val instr = bytecodes[i]
|
||||||
|
when {
|
||||||
|
instr == 42.toByte() /* ALOAD_0 */ -> {
|
||||||
|
i += 1
|
||||||
|
isALoad0BeforeStaticCall = true
|
||||||
|
}
|
||||||
|
instr in LOAD_INSTRUCTIONS_WITH_INDEX || instr in LOAD_INSTRUCTIONS -> {
|
||||||
|
i += 1
|
||||||
|
if (instr in LOAD_INSTRUCTIONS_WITH_INDEX) i += 1
|
||||||
|
val nextInstr = bytecodes[i]
|
||||||
|
if (nextInstr == Opcodes.LDC.toByte()) {
|
||||||
|
i += 2
|
||||||
|
isALoad0BeforeStaticCall = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instr == Opcodes.INVOKESTATIC.toByte() -> {
|
||||||
|
i += 3
|
||||||
|
if (isALoad0BeforeStaticCall && i == (bytecodes.size - 1)) {
|
||||||
|
val nextInstr = bytecodes[i]
|
||||||
|
return nextInstr in RETURN_INSTRUCTIONS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: class DefaultImpl can be not loaded
|
||||||
|
private fun hasInterfaceWithImplementation(method: Method): Boolean {
|
||||||
|
val declaringType = method.declaringType() as? ClassType ?: return false
|
||||||
|
val interfaces = declaringType.allInterfaces()
|
||||||
|
val vm = declaringType.virtualMachine()
|
||||||
|
val traitImpls = interfaces.flatMap { vm.classesByName(it.name() + JvmAbi.DEFAULT_IMPLS_SUFFIX) }
|
||||||
|
return traitImpls.any { !it.methodsByName(method.name()).isEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:90
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:95
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:100
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:105
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:110
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:120
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:125
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:130
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:138
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:143
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:148
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceImpl.kt:154
|
||||||
|
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! smartStepIntoInterfaceImpl.SmartStepIntoInterfaceImplKt
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
smartStepIntoInterfaceImpl.kt:90
|
||||||
|
smartStepIntoInterfaceImpl.kt:95
|
||||||
|
smartStepIntoInterfaceImpl.kt:8
|
||||||
|
smartStepIntoInterfaceImpl.kt:100
|
||||||
|
smartStepIntoInterfaceImpl.kt:13
|
||||||
|
smartStepIntoInterfaceImpl.kt:105
|
||||||
|
smartStepIntoInterfaceImpl.kt:13
|
||||||
|
smartStepIntoInterfaceImpl.kt:110
|
||||||
|
smartStepIntoInterfaceImpl.kt:18
|
||||||
|
smartStepIntoInterfaceImpl.kt:120
|
||||||
|
smartStepIntoInterfaceImpl.kt:22
|
||||||
|
smartStepIntoInterfaceImpl.kt:125
|
||||||
|
smartStepIntoInterfaceImpl.kt:36
|
||||||
|
smartStepIntoInterfaceImpl.kt:130
|
||||||
|
smartStepIntoInterfaceImpl.kt:41
|
||||||
|
smartStepIntoInterfaceImpl.kt:138
|
||||||
|
MyJavaClass.java:16
|
||||||
|
smartStepIntoInterfaceImpl.kt:143
|
||||||
|
smartStepIntoInterfaceImpl.kt:59
|
||||||
|
smartStepIntoInterfaceImpl.kt:148
|
||||||
|
smartStepIntoInterfaceImpl.kt:64
|
||||||
|
smartStepIntoInterfaceImpl.kt:154
|
||||||
|
smartStepIntoInterfaceImpl.kt:70
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
LineBreakpoint created at syntheticProvider.kt:38
|
||||||
|
LineBreakpoint created at syntheticProvider.kt:42
|
||||||
|
LineBreakpoint created at syntheticProvider.kt:46
|
||||||
|
LineBreakpoint created at syntheticProvider.kt:50
|
||||||
|
LineBreakpoint created at syntheticProvider.kt:54
|
||||||
|
LineBreakpoint created at syntheticProvider.kt:58
|
||||||
|
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! syntheticProvider.SyntheticProviderKt
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
syntheticProvider.kt:38
|
||||||
|
syntheticProvider.kt:5
|
||||||
|
syntheticProvider.kt:42
|
||||||
|
syntheticProvider.kt:9
|
||||||
|
syntheticProvider.kt:46
|
||||||
|
syntheticProvider.kt:13
|
||||||
|
syntheticProvider.kt:50
|
||||||
|
syntheticProvider.kt:17
|
||||||
|
syntheticProvider.kt:54
|
||||||
|
syntheticProvider.kt:21
|
||||||
|
syntheticProvider.kt:58
|
||||||
|
syntheticProvider.kt:25
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
-11
@@ -5,12 +5,9 @@ traits.kt:5
|
|||||||
traits.kt:6
|
traits.kt:6
|
||||||
traits.kt:41
|
traits.kt:41
|
||||||
traits.kt:27
|
traits.kt:27
|
||||||
traits.kt:41
|
|
||||||
traits.kt:6
|
traits.kt:6
|
||||||
traits.kt:7
|
traits.kt:7
|
||||||
traits.kt:41
|
|
||||||
traits.kt:31
|
traits.kt:31
|
||||||
traits.kt:41
|
|
||||||
traits.kt:7
|
traits.kt:7
|
||||||
traits.kt:8
|
traits.kt:8
|
||||||
traits.kt:43
|
traits.kt:43
|
||||||
@@ -20,24 +17,16 @@ traits.kt:47
|
|||||||
traits.kt:9
|
traits.kt:9
|
||||||
traits.kt:11
|
traits.kt:11
|
||||||
traits.kt:19
|
traits.kt:19
|
||||||
traits.kt:11
|
|
||||||
traits.kt:27
|
traits.kt:27
|
||||||
traits.kt:11
|
|
||||||
traits.kt:19
|
traits.kt:19
|
||||||
traits.kt:20
|
traits.kt:20
|
||||||
traits.kt:11
|
|
||||||
traits.kt:31
|
traits.kt:31
|
||||||
traits.kt:11
|
|
||||||
traits.kt:20
|
traits.kt:20
|
||||||
traits.kt:21
|
traits.kt:21
|
||||||
traits.kt:13
|
traits.kt:13
|
||||||
traits.kt:34
|
|
||||||
traits.kt:13
|
|
||||||
traits.kt:21
|
traits.kt:21
|
||||||
traits.kt:22
|
traits.kt:22
|
||||||
traits.kt:17
|
traits.kt:17
|
||||||
traits.kt:38
|
|
||||||
traits.kt:17
|
|
||||||
traits.kt:22
|
traits.kt:22
|
||||||
traits.kt:23
|
traits.kt:23
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|||||||
@@ -11,4 +11,8 @@ public class MyJavaClass {
|
|||||||
public String testNotNullFun() {
|
public String testNotNullFun() {
|
||||||
return "a";
|
return "a";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int staticFun(Object s) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+155
@@ -0,0 +1,155 @@
|
|||||||
|
package smartStepIntoInterfaceImpl
|
||||||
|
|
||||||
|
import forTests.MyJavaClass
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
// without params
|
||||||
|
fun foo() {
|
||||||
|
val a = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// default param
|
||||||
|
fun foo(a: Int, b: Int = 1) {
|
||||||
|
val a = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkParamNotNull
|
||||||
|
fun foo(a: String) {
|
||||||
|
val a = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fooOverride() {
|
||||||
|
val a = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun staticCallInOverride(s: String) = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class IImpl: I {
|
||||||
|
// super call in override (step into doesn't work)
|
||||||
|
override fun fooOverride() {
|
||||||
|
return super.fooOverride()
|
||||||
|
}
|
||||||
|
|
||||||
|
// java static call
|
||||||
|
fun staticCall(s: String): Int {
|
||||||
|
return MyJavaClass.staticFun(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// java static call in override
|
||||||
|
override fun staticCallInOverride(s: String): Int {
|
||||||
|
return MyJavaClass.staticFun(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IImpl2: I {
|
||||||
|
// java static call in override with this param (step into doesn't work)
|
||||||
|
override fun staticCallInOverride(s: String): Int {
|
||||||
|
return MyJavaClass.staticFun(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Obj: I {
|
||||||
|
@JvmStatic private fun staticFun(s: String): Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// kotlin static call
|
||||||
|
fun staticCall(s: String): Int {
|
||||||
|
return staticFun(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// kotlin static call in override
|
||||||
|
override fun staticCallInOverride(s: String): Int {
|
||||||
|
return staticFun(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Obj2: I {
|
||||||
|
@JvmStatic private fun staticFun(s: Obj2): Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// kotlin static call in override with this param (step into doesn't work)
|
||||||
|
override fun staticCallInOverride(s: String): Int {
|
||||||
|
return staticFun(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun barI() = IImpl()
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
testSmartStepInto()
|
||||||
|
testStepInto()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSmartStepInto() {
|
||||||
|
// TODO First time - doesn't work: should be smartStepIntoInterfaceImpl.kt:8 between smartStepIntoInterfaceImpl.kt:90 and 95
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 2
|
||||||
|
//Breakpoint!
|
||||||
|
barI().foo()
|
||||||
|
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 2
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
barI().foo()
|
||||||
|
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 2
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
barI().foo(1)
|
||||||
|
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 2
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
barI().foo(1, 2)
|
||||||
|
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 2
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
barI().foo("a")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testStepInto() {
|
||||||
|
val ii = IImpl()
|
||||||
|
|
||||||
|
// TODO: should be smartStepIntoInterfaceImpl.kt:31 instead of smartStepIntoInterfaceImpl.kt:22
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
ii.fooOverride()
|
||||||
|
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
ii.staticCall("a")
|
||||||
|
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
ii.staticCallInOverride("a")
|
||||||
|
|
||||||
|
val ii2 = IImpl2()
|
||||||
|
|
||||||
|
// TODO: should be smartStepIntoInterfaceImpl.kt:48 instead of MyJavaClass.java:16
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
ii2.staticCallInOverride("a")
|
||||||
|
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
Obj.staticCall("a")
|
||||||
|
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
Obj.staticCallInOverride("a")
|
||||||
|
|
||||||
|
// TODO: should be smartStepIntoInterfaceImpl.kt:75 instead of smartStepIntoInterfaceImpl.kt:70
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
Obj2.staticCallInOverride("a")
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package syntheticProvider
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
fun manyInts(i: Int, i2: Int, i3: Int, i4: Int): Int {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
fun manyLongs(i: Long, i2: Long, i3: Long, i4: Long): Long {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
fun manyDouble(i: Double, i2: Double, i3: Double, i4: Double): Double {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
fun manyFloat(i: Float, i2: Float, i3: Float, i4: Float): Float {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
fun manyObject(i: Any, i2: Any, i3: Any, i4: Any): Any {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
fun void() {
|
||||||
|
val a = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IImpl: I
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val i = IImpl()
|
||||||
|
i.manyInts(1, 1, 1, 1)
|
||||||
|
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
i.manyInts(1, 1, 1, 1)
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
i.manyLongs(1, 1, 1, 1)
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
i.manyDouble(1.0, 1.0, 1.0, 1.0)
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
i.manyFloat(1.0f, 1.0f, 1.0f, 1.0f)
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
i.manyObject(1, 1, 1, 1)
|
||||||
|
// STEP_INTO: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
i.void()
|
||||||
|
}
|
||||||
@@ -10,11 +10,11 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
val o = object: MyInterface {
|
val o = object: MyInterface {
|
||||||
override fun inInterfaceOverride(): Int {
|
override fun inInterfaceOverride(): Int {
|
||||||
return super.inInterfaceOverride()
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override val propInInterfaceOverride: Int
|
override val propInInterfaceOverride: Int
|
||||||
get() = super.propInInterfaceOverride
|
get() = 1
|
||||||
}
|
}
|
||||||
o.inInterface()
|
o.inInterface()
|
||||||
o.propInInterface
|
o.propInInterface
|
||||||
|
|||||||
@@ -595,6 +595,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
doCustomTest(fileName);
|
doCustomTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartStepIntoInterfaceImpl.kt")
|
||||||
|
public void testSmartStepIntoInterfaceImpl() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInterfaceImpl.kt");
|
||||||
|
doCustomTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("stepIntoStdlibInlineFun2step.kt")
|
@TestMetadata("stepIntoStdlibInlineFun2step.kt")
|
||||||
public void testStepIntoStdlibInlineFun2step() throws Exception {
|
public void testStepIntoStdlibInlineFun2step() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepIntoStdlibInlineFun2step.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepIntoStdlibInlineFun2step.kt");
|
||||||
@@ -606,5 +612,11 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepOutInlineFunctionStdlib.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepOutInlineFunctionStdlib.kt");
|
||||||
doCustomTest(fileName);
|
doCustomTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("syntheticProvider.kt")
|
||||||
|
public void testSyntheticProvider() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/syntheticProvider.kt");
|
||||||
|
doCustomTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user