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.
This commit is contained in:
Alexander Udalov
2022-12-28 23:27:23 +01:00
parent 549bfb2d9e
commit 4a91957ff0
3 changed files with 45 additions and 2 deletions
@@ -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())
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// CORRECT_ERROR_TYPES
@file:Suppress("UNRESOLVED_REFERENCE")
@@ -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;
}
}