Fix step over if there isn't any inlined arguments
This commit is contained in:
+28
-14
@@ -21,6 +21,7 @@ import com.intellij.debugger.engine.DebugProcessImpl
|
||||
import com.intellij.debugger.engine.SuspendContextImpl
|
||||
import com.intellij.debugger.engine.events.DebuggerCommandImpl
|
||||
import com.intellij.debugger.impl.JvmSteppingCommandProvider
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.concurrency.Semaphore
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl
|
||||
import com.sun.jdi.Location
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineCount
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineEndOffset
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineStartOffset
|
||||
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -56,7 +58,8 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
|
||||
val file = sourcePosition.file as? JetFile ?: return null
|
||||
|
||||
val inlinedArguments = getInlinedArgumentsIfAny(sourcePosition) ?: return null
|
||||
val inlinedArguments = getInlinedArgumentsIfAny(sourcePosition)
|
||||
if (inlinedArguments.isEmpty()) return null
|
||||
|
||||
val locations = computedReferenceType.allLineLocations()
|
||||
val countOfLinesInFile = file.getLineCount()
|
||||
@@ -96,7 +99,7 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
val nextLineLocations = locations.dropWhile { it.lineNumber() != location.lineNumber() }.filter { it.method() == location.method() }
|
||||
|
||||
val inlineFunction = getInlineFunctionsIfAny(file, lineStartOffset)
|
||||
if (inlineFunction != null) {
|
||||
if (inlineFunction.isNotEmpty()) {
|
||||
val xPosition = suspendContext.getXPositionForStepOutFromInlineFunction(nextLineLocations, inlineFunction) ?: return null
|
||||
return suspendContext.debugProcess.createRunToCursorCommand(suspendContext, xPosition, true)
|
||||
}
|
||||
@@ -152,12 +155,12 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getInlineFunctionsIfAny(file: JetFile, offset: Int): List<JetNamedFunction>? {
|
||||
val elementAt = file.findElementAt(offset) ?: return null
|
||||
val containingFunction = elementAt.getParentOfType<JetNamedFunction>(false) ?: return null
|
||||
private fun getInlineFunctionsIfAny(file: JetFile, offset: Int): List<JetNamedFunction> {
|
||||
val elementAt = file.findElementAt(offset) ?: return emptyList()
|
||||
val containingFunction = elementAt.getParentOfType<JetNamedFunction>(false) ?: return emptyList()
|
||||
|
||||
val descriptor = containingFunction.resolveToDescriptor()
|
||||
if (!InlineUtil.isInline(descriptor)) return null
|
||||
if (!InlineUtil.isInline(descriptor)) return emptyList()
|
||||
|
||||
val inlineFunctionsCalls = DebuggerUtils.analyzeElementWithInline(
|
||||
containingFunction.getResolutionFacade(),
|
||||
@@ -211,16 +214,27 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getInlinedArgumentsIfAny(sourcePosition: SourcePosition): List<JetFunction>? {
|
||||
val file = sourcePosition.file as? JetFile ?: return null
|
||||
private fun getInlinedArgumentsIfAny(sourcePosition: SourcePosition): List<JetFunction> {
|
||||
val file = sourcePosition.file as? JetFile ?: return emptyList()
|
||||
val lineNumber = sourcePosition.line
|
||||
val elementAt = CodeInsightUtils.getTopmostElementAtOffset(
|
||||
sourcePosition.elementAt,
|
||||
file.getLineStartOffset(lineNumber) ?: sourcePosition.elementAt.startOffset
|
||||
) ?: return null
|
||||
var elementAt = sourcePosition.elementAt
|
||||
|
||||
val start = elementAt.startOffset
|
||||
val end = elementAt.endOffset
|
||||
var startOffset = file.getLineStartOffset(lineNumber) ?: elementAt.startOffset
|
||||
var endOffset = file.getLineEndOffset(lineNumber) ?: elementAt.endOffset
|
||||
|
||||
var topMostElement: PsiElement? = null
|
||||
while (topMostElement !is JetElement && startOffset < endOffset) {
|
||||
elementAt = file.findElementAt(startOffset)
|
||||
if (elementAt != null) {
|
||||
topMostElement = CodeInsightUtils.getTopmostElementAtOffset(elementAt, startOffset)
|
||||
}
|
||||
startOffset++
|
||||
}
|
||||
|
||||
if (topMostElement == null) return emptyList()
|
||||
|
||||
val start = topMostElement.startOffset
|
||||
val end = topMostElement.endOffset
|
||||
|
||||
return CodeInsightUtils.
|
||||
findElementsOfClassInRange(file, start, end, JetFunctionLiteral::class.java, JetNamedFunction::class.java)
|
||||
|
||||
@@ -280,7 +280,7 @@ public class SelectionAwareScopeHighlighter(val editor: Editor) {
|
||||
}
|
||||
|
||||
fun PsiFile.getLineStartOffset(line: Int): Int? {
|
||||
val doc = this.let { file -> PsiDocumentManager.getInstance(getProject()).getDocument(file) }
|
||||
val doc = PsiDocumentManager.getInstance(project).getDocument(this)
|
||||
if (doc != null) {
|
||||
val startOffset = doc.getLineStartOffset(line)
|
||||
val element = findElementAt(startOffset) ?: return startOffset
|
||||
@@ -291,6 +291,10 @@ fun PsiFile.getLineStartOffset(line: Int): Int? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun PsiFile.getLineEndOffset(line: Int): Int? {
|
||||
return PsiDocumentManager.getInstance(project).getDocument(this)?.getLineEndOffset(line)
|
||||
}
|
||||
|
||||
fun PsiElement.getLineCount(): Int {
|
||||
val doc = getContainingFile()?.let { file -> PsiDocumentManager.getInstance(getProject()).getDocument(file) }
|
||||
if (doc != null) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
LineBreakpoint created at stepOverSimpleFun.kt:11
|
||||
!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! stepOverSimpleFun.StepOverSimpleFunPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
stepOverSimpleFun.kt:11
|
||||
stepOverSimpleFun.kt:4
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,26 @@
|
||||
package stepOverSimpleFun
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
foo(1)
|
||||
val a = 1
|
||||
}
|
||||
|
||||
fun foo(i: Int): Int {
|
||||
if (i > 0) {
|
||||
//Breakpoint!
|
||||
return 1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// Do not remove: kotlin strata should be available for this test
|
||||
inline fun f(p: () -> Unit) {
|
||||
val b = 1
|
||||
p()
|
||||
}
|
||||
|
||||
fun f2() {
|
||||
f {
|
||||
val b = 1
|
||||
}
|
||||
}
|
||||
@@ -348,6 +348,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverInlinedLambdaStdlib.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stepOverSimpleFun.kt")
|
||||
public void testStepOverSimpleFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverSimpleFun.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/debugger/tinyApp/src/stepping/filters")
|
||||
|
||||
Reference in New Issue
Block a user