Debugger: fix step over inside inline function (do not step into function literal argument)
This commit is contained in:
@@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
### IDE
|
### IDE
|
||||||
|
|
||||||
|
#### Debugger
|
||||||
|
|
||||||
|
- Do not step into inline lambda argument during step over inside inline function body
|
||||||
|
|
||||||
## 1.0.2
|
## 1.0.2
|
||||||
|
|
||||||
### Compiler
|
### Compiler
|
||||||
|
|||||||
@@ -20,12 +20,8 @@ import com.intellij.debugger.engine.DebugProcessImpl;
|
|||||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
|
||||||
import com.intellij.openapi.util.Computable;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.xdebugger.impl.XSourcePositionImpl;
|
import kotlin.ranges.IntRange;
|
||||||
import kotlin.*;
|
|
||||||
import kotlin.ranges.*;
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
import org.jetbrains.kotlin.psi.KtFunction;
|
import org.jetbrains.kotlin.psi.KtFunction;
|
||||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
|
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
|
||||||
@@ -47,36 +43,29 @@ public class DebuggerSteppingHelper {
|
|||||||
return debugProcess.new ResumeCommand(suspendContext) {
|
return debugProcess.new ResumeCommand(suspendContext) {
|
||||||
@Override
|
@Override
|
||||||
public void contextAction() {
|
public void contextAction() {
|
||||||
final StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy();
|
try {
|
||||||
if (frameProxy != null) {
|
StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy();
|
||||||
DebugProcessImpl.ResumeCommand runToCursorCommand = ApplicationManager.getApplication().runReadAction(new Computable<DebugProcessImpl.ResumeCommand>() {
|
if (frameProxy != null) {
|
||||||
@Override
|
Action action = KotlinSteppingCommandProviderKt.getStepOverPosition(
|
||||||
public DebugProcessImpl.ResumeCommand compute() {
|
frameProxy.location(),
|
||||||
try {
|
file,
|
||||||
XSourcePositionImpl position = KotlinSteppingCommandProviderKt.getStepOverPosition(
|
linesRange,
|
||||||
frameProxy.location(),
|
inlineArguments,
|
||||||
file,
|
additionalElementsToSkip
|
||||||
linesRange,
|
);
|
||||||
inlineArguments,
|
|
||||||
additionalElementsToSkip
|
DebugProcessImpl.ResumeCommand command = action.createCommand(debugProcess, suspendContext, ignoreBreakpoints);
|
||||||
);
|
|
||||||
if (position != null) {
|
if (command != null) {
|
||||||
return debugProcess.createRunToCursorCommand(suspendContext, position, ignoreBreakpoints);
|
command.contextAction();
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
catch (EvaluateException ignored) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (runToCursorCommand != null) {
|
|
||||||
runToCursorCommand.contextAction();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debugProcess.createStepOutCommand(suspendContext).contextAction();
|
debugProcess.createStepOutCommand(suspendContext).contextAction();
|
||||||
|
}
|
||||||
|
catch (EvaluateException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -91,35 +80,29 @@ public class DebuggerSteppingHelper {
|
|||||||
return debugProcess.new ResumeCommand(suspendContext) {
|
return debugProcess.new ResumeCommand(suspendContext) {
|
||||||
@Override
|
@Override
|
||||||
public void contextAction() {
|
public void contextAction() {
|
||||||
final StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy();
|
try {
|
||||||
if (frameProxy != null) {
|
StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy();
|
||||||
DebugProcessImpl.ResumeCommand runToCursorCommand = ApplicationManager.getApplication().runReadAction(new Computable<DebugProcessImpl.ResumeCommand>() {
|
if (frameProxy != null) {
|
||||||
@Override
|
Action action = KotlinSteppingCommandProviderKt.getStepOutPosition(
|
||||||
public DebugProcessImpl.ResumeCommand compute() {
|
frameProxy.location(),
|
||||||
try {
|
suspendContext,
|
||||||
XSourcePositionImpl position = KotlinSteppingCommandProviderKt.getStepOutPosition(
|
inlineFunctions,
|
||||||
frameProxy.location(),
|
inlineArgument
|
||||||
suspendContext,
|
);
|
||||||
inlineFunctions,
|
|
||||||
inlineArgument
|
DebugProcessImpl.ResumeCommand command = action.createCommand(debugProcess, suspendContext, ignoreBreakpoints);
|
||||||
);
|
|
||||||
if (position != null) {
|
if (command != null) {
|
||||||
return debugProcess.createRunToCursorCommand(suspendContext, position, ignoreBreakpoints);
|
command.contextAction();
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
catch (EvaluateException ignored) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (runToCursorCommand != null) {
|
|
||||||
runToCursorCommand.contextAction();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debugProcess.createStepOverCommand(suspendContext, ignoreBreakpoints).contextAction();
|
debugProcess.createStepOverCommand(suspendContext, ignoreBreakpoints).contextAction();
|
||||||
|
}
|
||||||
|
catch (EvaluateException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-40
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.idea.refactoring.getLineEndOffset
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
|
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
|
||||||
import org.jetbrains.kotlin.idea.refactoring.getLineStartOffset
|
import org.jetbrains.kotlin.idea.refactoring.getLineStartOffset
|
||||||
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
@@ -78,22 +79,31 @@ class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
|||||||
|
|
||||||
val linesRange = startLineNumber + 1..endLineNumber + 1
|
val linesRange = startLineNumber + 1..endLineNumber + 1
|
||||||
|
|
||||||
val inlineFunctionCalls = getInlineFunctionCallsIfAny(sourcePosition)
|
val inlineArgumentsToSkip = getElementsToSkip(containingFunction as KtNamedFunction, sourcePosition) ?: return null
|
||||||
if (inlineFunctionCalls.isEmpty()) return null
|
|
||||||
|
|
||||||
val inlineArguments = getInlineArgumentsIfAny(inlineFunctionCalls)
|
|
||||||
|
|
||||||
if (inlineArguments.any { it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inlineArguments.isEmpty() && inlineFunctionCalls.any { it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val additionalElementsToSkip = sourcePosition.elementAt.getAdditionalElementsToSkip()
|
val additionalElementsToSkip = sourcePosition.elementAt.getAdditionalElementsToSkip()
|
||||||
|
|
||||||
return DebuggerSteppingHelper.createStepOverCommand(suspendContext, ignoreBreakpoints, file, linesRange, inlineArguments, additionalElementsToSkip)
|
return DebuggerSteppingHelper.createStepOverCommand(suspendContext, ignoreBreakpoints, file, linesRange, inlineArgumentsToSkip, additionalElementsToSkip)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getElementsToSkip(containingFunction: KtNamedFunction, sourcePosition: SourcePosition): List<KtFunction>? {
|
||||||
|
val inlineFunctionCalls = getInlineFunctionCallsIfAny(sourcePosition)
|
||||||
|
if (!inlineFunctionCalls.isEmpty()) {
|
||||||
|
val inlineArguments = getInlineArgumentsIfAny(inlineFunctionCalls)
|
||||||
|
if (inlineArguments.isNotEmpty() && inlineArguments.all { !it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
||||||
|
return inlineArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inlineArguments.isEmpty() && inlineFunctionCalls.all { !it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InlineUtil.isInline(containingFunction.resolveToDescriptor())) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PsiElement.getAdditionalElementsToSkip(): List<PsiElement> {
|
private fun PsiElement.getAdditionalElementsToSkip(): List<PsiElement> {
|
||||||
@@ -287,14 +297,36 @@ class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class Action(val position: XSourcePositionImpl?) {
|
||||||
|
class STEP_OVER: Action(null)
|
||||||
|
class STEP_OUT: Action(null)
|
||||||
|
class RUN_TO_CURSOR(position: XSourcePositionImpl): Action(position)
|
||||||
|
|
||||||
|
fun createCommand(
|
||||||
|
debugProcess: DebugProcessImpl,
|
||||||
|
suspendContext: SuspendContextImpl,
|
||||||
|
ignoreBreakpoints: Boolean
|
||||||
|
): DebugProcessImpl.ResumeCommand? {
|
||||||
|
return when (this) {
|
||||||
|
is Action.RUN_TO_CURSOR -> {
|
||||||
|
runReadAction {
|
||||||
|
debugProcess.createRunToCursorCommand(suspendContext, position!!, ignoreBreakpoints)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Action.STEP_OUT -> debugProcess.createStepOutCommand(suspendContext)
|
||||||
|
is Action.STEP_OVER -> debugProcess.createStepOverCommand(suspendContext, ignoreBreakpoints)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getStepOverPosition(
|
fun getStepOverPosition(
|
||||||
location: Location,
|
location: Location,
|
||||||
file: KtFile,
|
file: KtFile,
|
||||||
range: IntRange,
|
range: IntRange,
|
||||||
inlinedArguments: List<KtElement>,
|
inlinedArguments: List<KtElement>,
|
||||||
elementsToSkip: List<PsiElement>
|
elementsToSkip: List<PsiElement>
|
||||||
): XSourcePositionImpl? {
|
): Action {
|
||||||
val computedReferenceType = location.declaringType() ?: return null
|
val computedReferenceType = location.declaringType() ?: return Action.STEP_OVER()
|
||||||
|
|
||||||
fun isLocationSuitable(nextLocation: Location): Boolean {
|
fun isLocationSuitable(nextLocation: Location): Boolean {
|
||||||
if (nextLocation.method() != location.method() || nextLocation.lineNumber() !in range) {
|
if (nextLocation.method() != location.method() || nextLocation.lineNumber() !in range) {
|
||||||
@@ -316,17 +348,28 @@ fun getStepOverPosition(
|
|||||||
.dropWhile { it.lineNumber() == location.lineNumber() }
|
.dropWhile { it.lineNumber() == location.lineNumber() }
|
||||||
|
|
||||||
for (locationAtLine in locations) {
|
for (locationAtLine in locations) {
|
||||||
val lineNumber = locationAtLine.lineNumber()
|
val xPosition = runReadAction l@ {
|
||||||
val lineStartOffset = file.getLineStartOffset(lineNumber - 1) ?: continue
|
val lineNumber = locationAtLine.lineNumber()
|
||||||
if (inlinedArguments.any { it.textRange.contains(lineStartOffset) }) continue
|
val lineStartOffset = file.getLineStartOffset(lineNumber - 1) ?: return@l null
|
||||||
if (elementsToSkip.any { it.textRange.contains(lineStartOffset) }) continue
|
if (inlinedArguments.any { it.textRange.contains(lineStartOffset) }) return@l null
|
||||||
|
if (elementsToSkip.any { it.textRange.contains(lineStartOffset) }) return@l null
|
||||||
|
|
||||||
val elementAt = file.findElementAt(lineStartOffset) ?: continue
|
if (locationAtLine.lineNumber() == location.lineNumber()) return@l null
|
||||||
|
|
||||||
return XSourcePositionImpl.createByElement(elementAt) ?: return null
|
val elementAt = file.findElementAt(lineStartOffset) ?: return@l null
|
||||||
|
XSourcePositionImpl.createByElement(elementAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xPosition != null) {
|
||||||
|
return Action.RUN_TO_CURSOR(xPosition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
if (locations.isNotEmpty()) {
|
||||||
|
return Action.STEP_OUT()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Action.STEP_OVER()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStepOutPosition(
|
fun getStepOutPosition(
|
||||||
@@ -334,8 +377,8 @@ fun getStepOutPosition(
|
|||||||
suspendContext: SuspendContextImpl,
|
suspendContext: SuspendContextImpl,
|
||||||
inlineFunctions: List<KtNamedFunction>,
|
inlineFunctions: List<KtNamedFunction>,
|
||||||
inlinedArgument: KtFunctionLiteral?
|
inlinedArgument: KtFunctionLiteral?
|
||||||
): XSourcePositionImpl? {
|
): Action {
|
||||||
val computedReferenceType = location.declaringType() ?: return null
|
val computedReferenceType = location.declaringType() ?: return Action.STEP_OUT()
|
||||||
|
|
||||||
val locations = computedReferenceType.allLineLocations()
|
val locations = computedReferenceType.allLineLocations()
|
||||||
val nextLineLocations = locations
|
val nextLineLocations = locations
|
||||||
@@ -345,14 +388,16 @@ fun getStepOutPosition(
|
|||||||
.dropWhile { it.lineNumber() == location.lineNumber() }
|
.dropWhile { it.lineNumber() == location.lineNumber() }
|
||||||
|
|
||||||
if (inlineFunctions.isNotEmpty()) {
|
if (inlineFunctions.isNotEmpty()) {
|
||||||
return suspendContext.getXPositionForStepOutFromInlineFunction(nextLineLocations, inlineFunctions) ?: return null
|
val position = suspendContext.getXPositionForStepOutFromInlineFunction(nextLineLocations, inlineFunctions)
|
||||||
|
return position?.let { Action.RUN_TO_CURSOR(it) } ?: Action.STEP_OVER()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlinedArgument != null) {
|
if (inlinedArgument != null) {
|
||||||
return suspendContext.getXPositionForStepOutFromInlinedArgument(nextLineLocations, inlinedArgument) ?: return null
|
val position = suspendContext.getXPositionForStepOutFromInlinedArgument(nextLineLocations, inlinedArgument)
|
||||||
|
return position?.let { Action.RUN_TO_CURSOR(it) } ?: Action.STEP_OVER()
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return Action.STEP_OVER()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SuspendContextImpl.getXPositionForStepOutFromInlineFunction(
|
private fun SuspendContextImpl.getXPositionForStepOutFromInlineFunction(
|
||||||
@@ -384,20 +429,25 @@ private fun SuspendContextImpl.getNextPositionWithFilter(
|
|||||||
skip: (Int, PsiElement) -> Boolean
|
skip: (Int, PsiElement) -> Boolean
|
||||||
): XSourcePositionImpl? {
|
): XSourcePositionImpl? {
|
||||||
for (location in locations) {
|
for (location in locations) {
|
||||||
val sourcePosition = try {
|
val position = runReadAction l@ {
|
||||||
this.debugProcess.positionManager.getSourcePosition(location)
|
val sourcePosition = try {
|
||||||
|
this.debugProcess.positionManager.getSourcePosition(location)
|
||||||
|
}
|
||||||
|
catch(e: NoDataException) {
|
||||||
|
null
|
||||||
|
} ?: return@l null
|
||||||
|
|
||||||
|
val file = sourcePosition.file as? KtFile ?: return@l null
|
||||||
|
val elementAt = sourcePosition.elementAt ?: return@l null
|
||||||
|
val currentLine = location.lineNumber() - 1
|
||||||
|
val lineStartOffset = file.getLineStartOffset(currentLine) ?: return@l null
|
||||||
|
if (skip(lineStartOffset, elementAt)) return@l null
|
||||||
|
|
||||||
|
XSourcePositionImpl.createByElement(elementAt)
|
||||||
|
}
|
||||||
|
if (position != null) {
|
||||||
|
return position
|
||||||
}
|
}
|
||||||
catch(e: NoDataException) {
|
|
||||||
null
|
|
||||||
} ?: continue
|
|
||||||
|
|
||||||
val file = sourcePosition.file as? KtFile ?: continue
|
|
||||||
val elementAt = sourcePosition.elementAt ?: continue
|
|
||||||
val currentLine = location.lineNumber() - 1
|
|
||||||
val lineStartOffset = file.getLineStartOffset(currentLine) ?: continue
|
|
||||||
if (skip(lineStartOffset, elementAt)) continue
|
|
||||||
|
|
||||||
return XSourcePositionImpl.createByElement(elementAt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ stepOverIfWithInline.kt:24
|
|||||||
stepOverIfWithInline.kt:28
|
stepOverIfWithInline.kt:28
|
||||||
stepOverIfWithInline.kt:46
|
stepOverIfWithInline.kt:46
|
||||||
stepOverIfWithInline.kt:28
|
stepOverIfWithInline.kt:28
|
||||||
stepOverIfWithInline.kt:28
|
|
||||||
stepOverIfWithInline.kt:32
|
stepOverIfWithInline.kt:32
|
||||||
stepOverIfWithInline.kt:46
|
stepOverIfWithInline.kt:46
|
||||||
stepOverIfWithInline.kt:32
|
stepOverIfWithInline.kt:32
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
LineBreakpoint created at stepOverInsideInlineFun.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! stepOverInsideInlineFun.StepOverInsideInlineFunKt
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
stepOverInsideInlineFun.kt:11
|
||||||
|
stepOverInsideInlineFun.kt:12
|
||||||
|
stepOverInsideInlineFun.kt:13
|
||||||
|
stepOverInsideInlineFun.kt:7
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -17,6 +17,9 @@ stepOverTryCatchWithInline.kt:36
|
|||||||
stepOverTryCatchWithInline.kt:38
|
stepOverTryCatchWithInline.kt:38
|
||||||
stepOverTryCatchWithInline.kt:39
|
stepOverTryCatchWithInline.kt:39
|
||||||
stepOverTryCatchWithInline.kt:43
|
stepOverTryCatchWithInline.kt:43
|
||||||
|
stepOverTryCatchWithInline.kt:48
|
||||||
|
stepOverTryCatchWithInline.kt:43
|
||||||
|
stepOverTryCatchWithInline.kt:7
|
||||||
stepOverTryCatchWithInline.kt:8
|
stepOverTryCatchWithInline.kt:8
|
||||||
stepOverTryCatchWithInline.kt:10
|
stepOverTryCatchWithInline.kt:10
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package stepOverInsideInlineFun
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
bar {
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun bar(f: (Int) -> Unit) {
|
||||||
|
//Breakpoint!
|
||||||
|
val a = 1
|
||||||
|
val f = f(1)
|
||||||
|
val c = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP_OVER: 3
|
||||||
+1
-1
@@ -51,4 +51,4 @@ inline fun foo(f: () -> Int): Int {
|
|||||||
|
|
||||||
fun test(i: Int) = 1
|
fun test(i: Int) = 1
|
||||||
|
|
||||||
// STEP_OVER: 19
|
// STEP_OVER: 20
|
||||||
@@ -415,6 +415,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
doStepOverTest(fileName);
|
doStepOverTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stepOverInsideInlineFun.kt")
|
||||||
|
public void testStepOverInsideInlineFun() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverInsideInlineFun.kt");
|
||||||
|
doStepOverTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("stepOverReifiedParam.kt")
|
@TestMetadata("stepOverReifiedParam.kt")
|
||||||
public void testStepOverReifiedParam() throws Exception {
|
public void testStepOverReifiedParam() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverReifiedParam.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverReifiedParam.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user