From 093b1bebb081928c2f9ecffd553116f319215f35 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 14 Mar 2022 11:51:40 +0100 Subject: [PATCH] KAPT+IR: Generate LVT in kapt mode --- .../backend/jvm/codegen/ExpressionCodegen.kt | 47 ++++++------ .../backend/jvm/codegen/FunctionCodegen.kt | 2 +- .../testData/converter/annotations2_ir.txt | 4 +- .../testData/converter/kt25071_ir.txt | 74 ------------------- .../testData/converter/kt27126_ir.txt | 2 +- .../testData/converter/topLevel.kt | 2 - .../testData/converter/topLevel_ir.txt | 73 ++++++++++++++++++ 7 files changed, 103 insertions(+), 101 deletions(-) delete mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/kt25071_ir.txt create mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/topLevel_ir.txt diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index d60edb12e56..646f1e3d025 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -221,29 +221,34 @@ class ExpressionCodegen( fun generate() { mv.visitCode() val startLabel = markNewLabel() - if (irFunction.isMultifileBridge()) { - // Multifile bridges need to have line number 1 to be filtered out by the intellij debugging filters. - mv.visitLineNumber(1, startLabel) - } val info = BlockInfo() - val body = irFunction.body - ?: error("Function has no body: ${irFunction.render()}") - - generateNonNullAssertions() - generateFakeContinuationConstructorIfNeeded() - val result = body.accept(this, info) - // If this function has an expression body, return the result of that expression. - // Otherwise, if it does not end in a return statement, it must be void-returning, - // and an explicit return instruction at the end is still required to pass validation. - if (body !is IrStatementContainer || body.statements.lastOrNull() !is IrReturn) { - // Allow setting a breakpoint on the closing brace of a void-returning function - // without an explicit return, or the `class Something(` line of a primary constructor. - if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) { - irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary) + if (context.state.classBuilderMode.generateBodies) { + if (irFunction.isMultifileBridge()) { + // Multifile bridges need to have line number 1 to be filtered out by the intellij debugging filters. + mv.visitLineNumber(1, startLabel) } - val (returnType, returnIrType) = irFunction.returnAsmAndIrTypes() - result.materializeAt(returnType, returnIrType) - mv.areturn(returnType) + val body = irFunction.body + ?: error("Function has no body: ${irFunction.render()}") + + generateNonNullAssertions() + generateFakeContinuationConstructorIfNeeded() + val result = body.accept(this, info) + // If this function has an expression body, return the result of that expression. + // Otherwise, if it does not end in a return statement, it must be void-returning, + // and an explicit return instruction at the end is still required to pass validation. + if (body !is IrStatementContainer || body.statements.lastOrNull() !is IrReturn) { + // Allow setting a breakpoint on the closing brace of a void-returning function + // without an explicit return, or the `class Something(` line of a primary constructor. + if (irFunction.origin != JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER) { + irFunction.markLineNumber(startOffset = irFunction is IrConstructor && irFunction.isPrimary) + } + val (returnType, returnIrType) = irFunction.returnAsmAndIrTypes() + result.materializeAt(returnType, returnIrType) + mv.areturn(returnType) + } + } else { + mv.aconst(null) + mv.athrow() } val endLabel = markNewLabel() writeLocalVariablesInTable(info, endLabel) diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index b049f805203..773e961b160 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -104,7 +104,7 @@ class FunctionCodegen(private val irFunction: IrFunction, private val classCodeg // `$$forInline` versions of suspend functions have the same bodies as the originals, but with different // name/flags/annotations and with no state machine. val notForInline = irFunction.suspendForInlineToOriginal() - val smap = if (!context.state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) { + val smap = if (flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) { generateAnnotationDefaultValueIfNeeded(methodVisitor) SMAP(listOf()) } else if (notForInline != null) { diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/annotations2_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/annotations2_ir.txt index aa1ef0e356c..16de3f02658 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/annotations2_ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/annotations2_ir.txt @@ -27,12 +27,12 @@ public final class AnnotationsTest { @Anno(value = "top-level-fun") public static final void topLevelFun(@org.jetbrains.annotations.NotNull() @Anno(value = "top-level-fun-receiver") - java.lang.String p0) { + java.lang.String $this$topLevelFun) { } @org.jetbrains.annotations.NotNull() public static final java.lang.String getTopLevelVal(@Anno(value = "top-level-val-receiver") - int p0) { + int $this$topLevelVal) { return null; } diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/kt25071_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/kt25071_ir.txt deleted file mode 100644 index 45e719f40eb..00000000000 --- a/plugins/kapt3/kapt3-compiler/testData/converter/kt25071_ir.txt +++ /dev/null @@ -1,74 +0,0 @@ -package kapt; - -import java.lang.System; - -@kotlin.Metadata() -public final class StaticImport { - private final java.util.Collection x = null; - private final kapt.StaticMethod l = null; - private final kapt.StaticMethod m = null; - private final int y = 0; - - public StaticImport() { - super(); - } - - public final java.util.Collection getX() { - return null; - } - - public final kapt.StaticMethod getL() { - return null; - } - - public final kapt.StaticMethod getM() { - return null; - } - - public final int getY() { - return 0; - } -} - -//////////////////// - -package kapt; - -public class StaticMethod { - - public static StaticMethod of(T t1) { - return new StaticMethod(t1); - } - - public static StaticMethod of(T t1, T t2) { - return new StaticMethod(t1, t2); - } - - public static StaticMethod of2(T t1) { - return new StaticMethod(t1); - } - private final T[] ts; - - private StaticMethod(T... ts) { - this.ts = ts; - } -} - -//////////////////// - -package my.lib; - -import java.lang.System; - -@kotlin.Metadata() -public final class LibKt { - - public LibKt() { - super(); - } - - public static final int func(@org.jetbrains.annotations.NotNull() - java.lang.String p0) { - return 0; - } -} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/kt27126_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/kt27126_ir.txt index 42ea194e593..ab88cb94cce 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/kt27126_ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/kt27126_ir.txt @@ -73,7 +73,7 @@ public abstract class NullableBundleProperty implem super(); } - private final java.lang.String toKey(kotlin.reflect.KProperty p0) { + private final java.lang.String toKey(kotlin.reflect.KProperty $this$toKey) { return null; } diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.kt b/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.kt index 36f7da0de23..4c8ad9aacfa 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR - package test.another annotation class Anno(val value: String) diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/topLevel_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/topLevel_ir.txt new file mode 100644 index 00000000000..757b089b755 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/topLevel_ir.txt @@ -0,0 +1,73 @@ +package test.another; + +import java.lang.System; + +@kotlin.Metadata() +@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) +public abstract @interface Anno { + + public abstract java.lang.String value(); +} + +//////////////////// + +package test.another; + +import java.lang.System; + +@kotlin.Metadata() +public final class TopLevelKt { + + public TopLevelKt() { + super(); + } + private static final int topLevelProperty = 2; + public static final int topLevelConstProperty = 2; + + @org.jetbrains.annotations.Nullable() + public static final java.lang.String topLevelFunction() { + return null; + } + + @org.jetbrains.annotations.Nullable() + public static final >T topLevelGenericFunction() { + return null; + } + + public static final int getTopLevelProperty() { + return 0; + } + + @org.jetbrains.annotations.NotNull() + public static final java.lang.String getTopLevelProperty2() { + return null; + } + + public static final void extensionFunction(@org.jetbrains.annotations.NotNull() + @Anno(value = "rec") + java.lang.String $this$extensionFunction, @org.jetbrains.annotations.NotNull() + @Anno(value = "1") + java.lang.String a, @org.jetbrains.annotations.NotNull() + @Anno(value = "2") + java.lang.String b) { + } + + @org.jetbrains.annotations.NotNull() + public static final java.lang.String getExtensionProperty(@org.jetbrains.annotations.NotNull() + @Anno(value = "propRec") + T $this$extensionProperty) { + return null; + } + + public static final void setExtensionProperty(@org.jetbrains.annotations.NotNull() + @Anno(value = "propRec") + T $this$extensionProperty, @org.jetbrains.annotations.NotNull() + @Anno(value = "setparam") + java.lang.String setParamName) { + } + + @Anno(value = "extpr") + @java.lang.Deprecated() + public static void getExtensionProperty$annotations(java.lang.Object p0) { + } +}