Fix steping for inline functions with reified parameters
This commit is contained in:
+29
-14
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
@@ -58,8 +59,10 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
|
||||
val file = sourcePosition.file as? JetFile ?: return null
|
||||
|
||||
val inlinedArguments = getInlinedArgumentsIfAny(sourcePosition)
|
||||
if (inlinedArguments.isEmpty()) return null
|
||||
val inlineFunctionCalls = getInlineFunctionCallsIfAny(sourcePosition)
|
||||
if (inlineFunctionCalls.isEmpty()) return null
|
||||
|
||||
val inlinedArguments = getInlinedArgumentsIfAny(inlineFunctionCalls)
|
||||
|
||||
if (inlinedArguments.any { it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
||||
return null
|
||||
@@ -305,7 +308,16 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getInlinedArgumentsIfAny(sourcePosition: SourcePosition): List<JetFunction> {
|
||||
private fun getInlinedArgumentsIfAny(inlineFunctionCalls: List<JetCallExpression>): List<JetFunction> {
|
||||
return inlineFunctionCalls.flatMap {
|
||||
it.valueArguments
|
||||
.map { it.getArgumentExpression() }
|
||||
.filterIsInstance<JetFunctionLiteralExpression>()
|
||||
.map { it.functionLiteral }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInlineFunctionCallsIfAny(sourcePosition: SourcePosition): List<JetCallExpression> {
|
||||
val file = sourcePosition.file as? JetFile ?: return emptyList()
|
||||
val lineNumber = sourcePosition.line
|
||||
var elementAt = sourcePosition.elementAt
|
||||
@@ -327,20 +339,23 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
val start = topMostElement.startOffset
|
||||
val end = topMostElement.endOffset
|
||||
|
||||
val allInlinedArguments = CodeInsightUtils.
|
||||
findElementsOfClassInRange(file, start, end, JetFunctionLiteral::class.java, JetNamedFunction::class.java)
|
||||
.filter { JetPsiUtil.getParentCallIfPresent(it as JetExpression) != null }
|
||||
.filterIsInstance<JetFunction>()
|
||||
.filter {
|
||||
val context = it.analyze(BodyResolveMode.PARTIAL)
|
||||
InlineUtil.isInlinedArgument(it, context, false)
|
||||
}
|
||||
fun isInlineCall(expr: JetExpression): Boolean {
|
||||
val context = expr.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = expr.getResolvedCall(context) ?: return false
|
||||
return InlineUtil.isInline(resolvedCall.resultingDescriptor)
|
||||
}
|
||||
|
||||
val allInlineFunctionCalls = CodeInsightUtils.
|
||||
findElementsOfClassInRange(file, start, end, JetExpression::class.java)
|
||||
.map { JetPsiUtil.getParentCallIfPresent(it as JetExpression) }
|
||||
.filterIsInstance<JetCallExpression>()
|
||||
.filter { isInlineCall(it) }
|
||||
.toSet()
|
||||
|
||||
// It is necessary to check range because of multiline assign
|
||||
var linesRange = lineNumber..lineNumber
|
||||
return allInlinedArguments.filter {
|
||||
val parentCall = JetPsiUtil.getParentCallIfPresent(it)!!
|
||||
val shouldInclude = parentCall.getLineNumber() in linesRange
|
||||
return allInlineFunctionCalls.filter {
|
||||
val shouldInclude = it.getLineNumber() in linesRange
|
||||
if (shouldInclude) {
|
||||
linesRange = Math.min(linesRange.start, it.getLineNumber())..Math.max(linesRange.end, it.getLineNumber(false))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
LineBreakpoint created at stepOverReifiedParam.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 !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! stepOverReifiedParam.StepOverReifiedParamPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
stepOverReifiedParam.kt:5
|
||||
stepOverReifiedParam.kt:6
|
||||
stepOverReifiedParam.kt:7
|
||||
stepOverReifiedParam.kt:8
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,15 @@
|
||||
package stepOverReifiedParam
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
//Breakpoint!
|
||||
val a = 1
|
||||
foo(a)
|
||||
val b = 1
|
||||
}
|
||||
|
||||
inline fun <reified T> foo(t: T): T {
|
||||
val a = t
|
||||
return a
|
||||
}
|
||||
|
||||
// STEP_OVER: 3
|
||||
@@ -367,6 +367,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stepOverReifiedParam.kt")
|
||||
public void testStepOverReifiedParam() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverReifiedParam.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stepOverSimpleFun.kt")
|
||||
public void testStepOverSimpleFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverSimpleFun.kt");
|
||||
|
||||
Reference in New Issue
Block a user