diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java index 3259a679a70..994399eb8ed 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java @@ -21,9 +21,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.serialization.AnnotationSerializer; import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.kotlin.serialization.SerializerExtension; import org.jetbrains.kotlin.serialization.StringTable; @@ -31,6 +33,7 @@ import org.jetbrains.kotlin.serialization.deserialization.NameResolver; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor; import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf; +import org.jetbrains.kotlin.types.JetType; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.Method; @@ -70,6 +73,14 @@ public class JvmSerializerExtension extends SerializerExtension { } } + @Override + public void serializeType(@NotNull JetType type, @NotNull ProtoBuf.Type.Builder proto, @NotNull StringTable stringTable) { + // TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead + for (AnnotationDescriptor annotation : type.getAnnotations()) { + proto.addExtension(JvmProtoBuf.typeAnnotation, AnnotationSerializer.INSTANCE$.serializeAnnotation(annotation, stringTable)); + } + } + @Override @NotNull public String getLocalClassName(@NotNull ClassDescriptor descriptor) { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java index 62efb6d8edf..74cf8fa73f6 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java @@ -299,7 +299,7 @@ public class DescriptorSerializer { case IN_VARIANCE: return ProtoBuf.TypeParameter.Variance.IN; case OUT_VARIANCE: - return ProtoBuf.TypeParameter.Variance.OUT; + return ProtoBuf.TypeParameter.Variance.OUT; } throw new IllegalStateException("Unknown variance: " + variance); } @@ -323,6 +323,8 @@ public class DescriptorSerializer { builder.setNullable(true); } + extension.serializeType(type, builder, stringTable); + return builder; } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java index b0eb4c52233..a4661480b5d 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; +import org.jetbrains.kotlin.types.JetType; import java.util.Collection; @@ -53,6 +54,13 @@ public abstract class SerializerExtension { ) { } + public void serializeType( + @NotNull JetType type, + @NotNull ProtoBuf.Type.Builder proto, + @NotNull StringTable stringTable + ) { + } + @NotNull public String getLocalClassName(@NotNull ClassDescriptor descriptor) { throw new UnsupportedOperationException("Local classes are unsupported: " + descriptor); diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt new file mode 100644 index 00000000000..90a8187d9f4 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt @@ -0,0 +1,5 @@ +package test + +annotation class A + +fun ([A] String).foo() {} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt new file mode 100644 index 00000000000..76853d55f94 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.txt @@ -0,0 +1,7 @@ +package test + +internal fun [test.A()] kotlin.String.foo(): kotlin.Unit + +internal final annotation class A : kotlin.Annotation { + /*primary*/ public constructor A() +} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt b/compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt new file mode 100644 index 00000000000..794c1cc98c4 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt @@ -0,0 +1,7 @@ +package test + +annotation class A + +class SimpleTypeAnnotation { + fun foo(x: [A] IntRange): [A] Int = 42 +} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.txt b/compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.txt new file mode 100644 index 00000000000..8fd13bb17d3 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.txt @@ -0,0 +1,10 @@ +package test + +internal final annotation class A : kotlin.Annotation { + /*primary*/ public constructor A() +} + +internal final class SimpleTypeAnnotation { + /*primary*/ public constructor SimpleTypeAnnotation() + internal final fun foo(/*0*/ x: [test.A()] kotlin.IntRange): [test.A()] kotlin.Int +} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.kt b/compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.kt new file mode 100644 index 00000000000..b9507204c34 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.kt @@ -0,0 +1,9 @@ +// ALLOW_AST_ACCESS + +package test + +annotation class Ann(val x: String, val y: Double) + +class TypeAnnotationWithArguments { + fun foo(param: [Ann("param", 3.14)] IntRange): [Ann("fun", 2.72)] Unit {} +} diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.txt b/compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.txt new file mode 100644 index 00000000000..2f8b8e0b2e2 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.txt @@ -0,0 +1,14 @@ +package test + +internal final annotation class Ann : kotlin.Annotation { + /*primary*/ public constructor Ann(/*0*/ x: kotlin.String, /*1*/ y: kotlin.Double) + internal final val x: kotlin.String + internal final fun (): kotlin.String + internal final val y: kotlin.Double + internal final fun (): kotlin.Double +} + +internal final class TypeAnnotationWithArguments { + /*primary*/ public constructor TypeAnnotationWithArguments() + internal final fun foo(/*0*/ param: [test.Ann(x = "param": kotlin.String, y = 3.14.toDouble(): kotlin.Double)] kotlin.IntRange): [test.Ann(x = "fun": kotlin.String, y = 2.72.toDouble(): kotlin.Double)] kotlin.Unit +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index c3460ac57ba..635a14a23ac 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -2262,6 +2262,33 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledKotlin(fileName); } } + + @TestMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Types extends AbstractLoadJavaTest { + public void testAllFilesPresentInTypes() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("ReceiverParameter.kt") + public void testReceiverParameter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt"); + doTestCompiledKotlin(fileName); + } + + @TestMetadata("SimpleTypeAnnotation.kt") + public void testSimpleTypeAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); + doTestCompiledKotlin(fileName); + } + + @TestMetadata("TypeAnnotationWithArguments.kt") + public void testTypeAnnotationWithArguments() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.kt"); + doTestCompiledKotlin(fileName); + } + } } @TestMetadata("compiler/testData/loadJava/compiledKotlin/class") diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java index 6f624c4e380..1f3f100fae8 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/JvmRuntimeDescriptorLoaderTestGenerated.java @@ -419,6 +419,33 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD doTest(fileName); } } + + @TestMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Types extends AbstractJvmRuntimeDescriptorLoaderTest { + public void testAllFilesPresentInTypes() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("ReceiverParameter.kt") + public void testReceiverParameter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt"); + doTest(fileName); + } + + @TestMetadata("SimpleTypeAnnotation.kt") + public void testSimpleTypeAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); + doTest(fileName); + } + + @TestMetadata("TypeAnnotationWithArguments.kt") + public void testTypeAnnotationWithArguments() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/loadJava/compiledKotlin/class") diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java index cc6f2d0dd17..2ea2486072d 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java +++ b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java @@ -5362,8 +5362,9 @@ public final class DebugProtoBuf { // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.Annotation) } - public interface TypeOrBuilder - extends com.google.protobuf.MessageOrBuilder { + public interface TypeOrBuilder extends + com.google.protobuf.GeneratedMessage. + ExtendableMessageOrBuilder { // required .org.jetbrains.kotlin.serialization.Type.Constructor constructor = 1; /** @@ -5421,7 +5422,7 @@ public final class DebugProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ boolean hasFlexibleTypeCapabilitiesId(); @@ -5431,7 +5432,7 @@ public final class DebugProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ int getFlexibleTypeCapabilitiesId(); @@ -5472,10 +5473,10 @@ public final class DebugProtoBuf { * Protobuf type {@code org.jetbrains.kotlin.serialization.Type} */ public static final class Type extends - com.google.protobuf.GeneratedMessage - implements TypeOrBuilder { + com.google.protobuf.GeneratedMessage.ExtendableMessage< + Type> implements TypeOrBuilder { // Use Type.newBuilder() to construct. - private Type(com.google.protobuf.GeneratedMessage.Builder builder) { + private Type(com.google.protobuf.GeneratedMessage.ExtendableBuilder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } @@ -7066,7 +7067,7 @@ public final class DebugProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ public boolean hasFlexibleTypeCapabilitiesId() { @@ -7078,7 +7079,7 @@ public final class DebugProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ public int getFlexibleTypeCapabilitiesId() { @@ -7157,6 +7158,10 @@ public final class DebugProtoBuf { return false; } } + if (!extensionsAreInitialized()) { + memoizedIsInitialized = 0; + return false; + } memoizedIsInitialized = 1; return true; } @@ -7164,6 +7169,9 @@ public final class DebugProtoBuf { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); + com.google.protobuf.GeneratedMessage + .ExtendableMessage.ExtensionWriter extensionWriter = + newExtensionWriter(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeMessage(1, constructor_); } @@ -7179,6 +7187,7 @@ public final class DebugProtoBuf { if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeMessage(5, flexibleUpperBound_); } + extensionWriter.writeUntil(200, output); getUnknownFields().writeTo(output); } @@ -7208,6 +7217,7 @@ public final class DebugProtoBuf { size += com.google.protobuf.CodedOutputStream .computeMessageSize(5, flexibleUpperBound_); } + size += extensionsSerializedSize(); size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -7290,8 +7300,8 @@ public final class DebugProtoBuf { * Protobuf type {@code org.jetbrains.kotlin.serialization.Type} */ public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder { + com.google.protobuf.GeneratedMessage.ExtendableBuilder< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Type, Builder> implements org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return org.jetbrains.kotlin.serialization.DebugProtoBuf.internal_static_org_jetbrains_kotlin_serialization_Type_descriptor; @@ -7464,6 +7474,7 @@ public final class DebugProtoBuf { if (other.hasFlexibleUpperBound()) { mergeFlexibleUpperBound(other.getFlexibleUpperBound()); } + this.mergeExtensionFields(other); this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -7489,6 +7500,10 @@ public final class DebugProtoBuf { return false; } } + if (!extensionsAreInitialized()) { + + return false; + } return true; } @@ -7909,7 +7924,7 @@ public final class DebugProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public boolean hasFlexibleTypeCapabilitiesId() { @@ -7921,7 +7936,7 @@ public final class DebugProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public int getFlexibleTypeCapabilitiesId() { @@ -7933,7 +7948,7 @@ public final class DebugProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public Builder setFlexibleTypeCapabilitiesId(int value) { @@ -7948,7 +7963,7 @@ public final class DebugProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public Builder clearFlexibleTypeCapabilitiesId() { @@ -9885,6 +9900,7 @@ public final class DebugProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ boolean hasData(); @@ -9894,6 +9910,7 @@ public final class DebugProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable getData(); @@ -9903,6 +9920,7 @@ public final class DebugProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ org.jetbrains.kotlin.serialization.DebugProtoBuf.CallableOrBuilder getDataOrBuilder(); @@ -10020,6 +10038,7 @@ public final class DebugProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ public boolean hasData() { @@ -10031,6 +10050,7 @@ public final class DebugProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ public org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable getData() { @@ -10042,6 +10062,7 @@ public final class DebugProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ public org.jetbrains.kotlin.serialization.DebugProtoBuf.CallableOrBuilder getDataOrBuilder() { @@ -10306,6 +10327,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public boolean hasData() { @@ -10317,6 +10339,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable getData() { @@ -10332,6 +10355,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder setData(org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable value) { @@ -10353,6 +10377,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder setData( @@ -10372,6 +10397,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder mergeData(org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable value) { @@ -10396,6 +10422,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder clearData() { @@ -10414,6 +10441,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public org.jetbrains.kotlin.serialization.DebugProtoBuf.Callable.Builder getDataBuilder() { @@ -10427,6 +10455,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public org.jetbrains.kotlin.serialization.DebugProtoBuf.CallableOrBuilder getDataOrBuilder() { @@ -10442,6 +10471,7 @@ public final class DebugProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ private com.google.protobuf.SingleFieldBuilder< @@ -17002,7 +17032,7 @@ public final class DebugProtoBuf { "\n\004BYTE\020\000\022\010\n\004CHAR\020\001\022\t\n\005SHORT\020\002\022\007\n\003INT\020\003\022\010" + "\n\004LONG\020\004\022\t\n\005FLOAT\020\005\022\n\n\006DOUBLE\020\006\022\013\n\007BOOLE" + "AN\020\007\022\n\n\006STRING\020\010\022\t\n\005CLASS\020\t\022\010\n\004ENUM\020\n\022\016\n" + - "\nANNOTATION\020\013\022\t\n\005ARRAY\020\014\"\377\004\n\004Type\022I\n\013con", + "\nANNOTATION\020\013\022\t\n\005ARRAY\020\014\"\206\005\n\004Type\022I\n\013con", "structor\030\001 \002(\01324.org.jetbrains.kotlin.se" + "rialization.Type.Constructor\022C\n\010argument" + "\030\002 \003(\01321.org.jetbrains.kotlin.serializat" + @@ -17018,55 +17048,55 @@ public final class DebugProtoBuf { "ialization.Type.Argument.Projection:\003INV" + "\0226\n\004type\030\002 \001(\0132(.org.jetbrains.kotlin.se" + "rialization.Type\"0\n\nProjection\022\006\n\002IN\020\000\022\007" + - "\n\003OUT\020\001\022\007\n\003INV\020\002\022\010\n\004STAR\020\003\"\371\001\n\rTypeParam" + - "eter\022\n\n\002id\030\001 \002(\005\022\014\n\004name\030\002 \002(\005\022\026\n\007reifie" + - "d\030\003 \001(\010:\005false\022Q\n\010variance\030\004 \001(\0162:.org.j" + - "etbrains.kotlin.serialization.TypeParame" + - "ter.Variance:\003INV\022=\n\013upper_bound\030\005 \003(\0132(", - ".org.jetbrains.kotlin.serialization.Type" + - "\"$\n\010Variance\022\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003INV\020\002\"\261" + - "\005\n\005Class\022\020\n\005flags\030\001 \001(\005:\0010\022\017\n\007fq_name\030\003 " + - "\002(\005\022\035\n\025companion_object_name\030\004 \001(\005\022I\n\016ty" + - "pe_parameter\030\005 \003(\01321.org.jetbrains.kotli" + - "n.serialization.TypeParameter\022;\n\tsuperty" + - "pe\030\006 \003(\0132(.org.jetbrains.kotlin.serializ" + - "ation.Type\022\031\n\021nested_class_name\030\007 \003(\005\022<\n" + - "\006member\030\013 \003(\0132,.org.jetbrains.kotlin.ser" + - "ialization.Callable\022\022\n\nenum_entry\030\014 \003(\005\022", - "Y\n\023primary_constructor\030\r \001(\0132<.org.jetbr" + - "ains.kotlin.serialization.Class.PrimaryC" + - "onstructor\022K\n\025secondary_constructor\030\016 \003(" + - "\0132,.org.jetbrains.kotlin.serialization.C" + - "allable\032P\n\022PrimaryConstructor\022:\n\004data\030\001 " + - "\001(\0132,.org.jetbrains.kotlin.serialization" + - ".Callable\"p\n\004Kind\022\t\n\005CLASS\020\000\022\t\n\005TRAIT\020\001\022" + - "\016\n\nENUM_CLASS\020\002\022\016\n\nENUM_ENTRY\020\003\022\024\n\020ANNOT" + - "ATION_CLASS\020\004\022\n\n\006OBJECT\020\005\022\020\n\014CLASS_OBJEC" + - "T\020\006*\005\010d\020\310\001\"N\n\007Package\022<\n\006member\030\001 \003(\0132,.", - "org.jetbrains.kotlin.serialization.Calla" + - "ble*\005\010d\020\310\001\"\300\005\n\010Callable\022\r\n\005flags\030\001 \001(\005\022\024" + - "\n\014getter_flags\030\t \001(\005\022\024\n\014setter_flags\030\n \001" + - "(\005\022I\n\016type_parameter\030\004 \003(\01321.org.jetbrai" + - "ns.kotlin.serialization.TypeParameter\022?\n" + - "\rreceiver_type\030\005 \001(\0132(.org.jetbrains.kot" + - "lin.serialization.Type\022\014\n\004name\030\006 \002(\005\022T\n\017" + - "value_parameter\030\007 \003(\0132;.org.jetbrains.ko" + - "tlin.serialization.Callable.ValueParamet" + - "er\022=\n\013return_type\030\010 \002(\0132(.org.jetbrains.", - "kotlin.serialization.Type\032\263\001\n\016ValueParam" + - "eter\022\r\n\005flags\030\001 \001(\005\022\014\n\004name\030\002 \002(\005\0226\n\004typ" + - "e\030\003 \002(\0132(.org.jetbrains.kotlin.serializa" + - "tion.Type\022E\n\023vararg_element_type\030\004 \001(\0132(" + - ".org.jetbrains.kotlin.serialization.Type" + - "*\005\010d\020\310\001\"Q\n\nMemberKind\022\017\n\013DECLARATION\020\000\022\021" + - "\n\rFAKE_OVERRIDE\020\001\022\016\n\nDELEGATION\020\002\022\017\n\013SYN" + - "THESIZED\020\003\":\n\014CallableKind\022\007\n\003FUN\020\000\022\007\n\003V" + - "AL\020\001\022\007\n\003VAR\020\002\022\017\n\013CONSTRUCTOR\020\003*\005\010d\020\310\001*-\n" + - "\010Modality\022\t\n\005FINAL\020\000\022\010\n\004OPEN\020\001\022\014\n\010ABSTRA", - "CT\020\002*b\n\nVisibility\022\014\n\010INTERNAL\020\000\022\013\n\007PRIV" + - "ATE\020\001\022\r\n\tPROTECTED\020\002\022\n\n\006PUBLIC\020\003\022\023\n\017PRIV" + - "ATE_TO_THIS\020\004\022\t\n\005LOCAL\020\005B\022B\rDebugProtoBu" + - "f\210\001\000" + "\n\003OUT\020\001\022\007\n\003INV\020\002\022\010\n\004STAR\020\003*\005\010d\020\310\001\"\371\001\n\rTy" + + "peParameter\022\n\n\002id\030\001 \002(\005\022\014\n\004name\030\002 \002(\005\022\026\n" + + "\007reified\030\003 \001(\010:\005false\022Q\n\010variance\030\004 \001(\0162" + + ":.org.jetbrains.kotlin.serialization.Typ" + + "eParameter.Variance:\003INV\022=\n\013upper_bound\030", + "\005 \003(\0132(.org.jetbrains.kotlin.serializati" + + "on.Type\"$\n\010Variance\022\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003" + + "INV\020\002\"\261\005\n\005Class\022\020\n\005flags\030\001 \001(\005:\0010\022\017\n\007fq_" + + "name\030\003 \002(\005\022\035\n\025companion_object_name\030\004 \001(" + + "\005\022I\n\016type_parameter\030\005 \003(\01321.org.jetbrain" + + "s.kotlin.serialization.TypeParameter\022;\n\t" + + "supertype\030\006 \003(\0132(.org.jetbrains.kotlin.s" + + "erialization.Type\022\031\n\021nested_class_name\030\007" + + " \003(\005\022<\n\006member\030\013 \003(\0132,.org.jetbrains.kot" + + "lin.serialization.Callable\022\022\n\nenum_entry", + "\030\014 \003(\005\022Y\n\023primary_constructor\030\r \001(\0132<.or" + + "g.jetbrains.kotlin.serialization.Class.P" + + "rimaryConstructor\022K\n\025secondary_construct" + + "or\030\016 \003(\0132,.org.jetbrains.kotlin.serializ" + + "ation.Callable\032P\n\022PrimaryConstructor\022:\n\004" + + "data\030\001 \001(\0132,.org.jetbrains.kotlin.serial" + + "ization.Callable\"p\n\004Kind\022\t\n\005CLASS\020\000\022\t\n\005T" + + "RAIT\020\001\022\016\n\nENUM_CLASS\020\002\022\016\n\nENUM_ENTRY\020\003\022\024" + + "\n\020ANNOTATION_CLASS\020\004\022\n\n\006OBJECT\020\005\022\020\n\014CLAS" + + "S_OBJECT\020\006*\005\010d\020\310\001\"N\n\007Package\022<\n\006member\030\001", + " \003(\0132,.org.jetbrains.kotlin.serializatio" + + "n.Callable*\005\010d\020\310\001\"\300\005\n\010Callable\022\r\n\005flags\030" + + "\001 \001(\005\022\024\n\014getter_flags\030\t \001(\005\022\024\n\014setter_fl" + + "ags\030\n \001(\005\022I\n\016type_parameter\030\004 \003(\01321.org." + + "jetbrains.kotlin.serialization.TypeParam" + + "eter\022?\n\rreceiver_type\030\005 \001(\0132(.org.jetbra" + + "ins.kotlin.serialization.Type\022\014\n\004name\030\006 " + + "\002(\005\022T\n\017value_parameter\030\007 \003(\0132;.org.jetbr" + + "ains.kotlin.serialization.Callable.Value" + + "Parameter\022=\n\013return_type\030\010 \002(\0132(.org.jet", + "brains.kotlin.serialization.Type\032\263\001\n\016Val" + + "ueParameter\022\r\n\005flags\030\001 \001(\005\022\014\n\004name\030\002 \002(\005" + + "\0226\n\004type\030\003 \002(\0132(.org.jetbrains.kotlin.se" + + "rialization.Type\022E\n\023vararg_element_type\030" + + "\004 \001(\0132(.org.jetbrains.kotlin.serializati" + + "on.Type*\005\010d\020\310\001\"Q\n\nMemberKind\022\017\n\013DECLARAT" + + "ION\020\000\022\021\n\rFAKE_OVERRIDE\020\001\022\016\n\nDELEGATION\020\002" + + "\022\017\n\013SYNTHESIZED\020\003\":\n\014CallableKind\022\007\n\003FUN" + + "\020\000\022\007\n\003VAL\020\001\022\007\n\003VAR\020\002\022\017\n\013CONSTRUCTOR\020\003*\005\010" + + "d\020\310\001*-\n\010Modality\022\t\n\005FINAL\020\000\022\010\n\004OPEN\020\001\022\014\n", + "\010ABSTRACT\020\002*b\n\nVisibility\022\014\n\010INTERNAL\020\000\022" + + "\013\n\007PRIVATE\020\001\022\r\n\tPROTECTED\020\002\022\n\n\006PUBLIC\020\003\022" + + "\023\n\017PRIVATE_TO_THIS\020\004\022\t\n\005LOCAL\020\005B\022B\rDebug" + + "ProtoBuf\210\001\000" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java b/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java index 4bd65be6481..032991632be 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java +++ b/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java @@ -10,6 +10,7 @@ public final class DebugJvmProtoBuf { registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.methodSignature); registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.propertySignature); registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.implClassName); + registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.typeAnnotation); registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.index); } public interface JvmTypeOrBuilder @@ -3762,6 +3763,17 @@ public final class DebugJvmProtoBuf { .newFileScopedGeneratedExtension( java.lang.Integer.class, null); + public static final int TYPE_ANNOTATION_FIELD_NUMBER = 100; + /** + * extend .org.jetbrains.kotlin.serialization.Type { ... } + */ + public static final + com.google.protobuf.GeneratedMessage.GeneratedExtension< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Type, + java.util.List> typeAnnotation = com.google.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class, + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); public static final int INDEX_FIELD_NUMBER = 100; /** * extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... } @@ -3837,9 +3849,12 @@ public final class DebugJvmProtoBuf { "jetbrains.kotlin.serialization.jvm.JvmPr" + "opertySignature:E\n\017impl_class_name\022,.org" + ".jetbrains.kotlin.serialization.Callable" + - "\030f \001(\005:J\n\005index\022;.org.jetbrains.kotlin.s" + - "erialization.Callable.ValueParameter\030d \001" + - "(\005B\022B\020DebugJvmProtoBuf" + "\030f \001(\005:q\n\017type_annotation\022(.org.jetbrain" + + "s.kotlin.serialization.Type\030d \003(\0132..org." + + "jetbrains.kotlin.serialization.Annotatio" + + "n:J\n\005index\022;.org.jetbrains.kotlin.serial" + + "ization.Callable.ValueParameter\030d \001(\005B\022B", + "\020DebugJvmProtoBuf" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -3873,7 +3888,8 @@ public final class DebugJvmProtoBuf { methodSignature.internalInit(descriptor.getExtensions().get(0)); propertySignature.internalInit(descriptor.getExtensions().get(1)); implClassName.internalInit(descriptor.getExtensions().get(2)); - index.internalInit(descriptor.getExtensions().get(3)); + typeAnnotation.internalInit(descriptor.getExtensions().get(3)); + index.internalInit(descriptor.getExtensions().get(4)); return null; } }; diff --git a/core/descriptor.loader.java/src/jvm_descriptors.proto b/core/descriptor.loader.java/src/jvm_descriptors.proto index 7040e5e53e8..44dc9ccfe3b 100644 --- a/core/descriptor.loader.java/src/jvm_descriptors.proto +++ b/core/descriptor.loader.java/src/jvm_descriptors.proto @@ -85,6 +85,10 @@ extend org.jetbrains.kotlin.serialization.Callable { optional int32 impl_class_name = 102; } +extend org.jetbrains.kotlin.serialization.Type { + repeated Annotation type_annotation = 100; +} + extend org.jetbrains.kotlin.serialization.Callable.ValueParameter { // Index of the corresponding parameter of this method in JVM (counting receiver parameters, enum constructor synthetic parameters, etc.) optional int32 index = 100; diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt index f1511cabf87..5075a007802 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt @@ -16,23 +16,27 @@ package org.jetbrains.kotlin.load.kotlin -import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils -import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor -import org.jetbrains.kotlin.types.ErrorUtils -import org.jetbrains.kotlin.storage.StorageManager -import java.util.* -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ArrayValue -import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl -import org.jetbrains.kotlin.resolve.constants.ErrorValue -import org.jetbrains.kotlin.resolve.constants.createCompileTimeConstant +import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils +import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.constants.* +import org.jetbrains.kotlin.serialization.ProtoBuf +import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer +import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter +import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies -import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf +import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.ErrorUtils +import java.util.ArrayList +import java.util.HashMap public class BinaryClassAnnotationAndConstantLoaderImpl( private val module: ModuleDescriptor, @@ -42,6 +46,13 @@ public class BinaryClassAnnotationAndConstantLoaderImpl( ) : AbstractBinaryClassAnnotationAndConstantLoader>( storageManager, kotlinClassFinder, errorReporter ) { + private val annotationDeserializer = AnnotationDeserializer(module) + + override fun loadTypeAnnotations(type: ProtoBuf.Type, nameResolver: NameResolver): List { + return type.getExtension(JvmProtoBuf.typeAnnotation).map { annotation -> + annotationDeserializer.deserializeAnnotation(annotation, nameResolver) + } + } override fun loadConstant(desc: String, initializer: Any): CompileTimeConstant<*>? { val normalizedValue: Any = if (desc in "ZBCS") { @@ -65,7 +76,6 @@ public class BinaryClassAnnotationAndConstantLoaderImpl( return compileTimeConstant } - override fun loadAnnotation( annotationClassId: ClassId, result: MutableList diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java index 7896f3cb693..b5305d7af5c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java @@ -10,6 +10,7 @@ public final class JvmProtoBuf { registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.methodSignature); registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertySignature); registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.implClassName); + registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.typeAnnotation); registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.index); } public interface JvmTypeOrBuilder @@ -2849,6 +2850,21 @@ public final class JvmProtoBuf { null, 102, com.google.protobuf.WireFormat.FieldType.INT32); + public static final int TYPE_ANNOTATION_FIELD_NUMBER = 100; + /** + * extend .org.jetbrains.kotlin.serialization.Type { ... } + */ + public static final + com.google.protobuf.GeneratedMessageLite.GeneratedExtension< + org.jetbrains.kotlin.serialization.ProtoBuf.Type, + java.util.List> typeAnnotation = com.google.protobuf.GeneratedMessageLite + .newRepeatedGeneratedExtension( + org.jetbrains.kotlin.serialization.ProtoBuf.Type.getDefaultInstance(), + org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.getDefaultInstance(), + null, + 100, + com.google.protobuf.WireFormat.FieldType.MESSAGE, + false); public static final int INDEX_FIELD_NUMBER = 100; /** * extend .org.jetbrains.kotlin.serialization.Callable.ValueParameter { ... } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsAnnotationAndConstantLoader.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsAnnotationAndConstantLoader.kt index 70abd699a48..25a8f685cd1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsAnnotationAndConstantLoader.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsAnnotationAndConstantLoader.kt @@ -16,12 +16,12 @@ package org.jetbrains.kotlin.builtins -import org.jetbrains.kotlin.serialization.* -import org.jetbrains.kotlin.serialization.deserialization.* -import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant +import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf +import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.types.JetType class BuiltInsAnnotationAndConstantLoader( @@ -58,6 +58,11 @@ class BuiltInsAnnotationAndConstantLoader( return annotations.map { proto -> deserializer.deserializeAnnotation(proto, nameResolver) } } + override fun loadTypeAnnotations(proto: ProtoBuf.Type, nameResolver: NameResolver): List { + // TODO: support type annotations in built-ins + return listOf() + } + override fun loadPropertyConstant( container: ProtoContainer, proto: ProtoBuf.Callable, diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java index 1538602042c..441aa3620d6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java @@ -443,6 +443,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { private String renderDefaultType(@NotNull JetType type) { StringBuilder sb = new StringBuilder(); + renderAnnotations(type, sb, /* needBrackets = */ true); + if (type.isError()) { sb.append(type.getConstructor().toString()); // Debug name of an error type is more informative } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractJetType.java b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractJetType.java index ff87120636a..0c756aeef85 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractJetType.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractJetType.java @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.types; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.types.checker.JetTypeChecker; import java.util.Iterator; @@ -54,19 +56,32 @@ public abstract class AbstractJetType implements JetType { @Override public String toString() { - List arguments = getArguments(); - return getConstructor() + (arguments.isEmpty() ? "" : "<" + argumentsToString(arguments) + ">") + (isMarkedNullable() ? "?" : ""); - } + StringBuilder sb = new StringBuilder(); - private static StringBuilder argumentsToString(List arguments) { - StringBuilder stringBuilder = new StringBuilder(); - for (Iterator iterator = arguments.iterator(); iterator.hasNext();) { - TypeProjection argument = iterator.next(); - stringBuilder.append(argument); - if (iterator.hasNext()) { - stringBuilder.append(", "); - } + for (AnnotationDescriptor annotation : getAnnotations()) { + sb.append("["); + sb.append(DescriptorRenderer.DEBUG_TEXT.renderAnnotation(annotation)); + sb.append("] "); } - return stringBuilder; + + sb.append(getConstructor()); + + List arguments = getArguments(); + if (!arguments.isEmpty()) { + sb.append("<"); + for (Iterator i = arguments.iterator(); i.hasNext(); ) { + sb.append(i.next()); + if (i.hasNext()) { + sb.append(", "); + } + } + sb.append(">"); + } + + if (isMarkedNullable()) { + sb.append("?"); + } + + return sb.toString(); } } diff --git a/core/deserialization/src/descriptors.proto b/core/deserialization/src/descriptors.proto index 132caba62ff..06fd2915a1f 100644 --- a/core/deserialization/src/descriptors.proto +++ b/core/deserialization/src/descriptors.proto @@ -130,13 +130,15 @@ message Type { // Id in the StringTable // If this field is set, the type is flexible. - // All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound. + // All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound. optional int32 flexible_type_capabilities_id = 4; // While such an "indirect" encoding helps backwards compatibility with pre-flexible-types versions of this format, // we use it mainly to save space: having a special mandatory tag on each an every type just to have an option // to represent flexible types is too many wasted bytes. optional Type flexible_upper_bound = 5; + + extensions 100 to 199; } message TypeParameter { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java b/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java index 7156e3b55c9..b26eef19689 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java @@ -4276,8 +4276,9 @@ public final class ProtoBuf { // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.Annotation) } - public interface TypeOrBuilder - extends com.google.protobuf.MessageLiteOrBuilder { + public interface TypeOrBuilder extends + com.google.protobuf.GeneratedMessageLite. + ExtendableMessageOrBuilder { // required .org.jetbrains.kotlin.serialization.Type.Constructor constructor = 1; /** @@ -4321,7 +4322,7 @@ public final class ProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ boolean hasFlexibleTypeCapabilitiesId(); @@ -4331,7 +4332,7 @@ public final class ProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ int getFlexibleTypeCapabilitiesId(); @@ -4362,10 +4363,10 @@ public final class ProtoBuf { * Protobuf type {@code org.jetbrains.kotlin.serialization.Type} */ public static final class Type extends - com.google.protobuf.GeneratedMessageLite - implements TypeOrBuilder { + com.google.protobuf.GeneratedMessageLite.ExtendableMessage< + Type> implements TypeOrBuilder { // Use Type.newBuilder() to construct. - private Type(com.google.protobuf.GeneratedMessageLite.Builder builder) { + private Type(com.google.protobuf.GeneratedMessageLite.ExtendableBuilder builder) { super(builder); } @@ -5652,7 +5653,7 @@ public final class ProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ public boolean hasFlexibleTypeCapabilitiesId() { @@ -5664,7 +5665,7 @@ public final class ProtoBuf { *
      * Id in the StringTable
      * If this field is set, the type is flexible.
-     * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+     * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
      * 
*/ public int getFlexibleTypeCapabilitiesId() { @@ -5731,6 +5732,10 @@ public final class ProtoBuf { return false; } } + if (!extensionsAreInitialized()) { + memoizedIsInitialized = 0; + return false; + } memoizedIsInitialized = 1; return true; } @@ -5738,6 +5743,9 @@ public final class ProtoBuf { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); + com.google.protobuf.GeneratedMessageLite + .ExtendableMessage.ExtensionWriter extensionWriter = + newExtensionWriter(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeMessage(1, constructor_); } @@ -5753,6 +5761,7 @@ public final class ProtoBuf { if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeMessage(5, flexibleUpperBound_); } + extensionWriter.writeUntil(200, output); } private int memoizedSerializedSize = -1; @@ -5781,6 +5790,7 @@ public final class ProtoBuf { size += com.google.protobuf.CodedOutputStream .computeMessageSize(5, flexibleUpperBound_); } + size += extensionsSerializedSize(); memoizedSerializedSize = size; return size; } @@ -5856,9 +5866,8 @@ public final class ProtoBuf { * Protobuf type {@code org.jetbrains.kotlin.serialization.Type} */ public static final class Builder extends - com.google.protobuf.GeneratedMessageLite.Builder< - org.jetbrains.kotlin.serialization.ProtoBuf.Type, Builder> - implements org.jetbrains.kotlin.serialization.ProtoBuf.TypeOrBuilder { + com.google.protobuf.GeneratedMessageLite.ExtendableBuilder< + org.jetbrains.kotlin.serialization.ProtoBuf.Type, Builder> implements org.jetbrains.kotlin.serialization.ProtoBuf.TypeOrBuilder { // Construct using org.jetbrains.kotlin.serialization.ProtoBuf.Type.newBuilder() private Builder() { maybeForceBuilderInitialization(); @@ -5954,6 +5963,7 @@ public final class ProtoBuf { if (other.hasFlexibleUpperBound()) { mergeFlexibleUpperBound(other.getFlexibleUpperBound()); } + this.mergeExtensionFields(other); return this; } @@ -5978,6 +5988,10 @@ public final class ProtoBuf { return false; } } + if (!extensionsAreInitialized()) { + + return false; + } return true; } @@ -6227,7 +6241,7 @@ public final class ProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public boolean hasFlexibleTypeCapabilitiesId() { @@ -6239,7 +6253,7 @@ public final class ProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public int getFlexibleTypeCapabilitiesId() { @@ -6251,7 +6265,7 @@ public final class ProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public Builder setFlexibleTypeCapabilitiesId(int value) { @@ -6266,7 +6280,7 @@ public final class ProtoBuf { *
        * Id in the StringTable
        * If this field is set, the type is flexible.
-       * All the fields above represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
+       * All the other fields and extensions represent its lower bound, and flexible_upper_bound must be set and represents its upper bound.
        * 
*/ public Builder clearFlexibleTypeCapabilitiesId() { @@ -7793,6 +7807,7 @@ public final class ProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ boolean hasData(); @@ -7802,6 +7817,7 @@ public final class ProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ org.jetbrains.kotlin.serialization.ProtoBuf.Callable getData(); @@ -7898,6 +7914,7 @@ public final class ProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ public boolean hasData() { @@ -7909,6 +7926,7 @@ public final class ProtoBuf { *
        * If this field is present, it contains serialized data for the primary constructor.
        * Otherwise it's default and can be created manually upon deserialization
+       * Note: currently only objects have default primary constructor
        * 
*/ public org.jetbrains.kotlin.serialization.ProtoBuf.Callable getData() { @@ -8120,6 +8138,7 @@ public final class ProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public boolean hasData() { @@ -8131,6 +8150,7 @@ public final class ProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public org.jetbrains.kotlin.serialization.ProtoBuf.Callable getData() { @@ -8142,6 +8162,7 @@ public final class ProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder setData(org.jetbrains.kotlin.serialization.ProtoBuf.Callable value) { @@ -8159,6 +8180,7 @@ public final class ProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder setData( @@ -8174,6 +8196,7 @@ public final class ProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder mergeData(org.jetbrains.kotlin.serialization.ProtoBuf.Callable value) { @@ -8194,6 +8217,7 @@ public final class ProtoBuf { *
          * If this field is present, it contains serialized data for the primary constructor.
          * Otherwise it's default and can be created manually upon deserialization
+         * Note: currently only objects have default primary constructor
          * 
*/ public Builder clearData() { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.java b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.java index 66d363002a9..3bddc831d6c 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.java +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.java @@ -47,6 +47,12 @@ public interface AnnotationAndConstantLoader { @NotNull ProtoBuf.Callable.ValueParameter proto ); + @NotNull + List loadTypeAnnotations( + @NotNull ProtoBuf.Type type, + @NotNull NameResolver nameResolver + ); + @Nullable C loadPropertyConstant( @NotNull ProtoContainer container, diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt index 65e622e47d8..97ccf95f120 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt @@ -16,11 +16,13 @@ package org.jetbrains.kotlin.serialization.deserialization -import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.scopes.JetScope +import org.jetbrains.kotlin.serialization.ProtoBuf +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.utils.toReadOnlyList @@ -42,7 +44,16 @@ class DeserializedType( } private val memberScope = c.storageManager.createLazyValue { - computeMemberScope() + if (isError()) { + ErrorUtils.createErrorScope(getConstructor().toString()) + } + else { + getTypeMemberScope(getConstructor(), getArguments()) + } + } + + private val annotations = DeserializedAnnotations(c.storageManager) { + c.components.annotationAndConstantLoader.loadTypeAnnotations(typeProto, c.nameResolver) } override fun getConstructor(): TypeConstructor = constructor() @@ -51,14 +62,6 @@ class DeserializedType( override fun isMarkedNullable(): Boolean = typeProto.getNullable() - private fun computeMemberScope(): JetScope = - if (isError()) { - ErrorUtils.createErrorScope(getConstructor().toString()) - } - else { - getTypeMemberScope(getConstructor(), getArguments()) - } - private fun getTypeMemberScope(constructor: TypeConstructor, typeArguments: List): JetScope { val descriptor = constructor.getDeclarationDescriptor() return when (descriptor) { @@ -75,7 +78,7 @@ class DeserializedType( return descriptor != null && ErrorUtils.isError(descriptor) } - override fun getAnnotations(): Annotations = Annotations.EMPTY + override fun getAnnotations(): Annotations = annotations private fun List.getOrNull(index: Int): E? { return if (index in indices) this[index] else null diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt index 3331c4bc1d5..8e33c08a91c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt @@ -92,6 +92,11 @@ class AnnotationLoaderForStubBuilder( errorReporter: ErrorReporter ) : AbstractBinaryClassAnnotationAndConstantLoader( LockBasedStorageManager.NO_LOCKS, kotlinClassFinder, errorReporter) { + override fun loadTypeAnnotations(type: ProtoBuf.Type, nameResolver: NameResolver): MutableList { + // TODO: support type annotations in cls stubs + throw UnsupportedOperationException() + } + override fun loadConstant(desc: String, initializer: Any) = null override fun loadAnnotation(annotationClassId: ClassId, result: MutableList): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java index 4c0bf48b80a..6400a517c82 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/ResolveByStubTestGenerated.java @@ -417,6 +417,33 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest { doTest(fileName); } } + + @TestMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Types extends AbstractResolveByStubTest { + public void testAllFilesPresentInTypes() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/annotations/types"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("ReceiverParameter.kt") + public void testReceiverParameter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/ReceiverParameter.kt"); + doTest(fileName); + } + + @TestMetadata("SimpleTypeAnnotation.kt") + public void testSimpleTypeAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/SimpleTypeAnnotation.kt"); + doTest(fileName); + } + + @TestMetadata("TypeAnnotationWithArguments.kt") + public void testTypeAnnotationWithArguments() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/types/TypeAnnotationWithArguments.kt"); + doTest(fileName); + } + } } @TestMetadata("compiler/testData/loadJava/compiledKotlin/class")