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 83d1f4b3ae3..e0967418a60 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 @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.lower.ANNOTATION_IMPLEMENTATION import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.JvmBackendContext @@ -38,7 +39,10 @@ import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl -import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.types.getArrayElementType +import org.jetbrains.kotlin.ir.types.isArray import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.TypeMappingMode @@ -525,15 +529,7 @@ class ClassCodegen private constructor( private val IrDeclaration.descriptorOrigin: JvmDeclarationOrigin get() { - 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 - } + val psiElement = findPsiElementForDeclarationOrigin() return when { origin == IrDeclarationOrigin.FILE_CLASS -> JvmDeclarationOrigin(JvmDeclarationOriginKind.PACKAGE_PART, psiElement, toIrBasedDescriptor()) @@ -545,6 +541,27 @@ class ClassCodegen private constructor( } } + private fun IrDeclaration.findPsiElementForDeclarationOrigin(): PsiElement? { + // For synthetic $annotations methods for properties, use the PSI for the property or the constructor parameter. + // It's used in KAPT stub generation to sort the properties correctly based on their source position (see KT-44130). + if (this is IrFunction && name.asString().endsWith("\$annotations")) { + val metadata = metadata as? DescriptorMetadataSource.Property + if (metadata != null) { + return metadata.descriptor.psiElement + } + } + + val element = PsiSourceManager.findPsiElement(this) + + // 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. + return if (element is KtPropertyDelegate) element.parent else element + } + private fun storeSerializedIr(serializedIr: ByteArray) { val av = visitor.newAnnotation(JvmAnnotationNames.SERIALIZED_IR_DESC, true) val partsVisitor = av.visitArray(JvmAnnotationNames.SERIALIZED_IR_BYTES_FIELD_NAME) diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/annotations.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/annotations.ir.txt index 4a34475781b..234316398f5 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/annotations.ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/annotations.ir.txt @@ -113,14 +113,14 @@ public final class TestAnno2 { return null; } + @Anno3(value = "property") + @java.lang.Deprecated() + public static void getB$annotations() { + } + @Anno3(value = "setter") public final void setB(@Anno3(value = "setparam") @org.jetbrains.annotations.NotNull() java.lang.String p0) { } - - @Anno3(value = "property") - @java.lang.Deprecated() - public static void getB$annotations() { - } } diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/annotations2.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/annotations2.ir.txt index f696f3c8b9c..d2d2cd0bd67 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/annotations2.ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/annotations2.ir.txt @@ -26,16 +26,16 @@ public final class AnnotationsTest { java.lang.String $this$topLevelFun) { } + @Anno(value = "top-level-val") + @java.lang.Deprecated() + public static void getTopLevelVal$annotations(int p0) { + } + @org.jetbrains.annotations.NotNull() public static final java.lang.String getTopLevelVal(@Anno(value = "top-level-val-receiver") int $this$topLevelVal) { return null; } - - @Anno(value = "top-level-val") - @java.lang.Deprecated() - public static void getTopLevelVal$annotations(int p0) { - } } //////////////////// @@ -88,6 +88,11 @@ public abstract class Test { return null; } + @Anno(value = "v-property") + @java.lang.Deprecated() + public static void getV$annotations() { + } + @Anno(value = "v-set") public final void setV(@Anno(value = "v-setparam") @org.jetbrains.annotations.NotNull() @@ -105,9 +110,4 @@ public abstract class Test { @java.lang.Deprecated() public static void getAbstractVal$annotations() { } - - @Anno(value = "v-property") - @java.lang.Deprecated() - public static void getV$annotations() { - } } diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/annotationsWithConstants.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/annotationsWithConstants.ir.txt index c8f2e5fb56a..c4843c89ef8 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/annotationsWithConstants.ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/annotationsWithConstants.ir.txt @@ -169,26 +169,57 @@ public final class MyActivity { return 0; } + @Bind(id = lib.R.id.textView) + @java.lang.Deprecated() + public static void getA$annotations() { + } + public final int getB() { return 0; } + @Bind(id = lib.R.id.textView) + @java.lang.Deprecated() + public static void getB$annotations() { + } + public final int getC() { return 0; } + @Bind(id = app.R.layout.mainActivity) + @java.lang.Deprecated() + public static void getC$annotations() { + } + public final int getD() { return 0; } + @Bind(id = app.R.layout.mainActivity) + @java.lang.Deprecated() + public static void getD$annotations() { + } + public final int getE() { return 0; } + @Bind(id = app.R2.layout.mainActivity) + @Anno(a1 = app.B.a1, a2 = app.B.a2, a3 = app.B.a3, a4 = app.B.a4, a5 = app.B.a5, a6 = app.B.a6, a7 = app.B.a7, a8 = app.B.a8, a9 = "A") + @java.lang.Deprecated() + public static void getE$annotations() { + } + public final int getF() { return 0; } + @Bind(id = app.B.id.textView) + @java.lang.Deprecated() + public static void getF$annotations() { + } + @Bind(id = lib.R.id.textView) public final void foo() { } @@ -260,37 +291,6 @@ public final class MyActivity { public final int getPropF() { return 0; } - - @Bind(id = lib.R.id.textView) - @java.lang.Deprecated() - public static void getA$annotations() { - } - - @Bind(id = lib.R.id.textView) - @java.lang.Deprecated() - public static void getB$annotations() { - } - - @Bind(id = app.R.layout.mainActivity) - @java.lang.Deprecated() - public static void getC$annotations() { - } - - @Bind(id = app.R.layout.mainActivity) - @java.lang.Deprecated() - public static void getD$annotations() { - } - - @Bind(id = app.R2.layout.mainActivity) - @Anno(a1 = app.B.a1, a2 = app.B.a2, a3 = app.B.a3, a4 = app.B.a4, a5 = app.B.a5, a6 = app.B.a6, a7 = app.B.a7, a8 = app.B.a8, a9 = "A") - @java.lang.Deprecated() - public static void getE$annotations() { - } - - @Bind(id = app.B.id.textView) - @java.lang.Deprecated() - public static void getF$annotations() { - } } //////////////////// diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/comments.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/comments.ir.txt index 201c602e376..ac8be79a404 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/comments.ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/comments.ir.txt @@ -92,6 +92,14 @@ public final class Test { return null; } + /** + * prop2. + */ + @Anno() + @java.lang.Deprecated() + public static void getProp2$annotations() { + } + /** * get. */ @@ -106,11 +114,6 @@ public final class Test { public final void setProp3(@org.jetbrains.annotations.NotNull() java.lang.String v) { } - - @Anno() - @java.lang.Deprecated() - public static void getProp2$annotations() { - } } //////////////////// diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/commentsRemoved.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/commentsRemoved.ir.txt index eb94fe6a34e..a301af24614 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/commentsRemoved.ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/commentsRemoved.ir.txt @@ -66,6 +66,11 @@ public final class Test { return null; } + @Anno() + @java.lang.Deprecated() + public static void getProp2$annotations() { + } + @org.jetbrains.annotations.NotNull() public final java.lang.String getProp3() { return null; @@ -74,11 +79,6 @@ public final class Test { public final void setProp3(@org.jetbrains.annotations.NotNull() java.lang.String v) { } - - @Anno() - @java.lang.Deprecated() - public static void getProp2$annotations() { - } } //////////////////// diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/delegatedProperties.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/delegatedProperties.ir.txt deleted file mode 100644 index 96eb638cf40..00000000000 --- a/plugins/kapt3/kapt3-compiler/testData/converter/delegatedProperties.ir.txt +++ /dev/null @@ -1,67 +0,0 @@ -package test; - -@kotlin.Metadata() -public final class A { - @org.jetbrains.annotations.NotNull() - private final kotlin.Lazy x$delegate = null; - @org.jetbrains.annotations.NotNull() - private final test.C z$delegate = null; - @org.jetbrains.annotations.NotNull() - private final test.C y$delegate = null; - @org.jetbrains.annotations.NotNull() - private final kotlin.Lazy a$delegate = null; - @org.jetbrains.annotations.NotNull() - private final kotlin.Lazy b$delegate = null; - - public A() { - super(); - } - - @org.jetbrains.annotations.NotNull() - public final kotlin.Unit getX() { - return null; - } - - @org.jetbrains.annotations.NotNull() - public final java.lang.String getZ() { - return null; - } - - @org.jetbrains.annotations.NotNull() - public final java.lang.String getY() { - return null; - } - - @org.jetbrains.annotations.NotNull() - public final test.C getA() { - return null; - } - - @org.jetbrains.annotations.NotNull() - public final test.C getB() { - return null; - } - - @kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"}) - @java.lang.Deprecated() - public static void getX$annotations() { - } -} - -//////////////////// - -package test; - -@kotlin.Metadata() -public class C { - - public C(T v) { - super(); - } - - public final T getValue(@org.jetbrains.annotations.Nullable() - java.lang.Object p1, @org.jetbrains.annotations.Nullable() - java.lang.Object p2) { - return null; - } -} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/deprecated.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/deprecated.ir.txt deleted file mode 100644 index 2bcf7786de3..00000000000 --- a/plugins/kapt3/kapt3-compiler/testData/converter/deprecated.ir.txt +++ /dev/null @@ -1,45 +0,0 @@ -package deprecated; - -@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) -@kotlin.Metadata() -@java.lang.Deprecated() -public abstract @interface Anno { -} - -//////////////////// - -package deprecated; - -@Anno() -@kotlin.Metadata() -@java.lang.Deprecated() -public final class Foo { - @java.lang.Deprecated() - private final int prop = 0; - - public Foo() { - super(); - } - - @java.lang.Deprecated() - public final void foo(int a) { - } - - @java.lang.Deprecated() - public final int getProp() { - return 0; - } - - @java.lang.Deprecated() - public final int getFoo() { - return 0; - } - - @java.lang.Deprecated() - public final void setFoo(int value) { - } - - @java.lang.Deprecated() - public static void getProp$annotations() { - } -} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/incorrectDelegate.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/incorrectDelegate.ir.txt index ee695a068a9..8a62a00d12e 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/incorrectDelegate.ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/incorrectDelegate.ir.txt @@ -25,14 +25,14 @@ public final class HomeFragment { return null; } - private final GroupedNewsListDelegateAdapter getGroupedNewsListAdapter() { - return null; - } - @kotlin.Suppress(names = {"TOO_MANY_ARGUMENTS", "DELEGATE_SPECIAL_FUNCTION_MISSING"}) @java.lang.Deprecated() private static void getCategoryNewsListPresenter$annotations() { } + + private final GroupedNewsListDelegateAdapter getGroupedNewsListAdapter() { + return null; + } } //////////////////// diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.ir.txt deleted file mode 100644 index aeb5c4d162a..00000000000 --- a/plugins/kapt3/kapt3-compiler/testData/converter/topLevel.ir.txt +++ /dev/null @@ -1,69 +0,0 @@ -package test.another; - -@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) -@kotlin.Metadata() -public abstract @interface Anno { - - public abstract java.lang.String value(); -} - -//////////////////// - -package test.another; - -@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(@Anno(value = "rec") - @org.jetbrains.annotations.NotNull() - java.lang.String $this$extensionFunction, @Anno(value = "1") - @org.jetbrains.annotations.NotNull() - java.lang.String a, @Anno(value = "2") - @org.jetbrains.annotations.NotNull() - java.lang.String b) { - } - - @org.jetbrains.annotations.NotNull() - public static final java.lang.String getExtensionProperty(@Anno(value = "propRec") - @org.jetbrains.annotations.NotNull() - T $this$extensionProperty) { - return null; - } - - public static final void setExtensionProperty(@Anno(value = "propRec") - @org.jetbrains.annotations.NotNull() - T $this$extensionProperty, @Anno(value = "setparam") - @org.jetbrains.annotations.NotNull() - java.lang.String setParamName) { - } - - @Anno(value = "extpr") - @java.lang.Deprecated() - public static void getExtensionProperty$annotations(java.lang.Object p0) { - } -}