add support for compile time constant serialization
This commit is contained in:
@@ -41,6 +41,8 @@ import org.jetbrains.kotlin.load.kotlin.DeserializedResolverUtils
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
import org.jetbrains.kotlin.cli.jvm.JVMConfigurationKeys
|
import org.jetbrains.kotlin.cli.jvm.JVMConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.NullValue
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
|
||||||
private object BuiltInsSerializerExtension : SerializerExtension() {
|
private object BuiltInsSerializerExtension : SerializerExtension() {
|
||||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder, stringTable: StringTable) {
|
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder, stringTable: StringTable) {
|
||||||
@@ -71,6 +73,11 @@ private object BuiltInsSerializerExtension : SerializerExtension() {
|
|||||||
for (annotation in callable.getAnnotations()) {
|
for (annotation in callable.getAnnotations()) {
|
||||||
proto.addExtension(BuiltInsProtoBuf.callableAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable))
|
proto.addExtension(BuiltInsProtoBuf.callableAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable))
|
||||||
}
|
}
|
||||||
|
val compileTimeConstant = (callable as? PropertyDescriptor)?.getCompileTimeInitializer()
|
||||||
|
if (compileTimeConstant != null && compileTimeConstant !is NullValue) {
|
||||||
|
val type = compileTimeConstant.getType(KotlinBuiltIns.getInstance())
|
||||||
|
proto.setExtension(BuiltInsProtoBuf.compileTimeValue, AnnotationSerializer.valueProto(compileTimeConstant, type, stringTable).build())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeValueParameter(
|
override fun serializeValueParameter(
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
enum class Weapon {
|
||||||
|
ROCK
|
||||||
|
PAPER
|
||||||
|
SCISSORS
|
||||||
|
}
|
||||||
|
|
||||||
|
val byteConst: Byte = 10
|
||||||
|
val shortConst: Short = 20
|
||||||
|
val intConst: Int = 30
|
||||||
|
val longConst: Long = 40
|
||||||
|
val charConst: Char = 'A'
|
||||||
|
val stringConst: String = "abcd"
|
||||||
|
val booleanConst: Boolean = true
|
||||||
|
val floatConst: Float = 2.0f
|
||||||
|
val doubleConst: Double = 3.0
|
||||||
|
val enumConst: Weapon? = Weapon.ROCK
|
||||||
|
val arrayConst: Any = byteArray(1,2)
|
||||||
|
|
||||||
|
class Class {
|
||||||
|
val byteConst: Byte = 10
|
||||||
|
val shortConst: Short = 20
|
||||||
|
val intConst: Int = 30
|
||||||
|
val longConst: Long = 40
|
||||||
|
val charConst: Char = 'A'
|
||||||
|
val stringConst: String = "abcd"
|
||||||
|
val booleanConst: Boolean = true
|
||||||
|
val floatConst: Float = 2.0f
|
||||||
|
val doubleConst: Double = 3.0
|
||||||
|
val enumConst: Weapon? = Weapon.ROCK
|
||||||
|
val arrayConst: Any = byteArray(1,2)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal val arrayConst: kotlin.Any = {1.toByte(), 2.toByte()}
|
||||||
|
internal val booleanConst: kotlin.Boolean = true
|
||||||
|
internal val byteConst: kotlin.Byte = 10.toByte()
|
||||||
|
internal val charConst: kotlin.Char = \u0041 ('A')
|
||||||
|
internal val doubleConst: kotlin.Double = 3.0.toDouble()
|
||||||
|
internal val enumConst: test.Weapon? = Weapon.ROCK
|
||||||
|
internal val floatConst: kotlin.Float = 2.0.toFloat()
|
||||||
|
internal val intConst: kotlin.Int = 30
|
||||||
|
internal val longConst: kotlin.Long = 40.toLong()
|
||||||
|
internal val shortConst: kotlin.Short = 20.toShort()
|
||||||
|
internal val stringConst: kotlin.String = "abcd"
|
||||||
|
|
||||||
|
internal final class Class {
|
||||||
|
public constructor Class()
|
||||||
|
internal final val arrayConst: kotlin.Any = {1.toByte(), 2.toByte()}
|
||||||
|
internal final val booleanConst: kotlin.Boolean = true
|
||||||
|
internal final val byteConst: kotlin.Byte = 10.toByte()
|
||||||
|
internal final val charConst: kotlin.Char = \u0041 ('A')
|
||||||
|
internal final val doubleConst: kotlin.Double = 3.0.toDouble()
|
||||||
|
internal final val enumConst: test.Weapon? = Weapon.ROCK
|
||||||
|
internal final val floatConst: kotlin.Float = 2.0.toFloat()
|
||||||
|
internal final val intConst: kotlin.Int = 30
|
||||||
|
internal final val longConst: kotlin.Long = 40.toLong()
|
||||||
|
internal final val shortConst: kotlin.Short = 20.toShort()
|
||||||
|
internal final val stringConst: kotlin.String = "abcd"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final enum class Weapon : kotlin.Enum<test.Weapon> {
|
||||||
|
public enum entry ROCK : test.Weapon {
|
||||||
|
private constructor ROCK()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
|
||||||
|
public class object <class-object-for-ROCK> : test.Weapon.ROCK {
|
||||||
|
private constructor <class-object-for-ROCK>()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum entry PAPER : test.Weapon {
|
||||||
|
private constructor PAPER()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
|
||||||
|
public class object <class-object-for-PAPER> : test.Weapon.PAPER {
|
||||||
|
private constructor <class-object-for-PAPER>()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum entry SCISSORS : test.Weapon {
|
||||||
|
private constructor SCISSORS()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
|
||||||
|
public class object <class-object-for-SCISSORS> : test.Weapon.SCISSORS {
|
||||||
|
private constructor <class-object-for-SCISSORS>()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor Weapon()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.Weapon): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Weapon
|
||||||
|
public final /*synthesized*/ fun values(): kotlin.Array<test.Weapon>
|
||||||
|
}
|
||||||
@@ -61,6 +61,10 @@ public class BuiltInsSerializerTest : TestCaseWithTmpdir() {
|
|||||||
doTest("simple.kt")
|
doTest("simple.kt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testCompileTimeConstants() {
|
||||||
|
doTest("compileTimeConstants.kt")
|
||||||
|
}
|
||||||
|
|
||||||
fun testAnnotationTargets() {
|
fun testAnnotationTargets() {
|
||||||
doTest("annotationTargets.kt")
|
doTest("annotationTargets.kt")
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-6
@@ -10,6 +10,7 @@ public final class DebugBuiltInsProtoBuf {
|
|||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.className);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.className);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.classAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.classAnnotation);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.callableAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.callableAnnotation);
|
||||||
|
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.compileTimeValue);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.parameterAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.parameterAnnotation);
|
||||||
}
|
}
|
||||||
public static final int CLASS_NAME_FIELD_NUMBER = 150;
|
public static final int CLASS_NAME_FIELD_NUMBER = 150;
|
||||||
@@ -45,6 +46,17 @@ public final class DebugBuiltInsProtoBuf {
|
|||||||
.newFileScopedGeneratedExtension(
|
.newFileScopedGeneratedExtension(
|
||||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||||
|
public static final int COMPILE_TIME_VALUE_FIELD_NUMBER = 151;
|
||||||
|
/**
|
||||||
|
* <code>extend .org.jetbrains.kotlin.serialization.Callable { ... }</code>
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable,
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value> compileTimeValue = com.google.protobuf.GeneratedMessage
|
||||||
|
.newFileScopedGeneratedExtension(
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.class,
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.getDefaultInstance());
|
||||||
public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150;
|
public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150;
|
||||||
/**
|
/**
|
||||||
* <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code>
|
* <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code>
|
||||||
@@ -76,11 +88,14 @@ public final class DebugBuiltInsProtoBuf {
|
|||||||
"tation:z\n\023callable_annotation\022,.org.jetb" +
|
"tation:z\n\023callable_annotation\022,.org.jetb" +
|
||||||
"rains.kotlin.serialization.Callable\030\226\001 \003",
|
"rains.kotlin.serialization.Callable\030\226\001 \003",
|
||||||
"(\0132..org.jetbrains.kotlin.serialization." +
|
"(\0132..org.jetbrains.kotlin.serialization." +
|
||||||
"Annotation:\212\001\n\024parameter_annotation\022;.or" +
|
"Annotation:\210\001\n\022compile_time_value\022,.org." +
|
||||||
"g.jetbrains.kotlin.serialization.Callabl" +
|
"jetbrains.kotlin.serialization.Callable\030" +
|
||||||
"e.ValueParameter\030\226\001 \003(\0132..org.jetbrains." +
|
"\227\001 \001(\0132=.org.jetbrains.kotlin.serializat" +
|
||||||
"kotlin.serialization.AnnotationB\027B\025Debug" +
|
"ion.Annotation.Argument.Value:\212\001\n\024parame" +
|
||||||
"BuiltInsProtoBuf"
|
"ter_annotation\022;.org.jetbrains.kotlin.se" +
|
||||||
|
"rialization.Callable.ValueParameter\030\226\001 \003" +
|
||||||
|
"(\0132..org.jetbrains.kotlin.serialization." +
|
||||||
|
"AnnotationB\027B\025DebugBuiltInsProtoBuf"
|
||||||
};
|
};
|
||||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||||
@@ -90,7 +105,8 @@ public final class DebugBuiltInsProtoBuf {
|
|||||||
className.internalInit(descriptor.getExtensions().get(0));
|
className.internalInit(descriptor.getExtensions().get(0));
|
||||||
classAnnotation.internalInit(descriptor.getExtensions().get(1));
|
classAnnotation.internalInit(descriptor.getExtensions().get(1));
|
||||||
callableAnnotation.internalInit(descriptor.getExtensions().get(2));
|
callableAnnotation.internalInit(descriptor.getExtensions().get(2));
|
||||||
parameterAnnotation.internalInit(descriptor.getExtensions().get(3));
|
compileTimeValue.internalInit(descriptor.getExtensions().get(3));
|
||||||
|
parameterAnnotation.internalInit(descriptor.getExtensions().get(4));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-3
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.serialization.Flags
|
import org.jetbrains.kotlin.serialization.Flags
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
|
||||||
|
import org.jetbrains.kotlin.types.JetType
|
||||||
|
|
||||||
public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
|
public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
@@ -130,11 +132,11 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
|||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
proto: ProtoBuf.Callable,
|
proto: ProtoBuf.Callable,
|
||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
kind: AnnotatedCallableKind
|
expectedType: JetType
|
||||||
): C? {
|
): C? {
|
||||||
val signature = getCallableSignature(proto, nameResolver, kind) ?: return null
|
val signature = getCallableSignature(proto, nameResolver, AnnotatedCallableKind.PROPERTY) ?: return null
|
||||||
|
|
||||||
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind)
|
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, AnnotatedCallableKind.PROPERTY)
|
||||||
if (kotlinClass == null) {
|
if (kotlinClass == null) {
|
||||||
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName(nameResolver)}", null)
|
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: ${container.getFqName(nameResolver)}", null)
|
||||||
return null
|
return null
|
||||||
|
|||||||
+4
-3
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
|
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
|
||||||
|
import org.jetbrains.kotlin.types.JetType
|
||||||
|
|
||||||
class BuiltInsAnnotationAndConstantLoader(
|
class BuiltInsAnnotationAndConstantLoader(
|
||||||
module: ModuleDescriptor
|
module: ModuleDescriptor
|
||||||
@@ -61,9 +62,9 @@ class BuiltInsAnnotationAndConstantLoader(
|
|||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
proto: ProtoBuf.Callable,
|
proto: ProtoBuf.Callable,
|
||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
kind: AnnotatedCallableKind
|
expectedType: JetType
|
||||||
): CompileTimeConstant<*>? {
|
): CompileTimeConstant<*>? {
|
||||||
// TODO: support deserialization of compile time constants in built-ins when needed
|
val value = proto.getExtension(BuiltInsProtoBuf.compileTimeValue)
|
||||||
throw UnsupportedOperationException()
|
return deserializer.resolveValue(expectedType, value, nameResolver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ extend Class {
|
|||||||
|
|
||||||
extend Callable {
|
extend Callable {
|
||||||
repeated Annotation callable_annotation = 150;
|
repeated Annotation callable_annotation = 150;
|
||||||
|
optional Annotation.Argument.Value compile_time_value = 151;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend Callable.ValueParameter {
|
extend Callable.ValueParameter {
|
||||||
|
|||||||
+16
@@ -10,6 +10,7 @@ public final class BuiltInsProtoBuf {
|
|||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.className);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.className);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.classAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.classAnnotation);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.callableAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.callableAnnotation);
|
||||||
|
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.compileTimeValue);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.parameterAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf.parameterAnnotation);
|
||||||
}
|
}
|
||||||
public static final int CLASS_NAME_FIELD_NUMBER = 150;
|
public static final int CLASS_NAME_FIELD_NUMBER = 150;
|
||||||
@@ -57,6 +58,21 @@ public final class BuiltInsProtoBuf {
|
|||||||
150,
|
150,
|
||||||
com.google.protobuf.WireFormat.FieldType.MESSAGE,
|
com.google.protobuf.WireFormat.FieldType.MESSAGE,
|
||||||
false);
|
false);
|
||||||
|
public static final int COMPILE_TIME_VALUE_FIELD_NUMBER = 151;
|
||||||
|
/**
|
||||||
|
* <code>extend .org.jetbrains.kotlin.serialization.Callable { ... }</code>
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Callable,
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value> compileTimeValue = com.google.protobuf.GeneratedMessageLite
|
||||||
|
.newSingularGeneratedExtension(
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Callable.getDefaultInstance(),
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.getDefaultInstance(),
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.getDefaultInstance(),
|
||||||
|
null,
|
||||||
|
151,
|
||||||
|
com.google.protobuf.WireFormat.FieldType.MESSAGE);
|
||||||
public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150;
|
public static final int PARAMETER_ANNOTATION_FIELD_NUMBER = 150;
|
||||||
/**
|
/**
|
||||||
* <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code>
|
* <code>extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... }</code>
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.serialization.deserialization;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||||
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -51,6 +52,6 @@ public interface AnnotationAndConstantLoader<A, C> {
|
|||||||
@NotNull ProtoContainer container,
|
@NotNull ProtoContainer container,
|
||||||
@NotNull ProtoBuf.Callable proto,
|
@NotNull ProtoBuf.Callable proto,
|
||||||
@NotNull NameResolver nameResolver,
|
@NotNull NameResolver nameResolver,
|
||||||
@NotNull AnnotatedCallableKind kind
|
@NotNull JetType expectedType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
|
|
||||||
public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
||||||
private val builtIns: KotlinBuiltIns
|
private val builtIns: KotlinBuiltIns
|
||||||
@@ -62,7 +63,7 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
|||||||
return Pair(parameter, resolveValue(parameter.getType(), proto.getValue(), nameResolver))
|
return Pair(parameter, resolveValue(parameter.getType(), proto.getValue(), nameResolver))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveValue(
|
public fun resolveValue(
|
||||||
expectedType: JetType,
|
expectedType: JetType,
|
||||||
value: Value,
|
value: Value,
|
||||||
nameResolver: NameResolver
|
nameResolver: NameResolver
|
||||||
@@ -90,9 +91,7 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
|||||||
AnnotationValue(deserializeAnnotation(value.getAnnotation(), nameResolver))
|
AnnotationValue(deserializeAnnotation(value.getAnnotation(), nameResolver))
|
||||||
}
|
}
|
||||||
Type.ARRAY -> {
|
Type.ARRAY -> {
|
||||||
if (!KotlinBuiltIns.isArray(expectedType) &&
|
val expectedIsArray = KotlinBuiltIns.isArray(expectedType) || KotlinBuiltIns.isPrimitiveArray(expectedType)
|
||||||
!KotlinBuiltIns.isPrimitiveArray(expectedType)) return ErrorValue.create("Unexpected argument value")
|
|
||||||
|
|
||||||
val arrayElements = value.getArrayElementList()
|
val arrayElements = value.getArrayElementList()
|
||||||
|
|
||||||
val actualArrayType =
|
val actualArrayType =
|
||||||
@@ -102,13 +101,13 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
|||||||
builtIns.getArrayType(Variance.INVARIANT, actualElementType)
|
builtIns.getArrayType(Variance.INVARIANT, actualElementType)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// In the case of empty array, no element has the element type, so we fall back to the expected type.
|
// In the case of empty array, no element has the element type, so we fall back to the expected type, if any.
|
||||||
// This is not very accurate when annotation class has been changed without recompiling clients,
|
// This is not very accurate when annotation class has been changed without recompiling clients,
|
||||||
// but should not in fact matter because the value is empty anyway
|
// but should not in fact matter because the value is empty anyway
|
||||||
expectedType
|
if (expectedIsArray) expectedType else builtIns.getArrayType(Variance.INVARIANT, builtIns.getAnyType())
|
||||||
}
|
}
|
||||||
|
|
||||||
val expectedElementType = builtIns.getArrayElementType(expectedType)
|
val expectedElementType = builtIns.getArrayElementType(if (expectedIsArray) expectedType else actualArrayType)
|
||||||
|
|
||||||
ArrayValue(
|
ArrayValue(
|
||||||
arrayElements.map { resolveValue(expectedElementType, it, nameResolver) },
|
arrayElements.map { resolveValue(expectedElementType, it, nameResolver) },
|
||||||
@@ -119,12 +118,13 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
|||||||
else -> error("Unsupported annotation argument type: ${value.getType()} (expected $expectedType)")
|
else -> error("Unsupported annotation argument type: ${value.getType()} (expected $expectedType)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.getType(builtIns) != expectedType) {
|
if (result.getType(builtIns) isSubtypeOf expectedType) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
else {
|
||||||
// This means that an annotation class has been changed incompatibly without recompiling clients
|
// This means that an annotation class has been changed incompatibly without recompiling clients
|
||||||
return ErrorValue.create("Unexpected argument value")
|
return ErrorValue.create("Unexpected argument value")
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: see analogous code in BinaryClassAnnotationAndConstantLoaderImpl
|
// NOTE: see analogous code in BinaryClassAnnotationAndConstantLoaderImpl
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
property.setCompileTimeInitializer(
|
property.setCompileTimeInitializer(
|
||||||
c.storageManager.createNullableLazyValue {
|
c.storageManager.createNullableLazyValue {
|
||||||
val container = c.containingDeclaration.asProtoContainer()
|
val container = c.containingDeclaration.asProtoContainer()
|
||||||
c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, c.nameResolver, AnnotatedCallableKind.PROPERTY)
|
c.components.annotationAndConstantLoader.loadPropertyConstant(container, proto, c.nameResolver, property.getReturnType())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user