KAPT+IR: Properly process annotations and backing field annotations

This commit is contained in:
Mikhael Bogdanov
2022-02-16 10:37:48 +01:00
parent ea2bf3c867
commit f05c72d48f
14 changed files with 486 additions and 12 deletions
@@ -52,7 +52,7 @@ abstract class IrBasedDeclarationDescriptor<T : IrDeclaration>(val owner: T) : D
symbol.owner.valueParameters.map { it.name to getValueArgument(it.index) }
.filter { it.second != null }
.associate { it.first to it.second!!.toConstantValue() },
/*TODO*/ SourceElement.NO_SOURCE
source
)
}
@@ -5,12 +5,15 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrConstructorCall : IrFunctionAccessExpression() {
abstract override val symbol: IrConstructorSymbol
abstract val source: SourceElement
abstract val constructorTypeArgumentsCount: Int
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
@@ -23,6 +24,7 @@ class IrConstructorCallImpl(
override val constructorTypeArgumentsCount: Int,
valueArgumentsCount: Int,
override val origin: IrStatementOrigin? = null,
override val source: SourceElement = SourceElement.NO_SOURCE
) : IrConstructorCall() {
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
@@ -170,7 +170,8 @@ abstract class ConstantValueGenerator(
primaryConstructorSymbol,
valueArgumentsCount = primaryConstructorDescriptor.valueParameters.size,
typeArgumentsCount = annotationClassDescriptor.declaredTypeParameters.size,
constructorTypeArgumentsCount = 0
constructorTypeArgumentsCount = 0,
source = annotationDescriptor.source
)
val substitutor = TypeConstructorSubstitution.create(annotationType).buildSubstitutor()
@@ -120,6 +120,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
private val mutableBindings = mutableMapOf<String, KaptJavaFileObject>()
private val isIrBackend = kaptContext.generationState.isIrBackend
val bindings: Map<String, KaptJavaFileObject>
get() = mutableBindings
@@ -691,8 +693,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
val origin = kaptContext.origins[field]
val descriptor = origin?.descriptor
val fieldAnnotations = when (descriptor) {
is PropertyDescriptor -> descriptor.backingField?.annotations
val fieldAnnotations = when {
!isIrBackend && descriptor is PropertyDescriptor -> descriptor.backingField?.annotations
else -> descriptor?.annotations
} ?: Annotations.EMPTY
@@ -5,12 +5,24 @@
package org.jetbrains.kotlin.kapt3.test
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.test.TargetBackend
open class AbstractIrClassFileToSourceStubConverterTest : AbstractClassFileToSourceStubConverterTest() {
override val backend = TargetBackend.JVM_IR
override fun updateConfiguration(configuration: CompilerConfiguration) {
configuration.put(JVMConfigurationKeys.DO_NOT_CLEAR_BINDING_CONTEXT, true)
super.updateConfiguration(configuration)
}
}
abstract class AbstractIrKotlinKaptContextTest : AbstractKotlinKaptContextTest() {
override val backend = TargetBackend.JVM_IR
override fun updateConfiguration(configuration: CompilerConfiguration) {
configuration.put(JVMConfigurationKeys.DO_NOT_CLEAR_BINDING_CONTEXT, true)
super.updateConfiguration(configuration)
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// CORRECT_ERROR_TYPES
// NO_VALIDATION
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
//FILE: lib/R.java
package lib;
@@ -0,0 +1,383 @@
package app;
import java.lang.System;
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface Anno {
public abstract boolean a1();
public abstract byte a2();
public abstract int a3();
public abstract short a4();
public abstract long a5();
public abstract char a6();
public abstract float a7();
public abstract double a8();
public abstract java.lang.String a9();
}
////////////////////
package app;
public class B {
public B() {
super();
}
public static class id {
public id() {
super();
}
public static final int textView = 200;
}
public static final boolean a1 = false;
public static final byte a2 = 1;
public static final int a3 = 2;
public static final short a4 = 3;
public static final long a5 = 4L;
public static final char a6 = '5';
public static final float a7 = 6.0F;
public static final double a8 = 7.0;
public static final String a9 = "A";
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface Bind {
public abstract int id();
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.FIELD})
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.FIELD})
public abstract @interface BindField {
public abstract int id();
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
public final class JJ {
@org.jetbrains.annotations.NotNull()
private static final java.lang.String b = null;
@org.jetbrains.annotations.NotNull()
public static final app.JJ INSTANCE = null;
private JJ() {
super();
}
@org.jetbrains.annotations.NotNull()
public final java.lang.String getB() {
return null;
}
@org.jetbrains.annotations.NotNull()
public final java.lang.String c() {
return null;
}
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface MultiValue {
public abstract int[] ids();
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface MultiValueByte {
public abstract byte[] ids();
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public abstract @interface MultiValueString {
public abstract java.lang.String[] ids();
}
////////////////////
package app;
import java.lang.System;
@kotlin.Metadata()
public final class MyActivity {
@BindField(id = lib.R.id.textView)
private final int a = 0;
@BindField(id = lib.R.id.textView)
private final int b = 0;
@BindField(id = app.R.layout.mainActivity)
private final int c = 0;
@BindField(id = app.R.layout.mainActivity)
private final int d = 0;
@BindField(id = app.R2.layout.mainActivity)
private final int e = 0;
@BindField(id = app.B.id.textView)
private final int f = 0;
public final int propA = app.B.id.textView;
private final int propB = app.B.id.textView;
private int propC = app.B.id.textView;
@kotlin.jvm.JvmField()
public final int propD = app.B.id.textView;
@kotlin.jvm.JvmField()
public int propE = app.B.id.textView;
private final int propF = 0;
public MyActivity() {
super();
}
public final int getA() {
return 0;
}
public final int getB() {
return 0;
}
public final int getC() {
return 0;
}
public final int getD() {
return 0;
}
public final int getE() {
return 0;
}
public final int getF() {
return 0;
}
@Bind(id = lib.R.id.textView)
public final void foo() {
}
@Bind(id = lib.R.id.textView)
public final void foo2() {
}
@Bind(id = app.R.layout.mainActivity)
public final void foo3() {
}
@Bind(id = app.R.layout.mainActivity)
public final void foo4() {
}
@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")
@Bind(id = app.R2.layout.mainActivity)
public final void foo5() {
}
@Bind(id = app.B.id.textView)
public final void plainIntConstant() {
}
@MultiValue(ids = {})
public final void multi0() {
}
@MultiValue(ids = {app.B.id.textView})
public final void multi1() {
}
@MultiValue(ids = {app.B.id.textView, app.B.a3})
public final void multi2() {
}
@MultiValue(ids = {app.B.id.textView, app.B.a3})
public final void multi3() {
}
@MultiValueString(ids = {"A"})
public final void multi4() {
}
@MultiValueByte(ids = {app.B.a2})
public final void multi5() {
}
@lib.OnClick(value = {app.B.id.textView})
public final void multiJava1() {
}
@lib.OnClick(value = {app.B.id.textView, app.R.layout.mainActivity})
public final void multiJava2() {
}
public final int getPropB() {
return 0;
}
public final int getPropC() {
return 0;
}
public final void setPropC(int p0) {
}
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() {
}
@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")
@Bind(id = app.R2.layout.mainActivity)
@java.lang.Deprecated()
public static void getE$annotations() {
}
@Bind(id = app.B.id.textView)
@java.lang.Deprecated()
public static void getF$annotations() {
}
}
////////////////////
package app;
public class R {
public R() {
super();
}
public static class layout {
public layout() {
super();
}
public static final int mainActivity = 100;
}
}
////////////////////
package app;
public class R2 {
public R2() {
super();
}
public static class layout {
public layout() {
super();
}
public static final int mainActivity = 100;
}
}
////////////////////
package lib;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value() default {};
}
////////////////////
package lib;
public class R {
public R() {
super();
}
public static class id {
public id() {
super();
}
public static final int textView = 100;
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// CORRECT_ERROR_TYPES
package kapt
@@ -69,7 +69,7 @@ import java.lang.System;
@kotlin.Metadata()
public final class Test3 {
@org.jetbrains.annotations.NotNull()
private final Test3.Amigo.Example foo = null;
private final Test3.Amigo.Example foo = Test3.Amigo.Example.FOO;
public Test3() {
super();
@@ -101,7 +101,7 @@ import java.lang.System;
@kotlin.Metadata()
public final class Test4 {
private final int foo = 0;
private final int foo = 1;
@org.jetbrains.annotations.NotNull()
public static final Test4.Companion Companion = null;
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// CORRECT_ERROR_TYPES
import java.util.concurrent.*
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JVM_IR
object PrimitiveTypes {
const val booleanFalse: Boolean = false
const val booleanTrue: Boolean = true
@@ -0,0 +1,77 @@
import java.lang.System;
@kotlin.Metadata()
public final class PrimitiveTypes {
public static final boolean booleanFalse = false;
public static final boolean booleanTrue = true;
public static final int int0 = 0;
public static final int intMinus1000 = -1000;
public static final int intMinValue = -2147483648;
public static final int intMaxValue = 2147483647;
public static final int intHex = -1;
public static final byte byte0 = (byte)0;
public static final byte byte50 = (byte)50;
public static final short short5 = (short)5;
public static final char charC = 'C';
public static final char char0 = '\u0000';
public static final char char10 = '\n';
public static final char char13 = '\r';
public static final long long0 = 0L;
public static final long longMaxValue = 9223372036854775807L;
public static final long longMinValue = -9223372036854775808L;
public static final long longHex = 4294967295L;
public static final float float54 = 5.4F;
private static final float floatMaxValue = 3.4028235E38F;
private static final float floatNan = 0.0F / 0.0F;
private static final float floatPositiveInfinity = 1.0F / 0.0F;
private static final float floatNegativeInfinity = -1.0F / 0.0F;
public static final double double54 = 5.4;
private static final double doubleMaxValue = 1.7976931348623157E308;
private static final double doubleNan = 0.0 / 0.0;
private static final double doublePositiveInfinity = 1.0 / 0.0;
private static final double doubleNegativeInfinity = -1.0 / 0.0;
@org.jetbrains.annotations.NotNull()
public static final java.lang.String stringHelloWorld = "Hello, world!";
@org.jetbrains.annotations.NotNull()
public static final java.lang.String stringQuotes = "quotes \" \'\'quotes";
@org.jetbrains.annotations.NotNull()
public static final java.lang.String stringRN = "\r\n";
@org.jetbrains.annotations.NotNull()
public static final PrimitiveTypes INSTANCE = null;
private PrimitiveTypes() {
super();
}
public final float getFloatMaxValue() {
return 0.0F;
}
public final float getFloatNan() {
return 0.0F;
}
public final float getFloatPositiveInfinity() {
return 0.0F;
}
public final float getFloatNegativeInfinity() {
return 0.0F;
}
public final double getDoubleMaxValue() {
return 0.0;
}
public final double getDoubleNan() {
return 0.0;
}
public final double getDoublePositiveInfinity() {
return 0.0;
}
public final double getDoubleNegativeInfinity() {
return 0.0;
}
}