diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 767fb8bd3c6..904f631ba19 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -232,7 +232,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; DescriptorSerializer serializer = - DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings())); + DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), typeMapper)); ProtoBuf.Class classProto = serializer.classProto(descriptor).build(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java index 7065e89bed9..6270ce0bb2f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmSerializerExtension.java @@ -19,29 +19,33 @@ package org.jetbrains.kotlin.codegen; import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.serialization.deserialization.NameResolver; -import org.jetbrains.kotlin.serialization.ProtoBuf; -import org.jetbrains.kotlin.serialization.SerializerExtension; -import org.jetbrains.kotlin.serialization.StringTable; -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor; -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor; +import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.serialization.ProtoBuf; +import org.jetbrains.kotlin.serialization.SerializerExtension; +import org.jetbrains.kotlin.serialization.StringTable; +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.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.Arrays; +import static org.jetbrains.kotlin.codegen.AsmUtil.shortNameByAsmType; import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*; public class JvmSerializerExtension extends SerializerExtension { private final JvmSerializationBindings bindings; + private final JetTypeMapper typeMapper; - public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings) { + public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull JetTypeMapper typeMapper) { this.bindings = bindings; + this.typeMapper = typeMapper; } @Override @@ -66,6 +70,12 @@ public class JvmSerializerExtension extends SerializerExtension { } } + @Override + @NotNull + public String getLocalClassName(@NotNull ClassDescriptor descriptor) { + return shortNameByAsmType(typeMapper.mapClass(descriptor)); + } + private void saveSignature( @NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java index a426e9d0ec2..57d95ebadf3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java @@ -270,7 +270,7 @@ public class PackageCodegen { if (file.isScript()) return; } - DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings)); + DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings, state.getTypeMapper())); Collection packageFragments = Lists.newArrayList(); ContainerUtil.addIfNotNull(packageFragments, packageFragment); ContainerUtil.addIfNotNull(packageFragments, compiledPackageFragment); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java index 515c37ed96e..a3ca6f30259 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/FileBasedKotlinClass.java @@ -56,7 +56,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { public final String outerInternalName; public final String innerSimpleName; - private OuterAndInnerName(@NotNull String outerInternalName, @NotNull String innerSimpleName) { + private OuterAndInnerName(@Nullable String outerInternalName, @Nullable String innerSimpleName) { this.outerInternalName = outerInternalName; this.innerSimpleName = innerSimpleName; } @@ -65,7 +65,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { protected static class InnerClassesInfo { private Map map = null; - public void add(@NotNull String name, @NotNull String outerName, @NotNull String innerName) { + public void add(@NotNull String name, @Nullable String outerName, @Nullable String innerName) { if (map == null) { map = new HashMap(); } @@ -98,9 +98,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { @Override public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) { - if (outerName != null && innerName != null) { - innerClasses.add(name, outerName, innerName); - } + innerClasses.add(name, outerName, innerName); } @Override @@ -268,10 +266,15 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { } List classes = new ArrayList(1); + boolean local = false; while (true) { OuterAndInnerName outer = innerClasses.get(name); if (outer == null) break; + if (outer.outerInternalName == null) { + local = true; + break; + } classes.add(outer.innerSimpleName); name = outer.outerInternalName; } @@ -283,7 +286,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { FqName packageFqName = outermostClassFqName.parent(); FqNameUnsafe relativeClassName = FqNameUnsafe.fromSegments(classes); - return new ClassId(packageFqName, relativeClassName); + return new ClassId(packageFqName, relativeClassName, local); } @Override diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java index 55da37a725a..88ec2e8a50e 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java +++ b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java @@ -1024,6 +1024,10 @@ public final class DebugProtoBuf { * PACKAGE = 1; */ PACKAGE(1, 1), + /** + * LOCAL = 2; + */ + LOCAL(2, 2), ; /** @@ -1034,6 +1038,10 @@ public final class DebugProtoBuf { * PACKAGE = 1; */ public static final int PACKAGE_VALUE = 1; + /** + * LOCAL = 2; + */ + public static final int LOCAL_VALUE = 2; public final int getNumber() { return value; } @@ -1042,6 +1050,7 @@ public final class DebugProtoBuf { switch (value) { case 0: return CLASS; case 1: return PACKAGE; + case 2: return LOCAL; default: return null; } } @@ -16536,95 +16545,96 @@ public final class DebugProtoBuf { java.lang.String[] descriptorData = { "\n.core/serialization/src/descriptors.deb" + "ug.proto\022\"org.jetbrains.kotlin.serializa" + - "tion\"\035\n\013StringTable\022\016\n\006string\030\001 \003(\t\"\275\002\n\022" + + "tion\"\035\n\013StringTable\022\016\n\006string\030\001 \003(\t\"\310\002\n\022" + "QualifiedNameTable\022\\\n\016qualified_name\030\001 \003" + "(\0132D.org.jetbrains.kotlin.serialization." + - "QualifiedNameTable.QualifiedName\032\310\001\n\rQua" + + "QualifiedNameTable.QualifiedName\032\323\001\n\rQua" + "lifiedName\022!\n\025parent_qualified_name\030\001 \001(" + "\005:\002-1\022\022\n\nshort_name\030\002 \002(\005\022`\n\004kind\030\003 \001(\0162" + "I.org.jetbrains.kotlin.serialization.Qua" + "lifiedNameTable.QualifiedName.Kind:\007PACK", - "AGE\"\036\n\004Kind\022\t\n\005CLASS\020\000\022\013\n\007PACKAGE\020\001\"\335\005\n\n" + - "Annotation\022\n\n\002id\030\001 \002(\005\022I\n\010argument\030\002 \003(\013" + - "27.org.jetbrains.kotlin.serialization.An" + - "notation.Argument\032\367\004\n\010Argument\022\017\n\007name_i" + - "d\030\001 \002(\005\022L\n\005value\030\002 \002(\0132=.org.jetbrains.k" + - "otlin.serialization.Annotation.Argument." + - "Value\032\213\004\n\005Value\022P\n\004type\030\001 \001(\0162B.org.jetb" + - "rains.kotlin.serialization.Annotation.Ar" + - "gument.Value.Type\022\021\n\tint_value\030\002 \001(\022\022\023\n\013" + - "float_value\030\003 \001(\002\022\024\n\014double_value\030\004 \001(\001\022", - "\024\n\014string_value\030\005 \001(\005\022\020\n\010class_id\030\006 \001(\005\022" + - "\025\n\renum_value_id\030\007 \001(\005\022B\n\nannotation\030\010 \001" + - "(\0132..org.jetbrains.kotlin.serialization." + - "Annotation\022T\n\rarray_element\030\t \003(\0132=.org." + + "AGE\")\n\004Kind\022\t\n\005CLASS\020\000\022\013\n\007PACKAGE\020\001\022\t\n\005L" + + "OCAL\020\002\"\335\005\n\nAnnotation\022\n\n\002id\030\001 \002(\005\022I\n\010arg" + + "ument\030\002 \003(\01327.org.jetbrains.kotlin.seria" + + "lization.Annotation.Argument\032\367\004\n\010Argumen" + + "t\022\017\n\007name_id\030\001 \002(\005\022L\n\005value\030\002 \002(\0132=.org." + "jetbrains.kotlin.serialization.Annotatio" + - "n.Argument.Value\"\230\001\n\004Type\022\010\n\004BYTE\020\000\022\010\n\004C" + - "HAR\020\001\022\t\n\005SHORT\020\002\022\007\n\003INT\020\003\022\010\n\004LONG\020\004\022\t\n\005F" + - "LOAT\020\005\022\n\n\006DOUBLE\020\006\022\013\n\007BOOLEAN\020\007\022\n\n\006STRIN" + - "G\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\013constructor\030\001 \002(", - "\01324.org.jetbrains.kotlin.serialization.T" + - "ype.Constructor\022C\n\010argument\030\002 \003(\01321.org." + - "jetbrains.kotlin.serialization.Type.Argu" + - "ment\022\027\n\010nullable\030\003 \001(\010:\005false\022%\n\035flexibl" + - "e_type_capabilities_id\030\004 \001(\005\022F\n\024flexible" + - "_upper_bound\030\005 \001(\0132(.org.jetbrains.kotli" + - "n.serialization.Type\032\220\001\n\013Constructor\022N\n\004" + - "kind\030\001 \001(\01629.org.jetbrains.kotlin.serial" + - "ization.Type.Constructor.Kind:\005CLASS\022\n\n\002" + - "id\030\002 \002(\005\"%\n\004Kind\022\t\n\005CLASS\020\000\022\022\n\016TYPE_PARA", - "METER\020\001\032\313\001\n\010Argument\022U\n\nprojection\030\001 \001(\016" + - "2<.org.jetbrains.kotlin.serialization.Ty" + - "pe.Argument.Projection:\003INV\0226\n\004type\030\002 \002(" + - "\0132(.org.jetbrains.kotlin.serialization.T" + - "ype\"0\n\nProjection\022\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003IN" + - "V\020\002\022\010\n\004STAR\020\003\"\371\001\n\rTypeParameter\022\n\n\002id\030\001 " + - "\002(\005\022\014\n\004name\030\002 \002(\005\022\026\n\007reified\030\003 \001(\010:\005fals" + - "e\022Q\n\010variance\030\004 \001(\0162:.org.jetbrains.kotl" + - "in.serialization.TypeParameter.Variance:" + - "\003INV\022=\n\013upper_bound\030\005 \003(\0132(.org.jetbrain", - "s.kotlin.serialization.Type\"$\n\010Variance\022" + - "\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003INV\020\002\"\340\004\n\005Class\022\020\n\005f" + - "lags\030\001 \001(\005:\0010\022\017\n\007fq_name\030\003 \002(\005\022\031\n\021class_" + - "object_name\030\004 \001(\005\022I\n\016type_parameter\030\005 \003(" + - "\01321.org.jetbrains.kotlin.serialization.T" + - "ypeParameter\022;\n\tsupertype\030\006 \003(\0132(.org.je" + - "tbrains.kotlin.serialization.Type\022\031\n\021nes" + - "ted_class_name\030\007 \003(\005\022<\n\006member\030\013 \003(\0132,.o" + - "rg.jetbrains.kotlin.serialization.Callab" + - "le\022\022\n\nenum_entry\030\014 \003(\005\022Y\n\023primary_constr", - "uctor\030\r \001(\0132<.org.jetbrains.kotlin.seria" + - "lization.Class.PrimaryConstructor\032P\n\022Pri" + - "maryConstructor\022:\n\004data\030\001 \001(\0132,.org.jetb" + - "rains.kotlin.serialization.Callable\"p\n\004K" + - "ind\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\020ANNOTATION_CLASS\020\004\022" + - "\n\n\006OBJECT\020\005\022\020\n\014CLASS_OBJECT\020\006*\005\010d\020\310\001\"N\n\007" + - "Package\022<\n\006member\030\001 \003(\0132,.org.jetbrains." + - "kotlin.serialization.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_flags\030\n \001(\005\022I\n\016type_par" + - "ameter\030\004 \003(\01321.org.jetbrains.kotlin.seri" + - "alization.TypeParameter\022?\n\rreceiver_type" + - "\030\005 \001(\0132(.org.jetbrains.kotlin.serializat" + - "ion.Type\022\014\n\004name\030\006 \002(\005\022T\n\017value_paramete" + - "r\030\007 \003(\0132;.org.jetbrains.kotlin.serializa" + - "tion.Callable.ValueParameter\022=\n\013return_t" + - "ype\030\010 \002(\0132(.org.jetbrains.kotlin.seriali" + - "zation.Type\032\263\001\n\016ValueParameter\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.serialization.Type\022E\n\023v" + - "ararg_element_type\030\004 \001(\0132(.org.jetbrains" + - ".kotlin.serialization.Type*\005\010d\020\310\001\"Q\n\nMem" + - "berKind\022\017\n\013DECLARATION\020\000\022\021\n\rFAKE_OVERRID" + - "E\020\001\022\016\n\nDELEGATION\020\002\022\017\n\013SYNTHESIZED\020\003\":\n\014" + - "CallableKind\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\010d\020\310\001*-\n\010Modality\022\t\n\005F" + - "INAL\020\000\022\010\n\004OPEN\020\001\022\014\n\010ABSTRACT\020\002*b\n\nVisibi" + - "lity\022\014\n\010INTERNAL\020\000\022\013\n\007PRIVATE\020\001\022\r\n\tPROTE" + - "CTED\020\002\022\n\n\006PUBLIC\020\003\022\023\n\017PRIVATE_TO_THIS\020\004\022", - "\t\n\005LOCAL\020\005B\022B\rDebugProtoBuf\210\001\000" + "n.Argument.Value\032\213\004\n\005Value\022P\n\004type\030\001 \001(\016" + + "2B.org.jetbrains.kotlin.serialization.An" + + "notation.Argument.Value.Type\022\021\n\tint_valu" + + "e\030\002 \001(\022\022\023\n\013float_value\030\003 \001(\002\022\024\n\014double_v", + "alue\030\004 \001(\001\022\024\n\014string_value\030\005 \001(\005\022\020\n\010clas" + + "s_id\030\006 \001(\005\022\025\n\renum_value_id\030\007 \001(\005\022B\n\nann" + + "otation\030\010 \001(\0132..org.jetbrains.kotlin.ser" + + "ialization.Annotation\022T\n\rarray_element\030\t" + + " \003(\0132=.org.jetbrains.kotlin.serializatio" + + "n.Annotation.Argument.Value\"\230\001\n\004Type\022\010\n\004" + + "BYTE\020\000\022\010\n\004CHAR\020\001\022\t\n\005SHORT\020\002\022\007\n\003INT\020\003\022\010\n\004" + + "LONG\020\004\022\t\n\005FLOAT\020\005\022\n\n\006DOUBLE\020\006\022\013\n\007BOOLEAN" + + "\020\007\022\n\n\006STRING\020\010\022\t\n\005CLASS\020\t\022\010\n\004ENUM\020\n\022\016\n\nA" + + "NNOTATION\020\013\022\t\n\005ARRAY\020\014\"\377\004\n\004Type\022I\n\013const", + "ructor\030\001 \002(\01324.org.jetbrains.kotlin.seri" + + "alization.Type.Constructor\022C\n\010argument\030\002" + + " \003(\01321.org.jetbrains.kotlin.serializatio" + + "n.Type.Argument\022\027\n\010nullable\030\003 \001(\010:\005false" + + "\022%\n\035flexible_type_capabilities_id\030\004 \001(\005\022" + + "F\n\024flexible_upper_bound\030\005 \001(\0132(.org.jetb" + + "rains.kotlin.serialization.Type\032\220\001\n\013Cons" + + "tructor\022N\n\004kind\030\001 \001(\01629.org.jetbrains.ko" + + "tlin.serialization.Type.Constructor.Kind" + + ":\005CLASS\022\n\n\002id\030\002 \002(\005\"%\n\004Kind\022\t\n\005CLASS\020\000\022\022", + "\n\016TYPE_PARAMETER\020\001\032\313\001\n\010Argument\022U\n\nproje" + + "ction\030\001 \001(\0162<.org.jetbrains.kotlin.seria" + + "lization.Type.Argument.Projection:\003INV\0226" + + "\n\004type\030\002 \002(\0132(.org.jetbrains.kotlin.seri" + + "alization.Type\"0\n\nProjection\022\006\n\002IN\020\000\022\007\n\003" + + "OUT\020\001\022\007\n\003INV\020\002\022\010\n\004STAR\020\003\"\371\001\n\rTypeParamet" + + "er\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.jet" + + "brains.kotlin.serialization.TypeParamete" + + "r.Variance:\003INV\022=\n\013upper_bound\030\005 \003(\0132(.o", + "rg.jetbrains.kotlin.serialization.Type\"$" + + "\n\010Variance\022\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003INV\020\002\"\340\004\n" + + "\005Class\022\020\n\005flags\030\001 \001(\005:\0010\022\017\n\007fq_name\030\003 \002(" + + "\005\022\031\n\021class_object_name\030\004 \001(\005\022I\n\016type_par" + + "ameter\030\005 \003(\01321.org.jetbrains.kotlin.seri" + + "alization.TypeParameter\022;\n\tsupertype\030\006 \003" + + "(\0132(.org.jetbrains.kotlin.serialization." + + "Type\022\031\n\021nested_class_name\030\007 \003(\005\022<\n\006membe" + + "r\030\013 \003(\0132,.org.jetbrains.kotlin.serializa" + + "tion.Callable\022\022\n\nenum_entry\030\014 \003(\005\022Y\n\023pri", + "mary_constructor\030\r \001(\0132<.org.jetbrains.k" + + "otlin.serialization.Class.PrimaryConstru" + + "ctor\032P\n\022PrimaryConstructor\022:\n\004data\030\001 \001(\013" + + "2,.org.jetbrains.kotlin.serialization.Ca" + + "llable\"p\n\004Kind\022\t\n\005CLASS\020\000\022\t\n\005TRAIT\020\001\022\016\n\n" + + "ENUM_CLASS\020\002\022\016\n\nENUM_ENTRY\020\003\022\024\n\020ANNOTATI" + + "ON_CLASS\020\004\022\n\n\006OBJECT\020\005\022\020\n\014CLASS_OBJECT\020\006" + + "*\005\010d\020\310\001\"N\n\007Package\022<\n\006member\030\001 \003(\0132,.org" + + ".jetbrains.kotlin.serialization.Callable" + + "*\005\010d\020\310\001\"\300\005\n\010Callable\022\r\n\005flags\030\001 \001(\005\022\024\n\014g", + "etter_flags\030\t \001(\005\022\024\n\014setter_flags\030\n \001(\005\022" + + "I\n\016type_parameter\030\004 \003(\01321.org.jetbrains." + + "kotlin.serialization.TypeParameter\022?\n\rre" + + "ceiver_type\030\005 \001(\0132(.org.jetbrains.kotlin" + + ".serialization.Type\022\014\n\004name\030\006 \002(\005\022T\n\017val" + + "ue_parameter\030\007 \003(\0132;.org.jetbrains.kotli" + + "n.serialization.Callable.ValueParameter\022" + + "=\n\013return_type\030\010 \002(\0132(.org.jetbrains.kot" + + "lin.serialization.Type\032\263\001\n\016ValueParamete" + + "r\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.serializatio" + + "n.Type\022E\n\023vararg_element_type\030\004 \001(\0132(.or" + + "g.jetbrains.kotlin.serialization.Type*\005\010" + + "d\020\310\001\"Q\n\nMemberKind\022\017\n\013DECLARATION\020\000\022\021\n\rF" + + "AKE_OVERRIDE\020\001\022\016\n\nDELEGATION\020\002\022\017\n\013SYNTHE" + + "SIZED\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\010d\020\310\001*-\n\010Mo" + + "dality\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\rDebugProtoBuf\210\001" + + "\000" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaClassDataFinder.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaClassDataFinder.kt index 8ec5245a569..01d902b2c18 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaClassDataFinder.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaClassDataFinder.kt @@ -28,6 +28,9 @@ public class JavaClassDataFinder( ) : ClassDataFinder { override fun findClassData(classId: ClassId): ClassData? { val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) ?: return null + assert(kotlinJvmBinaryClass.getClassId() == classId) { + "Class with incorrect id found: expected $classId, actual ${kotlinJvmBinaryClass.getClassId()}" + } val data = deserializedDescriptorResolver.readData(kotlinJvmBinaryClass, KotlinClassHeader.Kind.CLASS) ?: return null return JvmProtoBufUtil.readClassDataFrom(data) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java b/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java index 1d1f7bf13b1..20929b9527d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java +++ b/core/descriptors/src/org/jetbrains/kotlin/name/ClassId.java @@ -18,6 +18,15 @@ package org.jetbrains.kotlin.name; import org.jetbrains.annotations.NotNull; +/** + * A class name which is used to uniquely identify a Kotlin class. + * + * If local = true, the class represented by this id is either itself local or is an inner class of some local class. This also means that + * the first non-class container of the class is not a package. + * In the case of a local class, relativeClassName consists of a single name including all callables' and class' names all the way up to + * the package, separated by dollar signs. If a class is an inner of local, relativeClassName would consist of two names, + * the second one being the class' short name. + */ public final class ClassId { @NotNull public static ClassId topLevel(@NotNull FqName topLevelFqName) { @@ -26,15 +35,18 @@ public final class ClassId { private final FqName packageFqName; private final FqNameUnsafe relativeClassName; + private final boolean local; - public ClassId(@NotNull FqName packageFqName, @NotNull FqNameUnsafe relativeClassName) { + public ClassId(@NotNull FqName packageFqName, @NotNull FqNameUnsafe relativeClassName, boolean local) { this.packageFqName = packageFqName; - assert !relativeClassName.isRoot() : "Class name must not be root. " + packageFqName; + assert !relativeClassName.isRoot() : + "Class name must not be root: " + packageFqName + (local ? " (local)" : ""); this.relativeClassName = relativeClassName; + this.local = local; } public ClassId(@NotNull FqName packageFqName, @NotNull Name topLevelName) { - this(packageFqName, FqNameUnsafe.topLevel(topLevelName)); + this(packageFqName, FqNameUnsafe.topLevel(topLevelName), false); } @NotNull @@ -47,14 +59,18 @@ public final class ClassId { return relativeClassName; } + public boolean isLocal() { + return local; + } + @NotNull public ClassId createNestedClassId(@NotNull Name name) { - return new ClassId(getPackageFqName(), relativeClassName.child(name)); + return new ClassId(getPackageFqName(), relativeClassName.child(name), local); } @NotNull public ClassId getOuterClassId() { - return new ClassId(getPackageFqName(), relativeClassName.parent()); + return new ClassId(getPackageFqName(), relativeClassName.parent(), local); } public boolean isNestedClass() { @@ -74,16 +90,16 @@ public final class ClassId { ClassId id = (ClassId) o; - if (!packageFqName.equals(id.packageFqName)) return false; - if (!relativeClassName.equals(id.relativeClassName)) return false; - - return true; + return packageFqName.equals(id.packageFqName) && + relativeClassName.equals(id.relativeClassName) && + local == id.local; } @Override public int hashCode() { int result = packageFqName.hashCode(); result = 31 * result + relativeClassName.hashCode(); + result = 31 * result + Boolean.valueOf(local).hashCode(); return result; } diff --git a/core/serialization/src/descriptors.proto b/core/serialization/src/descriptors.proto index 5a387deb413..ee882316716 100644 --- a/core/serialization/src/descriptors.proto +++ b/core/serialization/src/descriptors.proto @@ -35,6 +35,7 @@ message QualifiedNameTable { enum Kind { CLASS = 0; PACKAGE = 1; + LOCAL = 2; } } diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java b/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java index 6609431f02c..5322f6b4bc5 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.java @@ -29,7 +29,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject; public class DescriptorSerializer { @@ -45,7 +46,7 @@ public class DescriptorSerializer { @NotNull public static DescriptorSerializer createTopLevel(@NotNull SerializerExtension extension) { - return new DescriptorSerializer(new StringTable(), new Interner(), extension); + return new DescriptorSerializer(new StringTable(extension), new Interner(), extension); } @NotNull @@ -210,42 +211,14 @@ public class DescriptorSerializer { builder.addValueParameter(local.valueParameter(valueParameterDescriptor)); } - builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType()))); + //noinspection ConstantConditions + builder.setReturnType(local.type(descriptor.getReturnType())); extension.serializeCallable(descriptor, builder, stringTable); return builder; } - @NotNull - private static JetType getSerializableReturnType(@NotNull JetType type) { - return isSerializableType(type) ? type : KotlinBuiltIns.getInstance().getAnyType(); - } - - /** - * @return true iff this type can be serialized. Types which correspond to type parameters, top-level classes, inner classes, and - * generic classes with serializable arguments are serializable. For other types (local classes, inner of local, etc.) it may be - * problematical to construct a FQ name for serialization - */ - private static boolean isSerializableType(@NotNull JetType type) { - ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); - if (descriptor instanceof TypeParameterDescriptor) { - return true; - } - else if (descriptor instanceof ClassDescriptor) { - for (TypeProjection projection : type.getArguments()) { - if (!isSerializableType(projection.getType())) { - return false; - } - } - - return isTopLevelOrInnerClass((ClassDescriptor) descriptor); - } - else { - throw new IllegalStateException("Unknown type constructor: " + type); - } - } - private static int getAccessorFlags(@NotNull PropertyAccessorDescriptor accessor) { return Flags.getAccessorFlags( hasAnnotations(accessor), diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java b/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java index 9f6944052b4..c7c556209f8 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java @@ -855,6 +855,10 @@ public final class ProtoBuf { * PACKAGE = 1; */ PACKAGE(1, 1), + /** + * LOCAL = 2; + */ + LOCAL(2, 2), ; /** @@ -865,6 +869,10 @@ public final class ProtoBuf { * PACKAGE = 1; */ public static final int PACKAGE_VALUE = 1; + /** + * LOCAL = 2; + */ + public static final int LOCAL_VALUE = 2; public final int getNumber() { return value; } @@ -873,6 +881,7 @@ public final class ProtoBuf { switch (value) { case 0: return CLASS; case 1: return PACKAGE; + case 2: return LOCAL; default: return null; } } diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java b/core/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java index eda2def896a..b0eb4c52233 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.java @@ -52,4 +52,9 @@ public abstract class SerializerExtension { @NotNull StringTable stringTable ) { } + + @NotNull + public String getLocalClassName(@NotNull ClassDescriptor descriptor) { + throw new UnsupportedOperationException("Local classes are unsupported: " + descriptor); + } } diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/StringTable.java b/core/serialization/src/org/jetbrains/kotlin/serialization/StringTable.java index 7590e2fafe7..6da0a05db48 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/StringTable.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/StringTable.java @@ -60,6 +60,11 @@ public class StringTable { private final Interner strings = new Interner(); private final Interner qualifiedNames = new Interner(); + private final SerializerExtension extension; + + public StringTable(@NotNull SerializerExtension extension) { + this.extension = extension; + } @NotNull public List getStrings() { @@ -89,23 +94,33 @@ public class StringTable { if (descriptor instanceof ClassDescriptor) { builder.setKind(QualifiedName.Kind.CLASS); } - builder.setShortName(getSimpleNameIndex(descriptor.getName())); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); + int shortName; if (containingDeclaration instanceof PackageFragmentDescriptor) { + shortName = getSimpleNameIndex(descriptor.getName()); PackageFragmentDescriptor fragment = (PackageFragmentDescriptor) containingDeclaration; if (!fragment.getFqName().isRoot()) { builder.setParentQualifiedName(getFqNameIndex(fragment.getFqName())); } } else if (containingDeclaration instanceof ClassDescriptor) { + shortName = getSimpleNameIndex(descriptor.getName()); ClassDescriptor outerClass = (ClassDescriptor) containingDeclaration; builder.setParentQualifiedName(getFqNameIndex(outerClass)); } else { - throw new IllegalStateException("FQ names are only stored for top-level or inner classes: " + descriptor); + if (descriptor instanceof ClassDescriptor) { + builder.setKind(QualifiedName.Kind.LOCAL); + shortName = getStringIndex(extension.getLocalClassName((ClassDescriptor) descriptor)); + } + else { + throw new IllegalStateException("Package container should be a package: " + descriptor); + } } + builder.setShortName(shortName); + return qualifiedNames.intern(new FqNameProto(builder)); } diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/NameResolver.java b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/NameResolver.java index ad0fe2f5577..8a63f78f69b 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/NameResolver.java +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/NameResolver.java @@ -17,13 +17,14 @@ package org.jetbrains.kotlin.serialization.deserialization; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.serialization.ProtoBuf; +import java.util.LinkedList; + import static org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName; public class NameResolver { @@ -61,42 +62,30 @@ public class NameResolver { @NotNull public ClassId getClassId(int index) { - QualifiedName fqNameProto = qualifiedNames.getQualifiedName(index); - assert fqNameProto.getKind() == ProtoBuf.QualifiedNameTable.QualifiedName.Kind.CLASS : "Not a class fqName: " + fqNameProto.getKind(); + LinkedList packageFqName = new LinkedList(); + LinkedList relativeClassName = new LinkedList(); + boolean local = false; - StringBuilder relativeClassName = new StringBuilder(); - QualifiedName packageFqNameProto = renderFqName(relativeClassName, fqNameProto, QualifiedName.Kind.CLASS); - - FqName packageFqName; - if (packageFqNameProto != null) { - StringBuilder sb = new StringBuilder(); - QualifiedName mustBeNull = renderFqName(sb, packageFqNameProto, QualifiedName.Kind.PACKAGE); - assert mustBeNull == null : "Prefix of an fqName must be all of kind PACKAGE"; - - packageFqName = new FqName(sb.toString()); - } - else { - packageFqName = FqName.ROOT; - } - - return new ClassId(packageFqName, new FqNameUnsafe(relativeClassName.toString())); - } - - @Nullable - private QualifiedName renderFqName(StringBuilder sb, QualifiedName fqNameProto, QualifiedName.Kind kind) { - QualifiedName result = null; - if (fqNameProto.hasParentQualifiedName()) { - QualifiedName parentProto = qualifiedNames.getQualifiedName(fqNameProto.getParentQualifiedName()); - if (kind == null || parentProto.getKind() == kind) { - result = renderFqName(sb, parentProto, kind); - sb.append("."); - } - else { - result = parentProto; + while (index != -1) { + QualifiedName proto = qualifiedNames.getQualifiedName(index); + String shortName = strings.getString(proto.getShortName()); + switch (proto.getKind()) { + case CLASS: + relativeClassName.addFirst(shortName); + break; + case PACKAGE: + packageFqName.addFirst(shortName); + break; + case LOCAL: + relativeClassName.addFirst(shortName); + local = true; + break; } + + index = proto.getParentQualifiedName(); } - sb.append(strings.getString(fqNameProto.getShortName())); - return result; + + return new ClassId(FqName.fromSegments(packageFqName), FqNameUnsafe.fromSegments(relativeClassName), local); } @NotNull diff --git a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index 0ffab2cd46e..c17f05ce7a5 100644 --- a/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/serialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -90,8 +90,14 @@ public class TypeDeserializer( typeParameterDescriptors().get(proto.getId())?.getTypeConstructor() ?: parent?.typeParameterTypeConstructor(proto) - private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? = - c.components.moduleDescriptor.findClassAcrossModuleDependencies(c.nameResolver.getClassId(fqNameIndex)) + private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? { + val id = c.nameResolver.getClassId(fqNameIndex) + if (id.isLocal()) { + // Local classes can't be found in scopes + return c.components.deserializeClass(id) + } + return c.components.moduleDescriptor.findClassAcrossModuleDependencies(id) + } fun typeArguments(protos: List): List = protos.map { proto ->