From 4a91957ff004dcb7023c342bba3040b5a0281d1a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 28 Dec 2022 23:27:23 +0100 Subject: [PATCH] Kapt+JVM_IR: fix "correct error types" mode for delegated properties Use the property as PSI element origin for delegated property accessors and field in JVM IR as it is done in the old JVM backend. Otherwise kapt "correct error types" mode can't find the property type and thus cannot succeed in "resolving" it, which led to java.lang.Object being used as a fallback. Note that in the unmuted test, .txt and _ir.txt dumps differ only in an unrelated NotNull annotation on a delegate field. See also KT-37586 for some related changes which fixed this problem initially in kapt. --- .../backend/jvm/codegen/ClassCodegen.kt | 11 +++++- .../converter/delegateCorrectErrorTypes.kt | 1 - .../delegateCorrectErrorTypes_ir.txt | 35 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes_ir.txt diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index f2c23f78927..0edc0ffc8ce 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.name.JvmNames.VOLATILE_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPropertyDelegate import org.jetbrains.kotlin.resolve.jvm.checkers.JvmSimpleNameBacktickChecker import org.jetbrains.kotlin.resolve.jvm.diagnostics.* import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature @@ -521,7 +522,15 @@ class ClassCodegen private constructor( private val IrDeclaration.descriptorOrigin: JvmDeclarationOrigin get() { - val psiElement = PsiSourceManager.findPsiElement(this) + val psiElement = PsiSourceManager.findPsiElement(this).let { element -> + // Offsets for accessors and field of delegated property in IR point to the 'by' keyword, so the closest PSI element is the + // KtPropertyDelegate (`by ...` expression). However, old JVM backend passed the PSI element of the property instead. + // This is important for example in case of KAPT stub generation in the "correct error types" mode, which tries to find the + // PSI element for each declaration with unresolved types and tries to heuristically "resolve" those unresolved types to + // generate them into the Java stub. In case of delegated property accessors, it should look for the property declaration, + // since the type can only be provided there, and not in the `by ...` expression. + if (element is KtPropertyDelegate) element.parent else element + } return when { origin == IrDeclarationOrigin.FILE_CLASS -> JvmDeclarationOrigin(JvmDeclarationOriginKind.PACKAGE_PART, psiElement, toIrBasedDescriptor()) diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes.kt b/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes.kt index 88293b3f81c..bd6bd55143d 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // CORRECT_ERROR_TYPES @file:Suppress("UNRESOLVED_REFERENCE") diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes_ir.txt new file mode 100644 index 00000000000..6a9d86297cb --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/delegateCorrectErrorTypes_ir.txt @@ -0,0 +1,35 @@ +package test; + +@kotlin.Metadata() +public final class Bar { + @org.jetbrains.annotations.NotNull() + private final test.Delegate unknown$delegate = null; + + public Bar(@org.jetbrains.annotations.NotNull() + test.Delegate delegate) { + super(); + } + + private final Unknown getUnknown() { + return null; + } +} + +//////////////////// + +package test; + +@kotlin.Metadata() +public final class Delegate { + + public Delegate() { + super(); + } + + @org.jetbrains.annotations.NotNull() + public final java.lang.Object getValue(@org.jetbrains.annotations.NotNull() + java.lang.Object thisRef, @org.jetbrains.annotations.NotNull() + KProperty property) { + return null; + } +}