diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index efc9006a3ee..be4d5292cbd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.backend.jvm.codegen.IrExpressionLambda +import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClosureCodegen import org.jetbrains.kotlin.codegen.StackValue @@ -368,7 +369,14 @@ class MethodInliner( ) val transformationVisitor = object : MethodVisitor(API, transformedNode) { - private val GENERATE_DEBUG_INFO = GENERATE_SMAP && inlineOnlySmapSkipper == null + /* + Ignore simple @InlineOnly functions such as 'error()' or 'assert()' without lambda parameters, + as we likely to want to have a line number from the call site in a stack trace. + */ + private val GENERATE_LINE_NUMBERS = GENERATE_SMAP && (inlineOnlySmapSkipper == null || run { + val callableDescriptor = inliningContext.root.sourceCompilerForInline.callableDescriptor + callableDescriptor != null && callableDescriptor.valueParameters.any { it.type.isFunctionType } + }) private val isInliningLambda = nodeRemapper.isInsideInliningLambda @@ -400,7 +408,7 @@ class MethodInliner( } override fun visitLineNumber(line: Int, start: Label) { - if (isInliningLambda || GENERATE_DEBUG_INFO) { + if (isInliningLambda || GENERATE_LINE_NUMBERS) { super.visitLineNumber(line, start) } } @@ -428,7 +436,7 @@ class MethodInliner( override fun visitLocalVariable( name: String, desc: String, signature: String?, start: Label, end: Label, index: Int ) { - if (isInliningLambda || GENERATE_DEBUG_INFO) { + if (isInliningLambda || (GENERATE_SMAP && inlineOnlySmapSkipper == null)) { val varSuffix = if (inliningContext.isRoot && !isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else "" val varName = if (!varSuffix.isEmpty() && name == "this") name + "_" else name super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index)) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt index 115bf9de262..9f73ff45e33 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -46,6 +46,8 @@ interface SourceCompilerForInline { val callElement: Any + val callableDescriptor: CallableDescriptor? + val lookupLocation: LookupLocation val callElementText: String @@ -99,6 +101,8 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid override val lookupLocation = KotlinLookupLocation(callElement) + override val callableDescriptor: CallableDescriptor? + get() = (this.context as? MethodContext)?.functionDescriptor override val callElementText by lazy { callElement.text diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index 7b6b9644e1a..2a8f9acf08f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.SourceInfo import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation @@ -50,6 +51,9 @@ class IrSourceCompilerForInline( override val callElementText: String get() = callElement.toString() + override val callableDescriptor: CallableDescriptor + get() = callElement.descriptor + override val callsiteFile: PsiFile? get() = TODO("not implemented") diff --git a/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault.kt b/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault.kt index 5641fb198b2..77ab330c0e0 100644 --- a/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault.kt +++ b/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault.kt @@ -87,22 +87,26 @@ Kotlin *F + 1 2.kt _2Kt -+ 2 1.kt -test/_1Kt ++ 2 Standard.kt +kotlin/StandardKt__StandardKt + 3 1.kt +test/_1Kt ++ 4 1.kt test/_1Kt$lParams$1 *L 1#1,10:1 -31#2,5:11 -29#2:17 -32#3:16 +34#2,4:11 +31#3,5:15 +29#3:21 +32#4:20 *E *S KotlinDebug *F + 1 2.kt _2Kt *L -5#1,5:11 -5#1:17 -5#1:16 +5#1,4:11 +5#1,5:15 +5#1:21 +5#1:20 *E \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault2.kt b/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault2.kt index 376d09d84fe..de183eeea8b 100644 --- a/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault2.kt +++ b/compiler/testData/codegen/boxInline/smap/defaultLambda/inlinInDefault2.kt @@ -123,26 +123,30 @@ Kotlin *F + 1 2.kt _2Kt -+ 2 1.kt -test/_1Kt ++ 2 Standard.kt +kotlin/StandardKt__StandardKt + 3 1.kt +test/_1Kt ++ 4 1.kt test/_1Kt$lParams$1 *L 1#1,10:1 -31#2:11 -70#2,2:12 -29#2:15 -50#3:14 -68#3:16 +34#2,4:11 +31#3:15 +70#3,2:16 +29#3:19 +50#4:18 +68#4:20 *E *S KotlinDebug *F + 1 2.kt _2Kt *L -5#1:11 -5#1,2:12 +5#1,4:11 5#1:15 -5#1:14 -5#1:16 +5#1,2:16 +5#1:19 +5#1:18 +5#1:20 *E \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/smap/defaultLambda/inlineAnonymousInDefault2.kt b/compiler/testData/codegen/boxInline/smap/defaultLambda/inlineAnonymousInDefault2.kt index 482b8b2b318..4e81a01a0ff 100644 --- a/compiler/testData/codegen/boxInline/smap/defaultLambda/inlineAnonymousInDefault2.kt +++ b/compiler/testData/codegen/boxInline/smap/defaultLambda/inlineAnonymousInDefault2.kt @@ -112,24 +112,28 @@ Kotlin *F + 1 2.kt _2Kt -+ 2 1.kt -test/_1Kt ++ 2 Standard.kt +kotlin/StandardKt__StandardKt + 3 1.kt +test/_1Kt ++ 4 1.kt test/_1Kt$lParams$1 *L 1#1,10:1 -31#2,5:11 -29#2:17 -32#3:16 +34#2,4:11 +31#3,5:15 +29#3:21 +32#4:20 *E *S KotlinDebug *F + 1 2.kt _2Kt *L -5#1,5:11 -5#1:17 -5#1:16 +5#1,4:11 +5#1,5:15 +5#1:21 +5#1:20 *E // FILE: 2.smap-separate-compilation @@ -140,24 +144,28 @@ Kotlin *F + 1 2.kt _2Kt -+ 2 1.kt -test/_1Kt ++ 2 Standard.kt +kotlin/StandardKt__StandardKt + 3 1.kt +test/_1Kt ++ 4 1.kt test/_1Kt$lParams$1 *L 1#1,10:1 -31#2,5:11 -29#2:17 -32#3:16 +34#2,4:11 +31#3,5:15 +29#3:21 +32#4:20 *E *S KotlinDebug *F + 1 2.kt _2Kt *L -5#1,5:11 -5#1:17 -5#1:16 +5#1,4:11 +5#1,5:15 +5#1:21 +5#1:20 *E SMAP diff --git a/compiler/testData/codegen/boxInline/smap/defaultLambda/kt21827.kt b/compiler/testData/codegen/boxInline/smap/defaultLambda/kt21827.kt index cefd819aeb6..409f714f259 100644 --- a/compiler/testData/codegen/boxInline/smap/defaultLambda/kt21827.kt +++ b/compiler/testData/codegen/boxInline/smap/defaultLambda/kt21827.kt @@ -76,20 +76,24 @@ Kotlin *F + 1 2.kt _2Kt -+ 2 1.kt -test/_1Kt ++ 2 Standard.kt +kotlin/StandardKt__StandardKt + 3 1.kt +test/_1Kt ++ 4 1.kt test/_1Kt$lParams$1 *L 1#1,10:1 -30#2,5:11 -31#3:16 +34#2,4:11 +30#3,5:15 +31#4:20 *E *S KotlinDebug *F + 1 2.kt _2Kt *L -5#1,5:11 -5#1:16 +5#1,4:11 +5#1,5:15 +5#1:20 *E \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmap.kt b/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmap.kt index 8ee31295455..e8ca584b863 100644 --- a/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmap.kt +++ b/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmap.kt @@ -20,6 +20,16 @@ Kotlin *F + 1 2.kt _2Kt ++ 2 _Strings.kt +kotlin/text/StringsKt___StringsKt *L 1#1,7:1 +498#2:8 +*E +*S KotlinDebug +*F ++ 1 2.kt +_2Kt +*L +4#1:8 *E diff --git a/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmapWithProperty.kt b/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmapWithProperty.kt index c749d0b31cf..a0f96bffae9 100644 --- a/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmapWithProperty.kt +++ b/compiler/testData/codegen/boxInline/smap/inlineOnly/noSmapWithProperty.kt @@ -25,6 +25,16 @@ Kotlin *F + 1 2.kt _2Kt ++ 2 1.kt +test/_1Kt *L 1#1,8:1 +10#2:9 +*E +*S KotlinDebug +*F ++ 1 2.kt +_2Kt +*L +5#1:9 *E diff --git a/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.kt b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.kt new file mode 100644 index 00000000000..5531e023ab3 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.kt @@ -0,0 +1,49 @@ +package inlineOnlyLambdas + +class Test +fun test() {} + +fun main(args: Array) { + val data = Test() + + //Breakpoint! (lambdaOrdinal = 1) + data.onelinerApply { test() } + + //Breakpoint! (lambdaOrdinal = 1) + data.multiLineApply { test() } + + //Breakpoint! (lambdaOrdinal = 1) + data.onelinerApply2 { test() } + + //Breakpoint! (lambdaOrdinal = 1) + data.multiLineApply2 { test() } + + //Breakpoint! + data.withoutLambdaParams() +} + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +inline fun T.withoutLambdaParams(): T { + return this +} + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +inline fun T.onelinerApply(block: T.() -> Unit): T { block(); return this } + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +inline fun T.multiLineApply(block: T.() -> Unit): T { + block(); + return this +} + +inline fun T.onelinerApply2(block: T.() -> Unit): T { block(); return this } + +inline fun T.multiLineApply2(block: T.() -> Unit): T { + block(); + return this +} + +// RESUME: 5 \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.out b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.out new file mode 100644 index 00000000000..fbd9acbed3f --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.out @@ -0,0 +1,15 @@ +LineBreakpoint created at inlineOnlyLambdas.kt:10 lambdaOrdinal = 1 +LineBreakpoint created at inlineOnlyLambdas.kt:13 lambdaOrdinal = 1 +LineBreakpoint created at inlineOnlyLambdas.kt:16 lambdaOrdinal = 1 +LineBreakpoint created at inlineOnlyLambdas.kt:19 lambdaOrdinal = 1 +LineBreakpoint created at inlineOnlyLambdas.kt:22 +Run Java +Connected to the target VM +inlineOnlyLambdas.kt:10 +inlineOnlyLambdas.kt:13 +inlineOnlyLambdas.kt:16 +inlineOnlyLambdas.kt:19 +inlineOnlyLambdas.kt:22 +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.kt b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.kt new file mode 100644 index 00000000000..fd142227e65 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.kt @@ -0,0 +1,38 @@ +package inlineOnlyLambdasStepping + +class Test +fun test() {} + +fun main(args: Array) { + val data = Test() + + // STEP_OVER: 2 + //Breakpoint! (lambdaOrdinal = 1) + data.onelinerApply { test() } + + data.multiLineApply { test() } + + // STEP_OVER: 3 + //Breakpoint! (lambdaOrdinal = 1) + data.onelinerApply2 { test() } + + data.multiLineApply2 { test() } +} + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +inline fun T.onelinerApply(block: T.() -> Unit): T { block(); return this } + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +inline fun T.multiLineApply(block: T.() -> Unit): T { + block(); + return this +} + +inline fun T.onelinerApply2(block: T.() -> Unit): T { block(); return this } + +inline fun T.multiLineApply2(block: T.() -> Unit): T { + block(); + return this +} \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.out b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.out new file mode 100644 index 00000000000..57572118ad1 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.out @@ -0,0 +1,13 @@ +LineBreakpoint created at inlineOnlyLambdasStepping.kt:11 lambdaOrdinal = 1 +LineBreakpoint created at inlineOnlyLambdasStepping.kt:17 lambdaOrdinal = 1 +Run Java +Connected to the target VM +inlineOnlyLambdasStepping.kt:11 +inlineOnlyLambdasStepping.kt:13 +inlineOnlyLambdasStepping.kt:17 +inlineOnlyLambdasStepping.kt:17 +inlineOnlyLambdasStepping.kt:19 +inlineOnlyLambdasStepping.kt:20 +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.kt b/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.kt index 737db2ba756..e173c7b6c4d 100644 --- a/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.kt +++ b/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.kt @@ -27,5 +27,5 @@ inline fun forEach(s: () -> Unit) { } } -// STEP_INTO: 9 +// STEP_INTO: 15 // TRACING_FILTERS_ENABLED: false \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.out b/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.out index edb5a34b1b8..414710bf588 100644 --- a/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.out +++ b/idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.out @@ -3,14 +3,20 @@ Run Java Connected to the target VM inlineOnly.kt:5 inlineOnly.kt:7 -inlineOnly.kt:13 -inlineOnly.kt:14 +inlineOnly.kt:25 +inlineOnly.kt:26 inlineOnly.kt:7 inlineOnly.kt:13 inlineOnly.kt:14 inlineOnly.kt:7 -inlineOnly.kt:9 -PrintStream.!EXT! +inlineOnly.kt:25 +inlineOnly.kt:26 +inlineOnly.kt:7 +inlineOnly.kt:13 +inlineOnly.kt:14 +inlineOnly.kt:7 +inlineOnly.kt:25 +inlineOnly.kt:28 Disconnected from the target VM Process finished with exit code 0 diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java index 01e30f44c64..f781ee0f1de 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java @@ -1218,6 +1218,18 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest { doCustomTest(fileName); } + @TestMetadata("inlineOnlyLambdas.kt") + public void testInlineOnlyLambdas() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdas.kt"); + doCustomTest(fileName); + } + + @TestMetadata("inlineOnlyLambdasStepping.kt") + public void testInlineOnlyLambdasStepping() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/inlineOnlyLambdasStepping.kt"); + doCustomTest(fileName); + } + @TestMetadata("inlineProperties.kt") public void testInlineProperties() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/inlineProperties.kt");