Skip all same line locations when stepping over inline call (KT-20351)
#KT-20351
This commit is contained in:
+12
-12
@@ -336,7 +336,7 @@ fun getStepOverAction(
|
||||
return ktFile?.name ?: this.sourceName(KOTLIN_STRATA_NAME)
|
||||
}
|
||||
|
||||
fun isLocationSuitable(nextLocation: Location): Boolean {
|
||||
fun isThisMethodLocation(nextLocation: Location): Boolean {
|
||||
if (nextLocation.method() != location.method()) {
|
||||
return false
|
||||
}
|
||||
@@ -358,7 +358,7 @@ fun getStepOverAction(
|
||||
val previousSuitableLocation = methodLocations.reversed()
|
||||
.dropWhile { it != location }
|
||||
.drop(1)
|
||||
.filter(::isLocationSuitable)
|
||||
.filter(::isThisMethodLocation)
|
||||
.dropWhile { it.ktLineNumber() == location.ktLineNumber() }
|
||||
.firstOrNull()
|
||||
|
||||
@@ -368,7 +368,7 @@ fun getStepOverAction(
|
||||
val patchedLocation = if (isBackEdgeLocation()) {
|
||||
// Pretend we had already done a backing step
|
||||
methodLocations
|
||||
.filter(::isLocationSuitable)
|
||||
.filter(::isThisMethodLocation)
|
||||
.firstOrNull { it.ktLineNumber() == location.ktLineNumber() } ?: location
|
||||
}
|
||||
else {
|
||||
@@ -388,22 +388,22 @@ fun getStepOverAction(
|
||||
|
||||
val inlineRangeVariables = getInlineRangeLocalVariables(frameProxy)
|
||||
|
||||
// Try to find the range of inlined lines:
|
||||
// - Lines from other files and from functions that are not in range of current one are definitely inlined
|
||||
// Try to find the range for step over:
|
||||
// - Lines from other files and from functions that are not in range of current one are definitely inlined and should be stepped over.
|
||||
// - Lines in function arguments of inlined functions are inlined too as we found them starting from the position of inlined call.
|
||||
// - Current line locations should also be stepped over.
|
||||
//
|
||||
// It also thinks that too many lines are inlined when there's a call of function argument or other
|
||||
// inline function in last statement of inline function. The list of inlineRangeVariables is used to overcome it.
|
||||
val probablyInlinedLocations = methodLocations
|
||||
// We might erroneously extend this range too much when there's a call of function argument or other
|
||||
// inline function in last statement of inline function. The list of inlineRangeVariables will be used later to overcome it.
|
||||
val stepOverLocations = methodLocations
|
||||
.dropWhile { it != patchedLocation }
|
||||
.drop(1)
|
||||
.dropWhile { it.ktLineNumber() == patchedLineNumber }
|
||||
.takeWhile { loc ->
|
||||
!isLocationSuitable(loc) || lambdaArgumentRanges.any { loc.ktLineNumber() in it }
|
||||
!isThisMethodLocation(loc) || lambdaArgumentRanges.any { loc.ktLineNumber() in it } || loc.ktLineNumber() == patchedLineNumber
|
||||
}
|
||||
.dropWhile { it.ktLineNumber() == patchedLineNumber }
|
||||
|
||||
if (!probablyInlinedLocations.isEmpty()) {
|
||||
if (!stepOverLocations.isEmpty()) {
|
||||
// Some Kotlin inlined methods with 'for' (and maybe others) generates bytecode that after dexing have a strange artifact.
|
||||
// GOTO instructions are moved to the end of method and as they don't have proper line, line is obtained from the previous
|
||||
// instruction. It might be method return or previous GOTO from the inlining. Simple stepping over such function is really
|
||||
@@ -423,7 +423,7 @@ fun getStepOverAction(
|
||||
|
||||
return Action.STEP_OVER_INLINED(StepOverFilterData(
|
||||
patchedLineNumber,
|
||||
probablyInlinedLocations.map { it.ktLineNumber() }.toSet(),
|
||||
stepOverLocations.map { it.ktLineNumber() }.toSet(),
|
||||
inlineRangeVariables,
|
||||
isDexDebug,
|
||||
returnCodeIndex
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package soInlineCallsInOneLine
|
||||
|
||||
fun test(i: Int): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun foo() {}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
//Breakpoint!
|
||||
val listOf = listOf(1)
|
||||
val testSome = listOf.filterNot(::test)
|
||||
foo()
|
||||
}
|
||||
|
||||
|
||||
// STEP_OVER: 3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
LineBreakpoint created at soInlineCallsInOneLine.kt:11
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
soInlineCallsInOneLine.kt:11
|
||||
soInlineCallsInOneLine.kt:12
|
||||
soInlineCallsInOneLine.kt:13
|
||||
soInlineCallsInOneLine.kt:14
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -578,6 +578,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("soInlineCallsInOneLine.kt")
|
||||
public void testSoInlineCallsInOneLine() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/soInlineCallsInOneLine.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("soInlineFunCallInLastStatementOfInlineWithArgumentFromCalleeAndOwn.kt")
|
||||
public void testSoInlineFunCallInLastStatementOfInlineWithArgumentFromCalleeAndOwn() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/soInlineFunCallInLastStatementOfInlineWithArgumentFromCalleeAndOwn.kt");
|
||||
|
||||
Reference in New Issue
Block a user