Fix stepping for inline functions inside when, if, try
This commit is contained in:
+117
-15
@@ -30,8 +30,8 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
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.getLineEndOffset
|
||||||
|
import org.jetbrains.kotlin.idea.core.refactoring.getLineNumber
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineStartOffset
|
import org.jetbrains.kotlin.idea.core.refactoring.getLineStartOffset
|
||||||
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -61,25 +61,116 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
|||||||
val inlinedArguments = getInlinedArgumentsIfAny(sourcePosition)
|
val inlinedArguments = getInlinedArgumentsIfAny(sourcePosition)
|
||||||
if (inlinedArguments.isEmpty()) return null
|
if (inlinedArguments.isEmpty()) return null
|
||||||
|
|
||||||
|
if (inlinedArguments.any { it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val additionalElementsToSkip = sourcePosition.elementAt.getAdditionalElementsToSkip()
|
||||||
|
|
||||||
|
val containingFunction = sourcePosition.elementAt.getParentOfType<JetNamedFunction>(false)
|
||||||
|
val startLineNumber = containingFunction?.getLineNumber(true) ?: return null
|
||||||
|
val endLineNumber = containingFunction?.getLineNumber(false) ?: return null
|
||||||
|
val linesRange = startLineNumber + 1..endLineNumber + 1
|
||||||
val locations = computedReferenceType.allLineLocations()
|
val locations = computedReferenceType.allLineLocations()
|
||||||
val countOfLinesInFile = file.getLineCount()
|
.dropWhile { it != location }
|
||||||
|
.drop(1)
|
||||||
|
.filter { it.method() == location.method() && it.lineNumber() in linesRange }
|
||||||
|
.dropWhile { it.lineNumber() == location.lineNumber() }
|
||||||
|
|
||||||
val nextLine = sourcePosition.line + 2 /* +1 - because of locations are counted from 1 and +1 - because we want next line */
|
for (locationAtLine in locations) {
|
||||||
|
val lineNumber = locationAtLine.lineNumber()
|
||||||
|
val lineStartOffset = file.getLineStartOffset(lineNumber - 1) ?: continue
|
||||||
|
if (inlinedArguments.any { it.textRange.contains(lineStartOffset) }) continue
|
||||||
|
if (additionalElementsToSkip.any { it.textRange.contains(lineStartOffset) }) continue
|
||||||
|
|
||||||
for (lineNumber in nextLine..countOfLinesInFile) {
|
val elementAt = file.findElementAt(lineStartOffset) ?: continue
|
||||||
val locationAtLine = locations.firstOrNull { it.lineNumber() == lineNumber }
|
|
||||||
if (locationAtLine != null) {
|
|
||||||
val lineStartOffset = file.getLineStartOffset(lineNumber - 1) ?: continue
|
|
||||||
if (inlinedArguments.any { it.textRange.contains(lineStartOffset) }) continue
|
|
||||||
|
|
||||||
val elementAt = file.findElementAt(lineStartOffset)
|
val xPosition = XSourcePositionImpl.createByElement(elementAt) ?: return null
|
||||||
val xPosition = XSourcePositionImpl.createByElement(elementAt) ?: return null
|
return suspendContext.debugProcess.createRunToCursorCommand(suspendContext, xPosition, ignoreBreakpoints)
|
||||||
|
}
|
||||||
|
|
||||||
return suspendContext.debugProcess.createRunToCursorCommand(suspendContext, xPosition, ignoreBreakpoints)
|
return suspendContext.debugProcess.createStepOutCommand(suspendContext)!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.getAdditionalElementsToSkip(): List<PsiElement> {
|
||||||
|
val result = arrayListOf<PsiElement>()
|
||||||
|
val ifParent = getParentOfType<JetIfExpression>(false)
|
||||||
|
if (ifParent != null) {
|
||||||
|
if (ifParent.then?.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
ifParent.elseKeyword?.let { result.add(it) }
|
||||||
|
ifParent.`else`?.let { result.add(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val tryParent = getParentOfType<JetTryExpression>(false)
|
||||||
|
if (tryParent != null) {
|
||||||
|
val catchClause = getParentOfType<JetCatchClause>(false)
|
||||||
|
if (catchClause != null) {
|
||||||
|
result.addAll(tryParent.catchClauses.filter { it != catchClause })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
val whenEntry = getParentOfType<JetWhenEntry>(false)
|
||||||
|
if (whenEntry != null) {
|
||||||
|
if (whenEntry.expression?.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
val whenParent = whenEntry.getParentOfType<JetWhenExpression>(false)
|
||||||
|
if (whenParent != null) {
|
||||||
|
result.addAll(whenParent.entries.filter { it != whenEntry })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.shouldNotUseStepOver(elementAt: PsiElement): Boolean {
|
||||||
|
val ifParent = getParentOfType<JetIfExpression>(false)
|
||||||
|
if (ifParent != null) {
|
||||||
|
// if (inlineFunCall()) {...}
|
||||||
|
if (ifParent.condition?.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
<caret>if (...) inlineFunCall()
|
||||||
|
else inlineFunCall()
|
||||||
|
*/
|
||||||
|
val ifParentElementAt = elementAt.getParentOfType<JetIfExpression>(false)
|
||||||
|
if (ifParentElementAt == null) {
|
||||||
|
if (ifParent.then?.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (ifParent.`else`?.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tryParent = getParentOfType<JetTryExpression>(false)
|
||||||
|
if (tryParent != null) {
|
||||||
|
/* try { inlineFunCall() }
|
||||||
|
catch()...
|
||||||
|
*/
|
||||||
|
if (tryParent.tryBlock.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val whenEntry = getParentOfType<JetWhenEntry>(false)
|
||||||
|
if (whenEntry != null) {
|
||||||
|
// <caret>inlineFunCall -> ...
|
||||||
|
if (whenEntry.conditions.any { it.textRange.contains(this.textRange) } ) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// <caret>1 == 2 -> inlineFunCall()
|
||||||
|
if (whenEntry.expression?.textRange?.contains(this.textRange) ?: false) {
|
||||||
|
val parentEntryElementAt = elementAt.getParentOfType<JetWhenEntry>(false) ?: return true
|
||||||
|
return parentEntryElementAt == whenEntry &&
|
||||||
|
whenEntry.conditions.any { it.textRange.contains(elementAt.textRange) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStepOutCommand(suspendContext: SuspendContextImpl?, stepSize: Int): DebugProcessImpl.ResumeCommand? {
|
override fun getStepOutCommand(suspendContext: SuspendContextImpl?, stepSize: Int): DebugProcessImpl.ResumeCommand? {
|
||||||
@@ -231,12 +322,12 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
|||||||
startOffset++
|
startOffset++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topMostElement == null) return emptyList()
|
if (topMostElement !is JetElement) return emptyList()
|
||||||
|
|
||||||
val start = topMostElement.startOffset
|
val start = topMostElement.startOffset
|
||||||
val end = topMostElement.endOffset
|
val end = topMostElement.endOffset
|
||||||
|
|
||||||
return CodeInsightUtils.
|
val allInlinedArguments = CodeInsightUtils.
|
||||||
findElementsOfClassInRange(file, start, end, JetFunctionLiteral::class.java, JetNamedFunction::class.java)
|
findElementsOfClassInRange(file, start, end, JetFunctionLiteral::class.java, JetNamedFunction::class.java)
|
||||||
.filter { JetPsiUtil.getParentCallIfPresent(it as JetExpression) != null }
|
.filter { JetPsiUtil.getParentCallIfPresent(it as JetExpression) != null }
|
||||||
.filterIsInstance<JetFunction>()
|
.filterIsInstance<JetFunction>()
|
||||||
@@ -244,5 +335,16 @@ public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
|||||||
val context = it.analyze(BodyResolveMode.PARTIAL)
|
val context = it.analyze(BodyResolveMode.PARTIAL)
|
||||||
InlineUtil.isInlinedArgument(it, context, false)
|
InlineUtil.isInlinedArgument(it, context, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
if (shouldInclude) {
|
||||||
|
linesRange = Math.min(linesRange.start, it.getLineNumber())..Math.max(linesRange.end, it.getLineNumber(false))
|
||||||
|
}
|
||||||
|
shouldInclude
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,6 +302,10 @@ fun PsiFile.getLineEndOffset(line: Int): Int? {
|
|||||||
return PsiDocumentManager.getInstance(project).getDocument(this)?.getLineEndOffset(line)
|
return PsiDocumentManager.getInstance(project).getDocument(this)?.getLineEndOffset(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiElement.getLineNumber(start: Boolean = true): Int {
|
||||||
|
return PsiDocumentManager.getInstance(project).getDocument(this.containingFile)?.getLineNumber(if (start) this.startOffset else this.endOffset) ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
fun PsiElement.getLineCount(): Int {
|
fun PsiElement.getLineCount(): Int {
|
||||||
val doc = getContainingFile()?.let { file -> PsiDocumentManager.getInstance(getProject()).getDocument(file) }
|
val doc = getContainingFile()?.let { file -> PsiDocumentManager.getInstance(getProject()).getDocument(file) }
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
LineBreakpoint created at stepOverIfWithInline.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! stepOverIfWithInline.StepOverIfWithInlinePackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
stepOverIfWithInline.kt:5
|
||||||
|
stepOverIfWithInline.kt:7
|
||||||
|
stepOverIfWithInline.kt:11
|
||||||
|
stepOverIfWithInline.kt:7
|
||||||
|
stepOverIfWithInline.kt:15
|
||||||
|
stepOverIfWithInline.kt:18
|
||||||
|
stepOverIfWithInline.kt:15
|
||||||
|
stepOverIfWithInline.kt:21
|
||||||
|
stepOverIfWithInline.kt:41
|
||||||
|
stepOverIfWithInline.kt:21
|
||||||
|
stepOverIfWithInline.kt:24
|
||||||
|
stepOverIfWithInline.kt:25
|
||||||
|
stepOverIfWithInline.kt:24
|
||||||
|
stepOverIfWithInline.kt:28
|
||||||
|
stepOverIfWithInline.kt:41
|
||||||
|
stepOverIfWithInline.kt:28
|
||||||
|
stepOverIfWithInline.kt:32
|
||||||
|
stepOverIfWithInline.kt:41
|
||||||
|
stepOverIfWithInline.kt:32
|
||||||
|
stepOverIfWithInline.kt:36
|
||||||
|
stepOverIfWithInline.kt:32
|
||||||
|
stepOverIfWithInline.kt:38
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
LineBreakpoint created at stepOverInlineFunctionInReturn.kt:9
|
||||||
|
!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! stepOverInlineFunctionInReturn.StepOverInlineFunctionInReturnPackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
stepOverInlineFunctionInReturn.kt:9
|
||||||
|
stepOverInlineFunctionInReturn.kt:10
|
||||||
|
stepOverInlineFunctionInReturn.kt:4
|
||||||
|
stepOverInlineFunctionInReturn.kt:5
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -11,7 +11,8 @@ stepOverInlinedLambda.kt:19
|
|||||||
stepOverInlinedLambda.kt:20
|
stepOverInlinedLambda.kt:20
|
||||||
stepOverInlinedLambda.kt:23
|
stepOverInlinedLambda.kt:23
|
||||||
stepOverInlinedLambda.kt:29
|
stepOverInlinedLambda.kt:29
|
||||||
stepOverInlinedLambda.kt:30
|
stepOverInlinedLambda.kt:31
|
||||||
|
stepOverInlinedLambda.kt:32
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
LineBreakpoint created at stepOverTryCatchWithInline.kt:14
|
||||||
|
!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! stepOverTryCatchWithInline.StepOverTryCatchWithInlinePackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
stepOverTryCatchWithInline.kt:14
|
||||||
|
stepOverTryCatchWithInline.kt:16
|
||||||
|
stepOverTryCatchWithInline.kt:17
|
||||||
|
stepOverTryCatchWithInline.kt:48
|
||||||
|
stepOverTryCatchWithInline.kt:17
|
||||||
|
stepOverTryCatchWithInline.kt:24
|
||||||
|
stepOverTryCatchWithInline.kt:25
|
||||||
|
stepOverTryCatchWithInline.kt:28
|
||||||
|
stepOverTryCatchWithInline.kt:35
|
||||||
|
stepOverTryCatchWithInline.kt:36
|
||||||
|
stepOverTryCatchWithInline.kt:48
|
||||||
|
stepOverTryCatchWithInline.kt:36
|
||||||
|
stepOverTryCatchWithInline.kt:39
|
||||||
|
stepOverTryCatchWithInline.kt:43
|
||||||
|
stepOverTryCatchWithInline.kt:8
|
||||||
|
stepOverTryCatchWithInline.kt:10
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
LineBreakpoint created at stepOverWhenInReturn.kt:10
|
||||||
|
!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! stepOverWhenInReturn.StepOverWhenInReturnPackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
stepOverWhenInReturn.kt:10
|
||||||
|
stepOverWhenInReturn.kt:11
|
||||||
|
stepOverWhenInReturn.kt:17
|
||||||
|
stepOverWhenInReturn.kt:11
|
||||||
|
stepOverWhenInReturn.kt:10
|
||||||
|
stepOverWhenInReturn.kt:4
|
||||||
|
stepOverWhenInReturn.kt:5
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
LineBreakpoint created at stepOverWhenWithInline.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! stepOverWhenWithInline.StepOverWhenWithInlinePackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
stepOverWhenWithInline.kt:5
|
||||||
|
stepOverWhenWithInline.kt:8
|
||||||
|
stepOverWhenWithInline.kt:9
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:9
|
||||||
|
stepOverWhenWithInline.kt:7
|
||||||
|
stepOverWhenWithInline.kt:14
|
||||||
|
stepOverWhenWithInline.kt:17
|
||||||
|
stepOverWhenWithInline.kt:18
|
||||||
|
stepOverWhenWithInline.kt:13
|
||||||
|
stepOverWhenWithInline.kt:26
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:26
|
||||||
|
stepOverWhenWithInline.kt:27
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:27
|
||||||
|
stepOverWhenWithInline.kt:25
|
||||||
|
stepOverWhenWithInline.kt:32
|
||||||
|
stepOverWhenWithInline.kt:34
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:34
|
||||||
|
stepOverWhenWithInline.kt:32
|
||||||
|
stepOverWhenWithInline.kt:38
|
||||||
|
stepOverWhenWithInline.kt:43
|
||||||
|
stepOverWhenWithInline.kt:38
|
||||||
|
stepOverWhenWithInline.kt:51
|
||||||
|
stepOverWhenWithInline.kt:52
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:52
|
||||||
|
stepOverWhenWithInline.kt:51
|
||||||
|
stepOverWhenWithInline.kt:58
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:58
|
||||||
|
stepOverWhenWithInline.kt:57
|
||||||
|
stepOverWhenWithInline.kt:64
|
||||||
|
stepOverWhenWithInline.kt:65
|
||||||
|
stepOverWhenWithInline.kt:63
|
||||||
|
stepOverWhenWithInline.kt:76
|
||||||
|
stepOverWhenWithInline.kt:83
|
||||||
|
stepOverWhenWithInline.kt:76
|
||||||
|
stepOverWhenWithInline.kt:75
|
||||||
|
stepOverWhenWithInline.kt:80
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package stepOverIfWithInline
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
//Breakpoint!
|
||||||
|
val prop = 1
|
||||||
|
// False with braces
|
||||||
|
val a = if (1 > 2) {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// False without braces
|
||||||
|
val b = if (1 > 2)
|
||||||
|
foo { test(1) }
|
||||||
|
else
|
||||||
|
foo { test(1) }
|
||||||
|
|
||||||
|
// One line
|
||||||
|
val c = if (1 > 2) foo { test(1) } else foo { test(1) }
|
||||||
|
|
||||||
|
// Else on next line, false
|
||||||
|
val d = if (1 > 2) foo { test(1) }
|
||||||
|
else foo { test(1) }
|
||||||
|
|
||||||
|
// Else on next line, true
|
||||||
|
val e = if (1 < 2) foo { test(1) }
|
||||||
|
else foo { test(1) }
|
||||||
|
|
||||||
|
// Inline function call in condition
|
||||||
|
val f = if (foo { test(1) } > 2) {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun foo(f: () -> Int): Int {
|
||||||
|
val a = 1
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
|
// STEP_OVER: 30
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package stepOverInlineFunctionInReturn
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f(): Int {
|
||||||
|
//Breakpoint!
|
||||||
|
val a = 1
|
||||||
|
return foo {
|
||||||
|
test(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun foo(f: () -> Int): Int {
|
||||||
|
val a = 1
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
|
// STEP_OVER: 4
|
||||||
+3
-1
@@ -27,6 +27,8 @@ fun main(args: Array<String>) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
val b = foo { test(1) }
|
val b = foo { test(1) }
|
||||||
|
|
||||||
|
foo(fun (){ test(1) })
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun foo(f: () -> Unit) {
|
inline fun foo(f: () -> Unit) {
|
||||||
@@ -47,4 +49,4 @@ class A {
|
|||||||
|
|
||||||
fun test(i: Int) = 1
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
// STEP_OVER: 11
|
// STEP_OVER: 13
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package stepOverTryCatchWithInline
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
try {
|
||||||
|
bar()
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
val a = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
//Breakpoint!
|
||||||
|
val prop = 1
|
||||||
|
// Try
|
||||||
|
try {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Many catch clauses
|
||||||
|
try {
|
||||||
|
throw IllegalStateException()
|
||||||
|
}
|
||||||
|
catch(e: IllegalStateException) {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// exception in lambda
|
||||||
|
try {
|
||||||
|
foo { throw IllegalStateException() }
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exception without catch
|
||||||
|
foo { throw IllegalStateException() }
|
||||||
|
val prop2 = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun foo(f: () -> Int): Int {
|
||||||
|
val a = 1
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
|
// STEP_OVER: 30
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package stepOverWhenInReturn
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
whenInReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun whenInReturn(): Int {
|
||||||
|
val a = 1
|
||||||
|
//Breakpoint!
|
||||||
|
return when(a) {
|
||||||
|
1 -> foo { 1 }
|
||||||
|
else -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun foo(f: () -> Int): Int {
|
||||||
|
val a = 1
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
|
// STEP_OVER: 6
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
package stepOverWhenWithInline
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
//Breakpoint!
|
||||||
|
val prop = 1
|
||||||
|
// Break after second
|
||||||
|
val a = when {
|
||||||
|
1 > 2 -> foo { test(1) }
|
||||||
|
2 > 1 -> foo { test(1) }
|
||||||
|
else -> foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val b = when {
|
||||||
|
1 > 2 -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
2 > 1 -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val c = when {
|
||||||
|
foo { test(1) } > 2 -> 1
|
||||||
|
2 > foo { test(1) } -> 2
|
||||||
|
else -> foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// When with expression
|
||||||
|
val a1 = when(prop) {
|
||||||
|
2 -> foo { test(1) }
|
||||||
|
1 -> foo { test(1) }
|
||||||
|
else -> foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val b1 = when(prop) {
|
||||||
|
2 -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break after first
|
||||||
|
val c1 = when(prop) {
|
||||||
|
foo { test(1) } -> 1
|
||||||
|
foo { test(2) } -> 2
|
||||||
|
else -> foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val a2 = when {
|
||||||
|
2 > 1 -> foo { test(1) }
|
||||||
|
1 > 2 -> foo { test(1) }
|
||||||
|
else -> foo { test(1) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val b2 = when {
|
||||||
|
2 > 1 -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
1 > 2 -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
foo { test(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val c2 = when {
|
||||||
|
2 > foo { test(1) } -> 2
|
||||||
|
foo { test(1) } > 2 -> 1
|
||||||
|
else -> foo { test(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun foo(f: () -> Int): Int {
|
||||||
|
val a = 1
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(i: Int) = i
|
||||||
|
|
||||||
|
// STEP_OVER: 50
|
||||||
@@ -343,6 +343,18 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
doStepOverTest(fileName);
|
doStepOverTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stepOverIfWithInline.kt")
|
||||||
|
public void testStepOverIfWithInline() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverIfWithInline.kt");
|
||||||
|
doStepOverTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stepOverInlineFunctionInReturn.kt")
|
||||||
|
public void testStepOverInlineFunctionInReturn() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverInlineFunctionInReturn.kt");
|
||||||
|
doStepOverTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("stepOverInlinedLambda.kt")
|
@TestMetadata("stepOverInlinedLambda.kt")
|
||||||
public void testStepOverInlinedLambda() throws Exception {
|
public void testStepOverInlinedLambda() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverInlinedLambda.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverInlinedLambda.kt");
|
||||||
@@ -360,6 +372,24 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverSimpleFun.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverSimpleFun.kt");
|
||||||
doStepOverTest(fileName);
|
doStepOverTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stepOverTryCatchWithInline.kt")
|
||||||
|
public void testStepOverTryCatchWithInline() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverTryCatchWithInline.kt");
|
||||||
|
doStepOverTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stepOverWhenInReturn.kt")
|
||||||
|
public void testStepOverWhenInReturn() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverWhenInReturn.kt");
|
||||||
|
doStepOverTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stepOverWhenWithInline.kt")
|
||||||
|
public void testStepOverWhenWithInline() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverWhenWithInline.kt");
|
||||||
|
doStepOverTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/debugger/tinyApp/src/stepping/filters")
|
@TestMetadata("idea/testData/debugger/tinyApp/src/stepping/filters")
|
||||||
|
|||||||
Reference in New Issue
Block a user