diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index e2e291fb85a..69fd32faf55 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -86,7 +86,7 @@ public class InlineCodegen extends CallGenerator { private final ReifiedTypeInliner reifiedTypeInliner; @Nullable private final TypeParameterMappings typeParameterMappings; - private final boolean isDefaultCompilation; + private final boolean isDefaultMethodCompilation; private LambdaInfo activeLambda; @@ -98,11 +98,11 @@ public class InlineCodegen extends CallGenerator { @NotNull FunctionDescriptor function, @NotNull KtElement callElement, @Nullable TypeParameterMappings typeParameterMappings, - boolean isDefaultCompilation + boolean isDefaultMethodCompilation ) { assert InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function) : "InlineCodegen can inline only inline functions and array constructors: " + function; - this.isDefaultCompilation = isDefaultCompilation; + this.isDefaultMethodCompilation = isDefaultMethodCompilation; this.state = state; this.typeMapper = state.getTypeMapper(); this.codegen = codegen; @@ -148,7 +148,11 @@ public class InlineCodegen extends CallGenerator { try { nodeAndSmap = createMethodNode(callDefault); - endCall(inlineCall(nodeAndSmap)); + if (isDefaultMethodCompilation) { + nodeAndSmap.getNode().accept(new MethodBodyVisitor(codegen.v)); + } else { + endCall(inlineCall(nodeAndSmap)); + } } catch (CompilationException e) { throw e; @@ -277,7 +281,7 @@ public class InlineCodegen extends CallGenerator { InliningContext info = new RootInliningContext( expressionMap, state, codegen.getInlineNameGenerator().subGenerator(jvmSignature.getAsmMethod().getName()), - codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings, isDefaultCompilation, + codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings, AnnotationUtilKt.hasInlineOnlyAnnotation(functionDescriptor) ); @@ -678,6 +682,11 @@ public class InlineCodegen extends CallGenerator { @NotNull Type parameterType, @NotNull StackValue value ) { + if (isDefaultMethodCompilation) { + //original method would be inlined directly into default impl body without any inline magic + //so we no need to load variables on stack to further method call + return; + } putValueIfNeeded(parameterType, value, -1); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java index 9f214c2a5a0..aeb0bab3360 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java @@ -288,8 +288,7 @@ public class MethodInliner { super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf); } } - else if (ReifiedTypeInliner.isNeedClassReificationMarker(new MethodInsnNode(opcode, owner, name, desc, false)) && - !isDefaultCompilation()) { + else if (ReifiedTypeInliner.isNeedClassReificationMarker(new MethodInsnNode(opcode, owner, name, desc, false))) { // we will put it if needed in anew processing } else { @@ -378,7 +377,6 @@ public class MethodInliner { ) { if (isInliningLambda || GENERATE_DEBUG_INFO) { String varSuffix = inliningContext.isRoot() && - !isDefaultCompilation() && !InlineCodegenUtil.isFakeLocalVariableForInline(name) ? INLINE_FUN_VAR_SUFFIX : ""; String varName = !varSuffix.isEmpty() && name.equals("this") ? name + "_" : name; @@ -446,7 +444,7 @@ public class MethodInliner { if (frame != null) { if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) { - awaitClassReification = !isDefaultCompilation(); + awaitClassReification = true; } else if (cur.getType() == AbstractInsnNode.METHOD_INSN) { if (InlineCodegenUtil.isFinallyStart(cur)) { @@ -809,8 +807,4 @@ public class MethodInliner { } } - - private boolean isDefaultCompilation() { - return inliningContext.isRoot() && ((RootInliningContext) inliningContext).isDefaultCompilation; - } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java index cc4a0f7b4a7..9543800a5c7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java @@ -28,7 +28,6 @@ public class RootInliningContext extends InliningContext { public final CodegenContext startContext; private final InlineCallSiteInfo inlineCallSiteInfo; public final TypeParameterMappings typeParameterMappings; - public final boolean isDefaultCompilation; public final boolean skipSmap; public final KtElement callElement; @@ -41,7 +40,6 @@ public class RootInliningContext extends InliningContext { @NotNull InlineCallSiteInfo classNameToInline, @NotNull ReifiedTypeInliner inliner, @Nullable TypeParameterMappings typeParameterMappings, - boolean isDefaultCompilation, boolean skipSmap ) { super(null, map, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), inliner, false, false); @@ -49,7 +47,6 @@ public class RootInliningContext extends InliningContext { this.startContext = startContext; this.inlineCallSiteInfo = classNameToInline; this.typeParameterMappings = typeParameterMappings; - this.isDefaultCompilation = isDefaultCompilation; this.skipSmap = skipSmap; } diff --git a/idea/testData/debugger/tinyApp/outs/remappedParameterInInline.out b/idea/testData/debugger/tinyApp/outs/remappedParameterInInline.out new file mode 100644 index 00000000000..7b21384b864 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/remappedParameterInInline.out @@ -0,0 +1,8 @@ +LineBreakpoint created at remappedParameterInInline.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! remappedParameterInInline.RemappedParameterInInlineKt +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +remappedParameterInInline.kt:11 +Compile bytecode for p +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/remappedParameterInInline.kt b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/remappedParameterInInline.kt new file mode 100644 index 00000000000..2c6dd1265c8 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/remappedParameterInInline.kt @@ -0,0 +1,19 @@ +package remappedParameterInInline + +inline fun watch(p: String, f: (String) -> Int) { + f(p) +} + +inline fun inlineDefault(p: Int = 1, f: (Int) -> Unit) { + // EXPRESSION: p + // RESULT: 1: I + //Breakpoint! + f(p) +} + +fun main(args: Array) { + val local = "mno" + watch(local) { it.length } + + inlineDefault { it } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java index eee6ee31f9f..4592bf1841b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -790,6 +790,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat doMultipleBreakpointsTest(fileName); } + @TestMetadata("remappedParameterInInline.kt") + public void testRemappedParameterInInline() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/remappedParameterInInline.kt"); + doMultipleBreakpointsTest(fileName); + } + @TestMetadata("whenEntry.kt") public void testWhenEntry() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/whenEntry.kt");