Support serialization/deserialization of local classes
Most of these changes are aimed to support and correctly transform ClassId for local classes, no actual bytes are written or read at the moment (see next commits). See the comment on ClassId for clarification. A hack in DescriptorSerializer which erased anonymous types to Any (which had been breaking the consistency between descriptors resolved from sources and from serialized information) is now gone
This commit is contained in:
@@ -232,7 +232,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||||
|
|
||||||
DescriptorSerializer serializer =
|
DescriptorSerializer serializer =
|
||||||
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings()));
|
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), typeMapper));
|
||||||
|
|
||||||
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
||||||
|
|
||||||
|
|||||||
@@ -19,29 +19,33 @@ package org.jetbrains.kotlin.codegen;
|
|||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver;
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||||
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.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer;
|
import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
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.kotlin.serialization.jvm.JvmProtoBuf;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.AsmUtil.shortNameByAsmType;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
|
import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
|
||||||
|
|
||||||
public class JvmSerializerExtension extends SerializerExtension {
|
public class JvmSerializerExtension extends SerializerExtension {
|
||||||
private final JvmSerializationBindings bindings;
|
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.bindings = bindings;
|
||||||
|
this.typeMapper = typeMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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(
|
private void saveSignature(
|
||||||
@NotNull CallableMemberDescriptor callable,
|
@NotNull CallableMemberDescriptor callable,
|
||||||
@NotNull ProtoBuf.Callable.Builder proto,
|
@NotNull ProtoBuf.Callable.Builder proto,
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ public class PackageCodegen {
|
|||||||
if (file.isScript()) return;
|
if (file.isScript()) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings));
|
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings, state.getTypeMapper()));
|
||||||
Collection<PackageFragmentDescriptor> packageFragments = Lists.newArrayList();
|
Collection<PackageFragmentDescriptor> packageFragments = Lists.newArrayList();
|
||||||
ContainerUtil.addIfNotNull(packageFragments, packageFragment);
|
ContainerUtil.addIfNotNull(packageFragments, packageFragment);
|
||||||
ContainerUtil.addIfNotNull(packageFragments, compiledPackageFragment);
|
ContainerUtil.addIfNotNull(packageFragments, compiledPackageFragment);
|
||||||
|
|||||||
+9
-6
@@ -56,7 +56,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
public final String outerInternalName;
|
public final String outerInternalName;
|
||||||
public final String innerSimpleName;
|
public final String innerSimpleName;
|
||||||
|
|
||||||
private OuterAndInnerName(@NotNull String outerInternalName, @NotNull String innerSimpleName) {
|
private OuterAndInnerName(@Nullable String outerInternalName, @Nullable String innerSimpleName) {
|
||||||
this.outerInternalName = outerInternalName;
|
this.outerInternalName = outerInternalName;
|
||||||
this.innerSimpleName = innerSimpleName;
|
this.innerSimpleName = innerSimpleName;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
protected static class InnerClassesInfo {
|
protected static class InnerClassesInfo {
|
||||||
private Map<String, OuterAndInnerName> map = null;
|
private Map<String, OuterAndInnerName> 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) {
|
if (map == null) {
|
||||||
map = new HashMap<String, OuterAndInnerName>();
|
map = new HashMap<String, OuterAndInnerName>();
|
||||||
}
|
}
|
||||||
@@ -98,9 +98,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) {
|
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
|
@Override
|
||||||
@@ -268,10 +266,15 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<String> classes = new ArrayList<String>(1);
|
List<String> classes = new ArrayList<String>(1);
|
||||||
|
boolean local = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
OuterAndInnerName outer = innerClasses.get(name);
|
OuterAndInnerName outer = innerClasses.get(name);
|
||||||
if (outer == null) break;
|
if (outer == null) break;
|
||||||
|
if (outer.outerInternalName == null) {
|
||||||
|
local = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
classes.add(outer.innerSimpleName);
|
classes.add(outer.innerSimpleName);
|
||||||
name = outer.outerInternalName;
|
name = outer.outerInternalName;
|
||||||
}
|
}
|
||||||
@@ -283,7 +286,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
|
|
||||||
FqName packageFqName = outermostClassFqName.parent();
|
FqName packageFqName = outermostClassFqName.parent();
|
||||||
FqNameUnsafe relativeClassName = FqNameUnsafe.fromSegments(classes);
|
FqNameUnsafe relativeClassName = FqNameUnsafe.fromSegments(classes);
|
||||||
return new ClassId(packageFqName, relativeClassName);
|
return new ClassId(packageFqName, relativeClassName, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1024,6 +1024,10 @@ public final class DebugProtoBuf {
|
|||||||
* <code>PACKAGE = 1;</code>
|
* <code>PACKAGE = 1;</code>
|
||||||
*/
|
*/
|
||||||
PACKAGE(1, 1),
|
PACKAGE(1, 1),
|
||||||
|
/**
|
||||||
|
* <code>LOCAL = 2;</code>
|
||||||
|
*/
|
||||||
|
LOCAL(2, 2),
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1034,6 +1038,10 @@ public final class DebugProtoBuf {
|
|||||||
* <code>PACKAGE = 1;</code>
|
* <code>PACKAGE = 1;</code>
|
||||||
*/
|
*/
|
||||||
public static final int PACKAGE_VALUE = 1;
|
public static final int PACKAGE_VALUE = 1;
|
||||||
|
/**
|
||||||
|
* <code>LOCAL = 2;</code>
|
||||||
|
*/
|
||||||
|
public static final int LOCAL_VALUE = 2;
|
||||||
|
|
||||||
|
|
||||||
public final int getNumber() { return value; }
|
public final int getNumber() { return value; }
|
||||||
@@ -1042,6 +1050,7 @@ public final class DebugProtoBuf {
|
|||||||
switch (value) {
|
switch (value) {
|
||||||
case 0: return CLASS;
|
case 0: return CLASS;
|
||||||
case 1: return PACKAGE;
|
case 1: return PACKAGE;
|
||||||
|
case 2: return LOCAL;
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16536,95 +16545,96 @@ public final class DebugProtoBuf {
|
|||||||
java.lang.String[] descriptorData = {
|
java.lang.String[] descriptorData = {
|
||||||
"\n.core/serialization/src/descriptors.deb" +
|
"\n.core/serialization/src/descriptors.deb" +
|
||||||
"ug.proto\022\"org.jetbrains.kotlin.serializa" +
|
"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" +
|
"QualifiedNameTable\022\\\n\016qualified_name\030\001 \003" +
|
||||||
"(\0132D.org.jetbrains.kotlin.serialization." +
|
"(\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(" +
|
"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" +
|
"\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" +
|
"I.org.jetbrains.kotlin.serialization.Qua" +
|
||||||
"lifiedNameTable.QualifiedName.Kind:\007PACK",
|
"lifiedNameTable.QualifiedName.Kind:\007PACK",
|
||||||
"AGE\"\036\n\004Kind\022\t\n\005CLASS\020\000\022\013\n\007PACKAGE\020\001\"\335\005\n\n" +
|
"AGE\")\n\004Kind\022\t\n\005CLASS\020\000\022\013\n\007PACKAGE\020\001\022\t\n\005L" +
|
||||||
"Annotation\022\n\n\002id\030\001 \002(\005\022I\n\010argument\030\002 \003(\013" +
|
"OCAL\020\002\"\335\005\n\nAnnotation\022\n\n\002id\030\001 \002(\005\022I\n\010arg" +
|
||||||
"27.org.jetbrains.kotlin.serialization.An" +
|
"ument\030\002 \003(\01327.org.jetbrains.kotlin.seria" +
|
||||||
"notation.Argument\032\367\004\n\010Argument\022\017\n\007name_i" +
|
"lization.Annotation.Argument\032\367\004\n\010Argumen" +
|
||||||
"d\030\001 \002(\005\022L\n\005value\030\002 \002(\0132=.org.jetbrains.k" +
|
"t\022\017\n\007name_id\030\001 \002(\005\022L\n\005value\030\002 \002(\0132=.org." +
|
||||||
"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." +
|
|
||||||
"jetbrains.kotlin.serialization.Annotatio" +
|
"jetbrains.kotlin.serialization.Annotatio" +
|
||||||
"n.Argument.Value\"\230\001\n\004Type\022\010\n\004BYTE\020\000\022\010\n\004C" +
|
"n.Argument.Value\032\213\004\n\005Value\022P\n\004type\030\001 \001(\016" +
|
||||||
"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" +
|
"2B.org.jetbrains.kotlin.serialization.An" +
|
||||||
"LOAT\020\005\022\n\n\006DOUBLE\020\006\022\013\n\007BOOLEAN\020\007\022\n\n\006STRIN" +
|
"notation.Argument.Value.Type\022\021\n\tint_valu" +
|
||||||
"G\020\010\022\t\n\005CLASS\020\t\022\010\n\004ENUM\020\n\022\016\n\nANNOTATION\020\013" +
|
"e\030\002 \001(\022\022\023\n\013float_value\030\003 \001(\002\022\024\n\014double_v",
|
||||||
"\022\t\n\005ARRAY\020\014\"\377\004\n\004Type\022I\n\013constructor\030\001 \002(",
|
"alue\030\004 \001(\001\022\024\n\014string_value\030\005 \001(\005\022\020\n\010clas" +
|
||||||
"\01324.org.jetbrains.kotlin.serialization.T" +
|
"s_id\030\006 \001(\005\022\025\n\renum_value_id\030\007 \001(\005\022B\n\nann" +
|
||||||
"ype.Constructor\022C\n\010argument\030\002 \003(\01321.org." +
|
"otation\030\010 \001(\0132..org.jetbrains.kotlin.ser" +
|
||||||
"jetbrains.kotlin.serialization.Type.Argu" +
|
"ialization.Annotation\022T\n\rarray_element\030\t" +
|
||||||
"ment\022\027\n\010nullable\030\003 \001(\010:\005false\022%\n\035flexibl" +
|
" \003(\0132=.org.jetbrains.kotlin.serializatio" +
|
||||||
"e_type_capabilities_id\030\004 \001(\005\022F\n\024flexible" +
|
"n.Annotation.Argument.Value\"\230\001\n\004Type\022\010\n\004" +
|
||||||
"_upper_bound\030\005 \001(\0132(.org.jetbrains.kotli" +
|
"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" +
|
||||||
"n.serialization.Type\032\220\001\n\013Constructor\022N\n\004" +
|
"LONG\020\004\022\t\n\005FLOAT\020\005\022\n\n\006DOUBLE\020\006\022\013\n\007BOOLEAN" +
|
||||||
"kind\030\001 \001(\01629.org.jetbrains.kotlin.serial" +
|
"\020\007\022\n\n\006STRING\020\010\022\t\n\005CLASS\020\t\022\010\n\004ENUM\020\n\022\016\n\nA" +
|
||||||
"ization.Type.Constructor.Kind:\005CLASS\022\n\n\002" +
|
"NNOTATION\020\013\022\t\n\005ARRAY\020\014\"\377\004\n\004Type\022I\n\013const",
|
||||||
"id\030\002 \002(\005\"%\n\004Kind\022\t\n\005CLASS\020\000\022\022\n\016TYPE_PARA",
|
"ructor\030\001 \002(\01324.org.jetbrains.kotlin.seri" +
|
||||||
"METER\020\001\032\313\001\n\010Argument\022U\n\nprojection\030\001 \001(\016" +
|
"alization.Type.Constructor\022C\n\010argument\030\002" +
|
||||||
"2<.org.jetbrains.kotlin.serialization.Ty" +
|
" \003(\01321.org.jetbrains.kotlin.serializatio" +
|
||||||
"pe.Argument.Projection:\003INV\0226\n\004type\030\002 \002(" +
|
"n.Type.Argument\022\027\n\010nullable\030\003 \001(\010:\005false" +
|
||||||
"\0132(.org.jetbrains.kotlin.serialization.T" +
|
"\022%\n\035flexible_type_capabilities_id\030\004 \001(\005\022" +
|
||||||
"ype\"0\n\nProjection\022\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003IN" +
|
"F\n\024flexible_upper_bound\030\005 \001(\0132(.org.jetb" +
|
||||||
"V\020\002\022\010\n\004STAR\020\003\"\371\001\n\rTypeParameter\022\n\n\002id\030\001 " +
|
"rains.kotlin.serialization.Type\032\220\001\n\013Cons" +
|
||||||
"\002(\005\022\014\n\004name\030\002 \002(\005\022\026\n\007reified\030\003 \001(\010:\005fals" +
|
"tructor\022N\n\004kind\030\001 \001(\01629.org.jetbrains.ko" +
|
||||||
"e\022Q\n\010variance\030\004 \001(\0162:.org.jetbrains.kotl" +
|
"tlin.serialization.Type.Constructor.Kind" +
|
||||||
"in.serialization.TypeParameter.Variance:" +
|
":\005CLASS\022\n\n\002id\030\002 \002(\005\"%\n\004Kind\022\t\n\005CLASS\020\000\022\022",
|
||||||
"\003INV\022=\n\013upper_bound\030\005 \003(\0132(.org.jetbrain",
|
"\n\016TYPE_PARAMETER\020\001\032\313\001\n\010Argument\022U\n\nproje" +
|
||||||
"s.kotlin.serialization.Type\"$\n\010Variance\022" +
|
"ction\030\001 \001(\0162<.org.jetbrains.kotlin.seria" +
|
||||||
"\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" +
|
"lization.Type.Argument.Projection:\003INV\0226" +
|
||||||
"lags\030\001 \001(\005:\0010\022\017\n\007fq_name\030\003 \002(\005\022\031\n\021class_" +
|
"\n\004type\030\002 \002(\0132(.org.jetbrains.kotlin.seri" +
|
||||||
"object_name\030\004 \001(\005\022I\n\016type_parameter\030\005 \003(" +
|
"alization.Type\"0\n\nProjection\022\006\n\002IN\020\000\022\007\n\003" +
|
||||||
"\01321.org.jetbrains.kotlin.serialization.T" +
|
"OUT\020\001\022\007\n\003INV\020\002\022\010\n\004STAR\020\003\"\371\001\n\rTypeParamet" +
|
||||||
"ypeParameter\022;\n\tsupertype\030\006 \003(\0132(.org.je" +
|
"er\022\n\n\002id\030\001 \002(\005\022\014\n\004name\030\002 \002(\005\022\026\n\007reified\030" +
|
||||||
"tbrains.kotlin.serialization.Type\022\031\n\021nes" +
|
"\003 \001(\010:\005false\022Q\n\010variance\030\004 \001(\0162:.org.jet" +
|
||||||
"ted_class_name\030\007 \003(\005\022<\n\006member\030\013 \003(\0132,.o" +
|
"brains.kotlin.serialization.TypeParamete" +
|
||||||
"rg.jetbrains.kotlin.serialization.Callab" +
|
"r.Variance:\003INV\022=\n\013upper_bound\030\005 \003(\0132(.o",
|
||||||
"le\022\022\n\nenum_entry\030\014 \003(\005\022Y\n\023primary_constr",
|
"rg.jetbrains.kotlin.serialization.Type\"$" +
|
||||||
"uctor\030\r \001(\0132<.org.jetbrains.kotlin.seria" +
|
"\n\010Variance\022\006\n\002IN\020\000\022\007\n\003OUT\020\001\022\007\n\003INV\020\002\"\340\004\n" +
|
||||||
"lization.Class.PrimaryConstructor\032P\n\022Pri" +
|
"\005Class\022\020\n\005flags\030\001 \001(\005:\0010\022\017\n\007fq_name\030\003 \002(" +
|
||||||
"maryConstructor\022:\n\004data\030\001 \001(\0132,.org.jetb" +
|
"\005\022\031\n\021class_object_name\030\004 \001(\005\022I\n\016type_par" +
|
||||||
"rains.kotlin.serialization.Callable\"p\n\004K" +
|
"ameter\030\005 \003(\01321.org.jetbrains.kotlin.seri" +
|
||||||
"ind\022\t\n\005CLASS\020\000\022\t\n\005TRAIT\020\001\022\016\n\nENUM_CLASS\020" +
|
"alization.TypeParameter\022;\n\tsupertype\030\006 \003" +
|
||||||
"\002\022\016\n\nENUM_ENTRY\020\003\022\024\n\020ANNOTATION_CLASS\020\004\022" +
|
"(\0132(.org.jetbrains.kotlin.serialization." +
|
||||||
"\n\n\006OBJECT\020\005\022\020\n\014CLASS_OBJECT\020\006*\005\010d\020\310\001\"N\n\007" +
|
"Type\022\031\n\021nested_class_name\030\007 \003(\005\022<\n\006membe" +
|
||||||
"Package\022<\n\006member\030\001 \003(\0132,.org.jetbrains." +
|
"r\030\013 \003(\0132,.org.jetbrains.kotlin.serializa" +
|
||||||
"kotlin.serialization.Callable*\005\010d\020\310\001\"\300\005\n" +
|
"tion.Callable\022\022\n\nenum_entry\030\014 \003(\005\022Y\n\023pri",
|
||||||
"\010Callable\022\r\n\005flags\030\001 \001(\005\022\024\n\014getter_flags",
|
"mary_constructor\030\r \001(\0132<.org.jetbrains.k" +
|
||||||
"\030\t \001(\005\022\024\n\014setter_flags\030\n \001(\005\022I\n\016type_par" +
|
"otlin.serialization.Class.PrimaryConstru" +
|
||||||
"ameter\030\004 \003(\01321.org.jetbrains.kotlin.seri" +
|
"ctor\032P\n\022PrimaryConstructor\022:\n\004data\030\001 \001(\013" +
|
||||||
"alization.TypeParameter\022?\n\rreceiver_type" +
|
"2,.org.jetbrains.kotlin.serialization.Ca" +
|
||||||
"\030\005 \001(\0132(.org.jetbrains.kotlin.serializat" +
|
"llable\"p\n\004Kind\022\t\n\005CLASS\020\000\022\t\n\005TRAIT\020\001\022\016\n\n" +
|
||||||
"ion.Type\022\014\n\004name\030\006 \002(\005\022T\n\017value_paramete" +
|
"ENUM_CLASS\020\002\022\016\n\nENUM_ENTRY\020\003\022\024\n\020ANNOTATI" +
|
||||||
"r\030\007 \003(\0132;.org.jetbrains.kotlin.serializa" +
|
"ON_CLASS\020\004\022\n\n\006OBJECT\020\005\022\020\n\014CLASS_OBJECT\020\006" +
|
||||||
"tion.Callable.ValueParameter\022=\n\013return_t" +
|
"*\005\010d\020\310\001\"N\n\007Package\022<\n\006member\030\001 \003(\0132,.org" +
|
||||||
"ype\030\010 \002(\0132(.org.jetbrains.kotlin.seriali" +
|
".jetbrains.kotlin.serialization.Callable" +
|
||||||
"zation.Type\032\263\001\n\016ValueParameter\022\r\n\005flags\030" +
|
"*\005\010d\020\310\001\"\300\005\n\010Callable\022\r\n\005flags\030\001 \001(\005\022\024\n\014g",
|
||||||
"\001 \001(\005\022\014\n\004name\030\002 \002(\005\0226\n\004type\030\003 \002(\0132(.org.",
|
"etter_flags\030\t \001(\005\022\024\n\014setter_flags\030\n \001(\005\022" +
|
||||||
"jetbrains.kotlin.serialization.Type\022E\n\023v" +
|
"I\n\016type_parameter\030\004 \003(\01321.org.jetbrains." +
|
||||||
"ararg_element_type\030\004 \001(\0132(.org.jetbrains" +
|
"kotlin.serialization.TypeParameter\022?\n\rre" +
|
||||||
".kotlin.serialization.Type*\005\010d\020\310\001\"Q\n\nMem" +
|
"ceiver_type\030\005 \001(\0132(.org.jetbrains.kotlin" +
|
||||||
"berKind\022\017\n\013DECLARATION\020\000\022\021\n\rFAKE_OVERRID" +
|
".serialization.Type\022\014\n\004name\030\006 \002(\005\022T\n\017val" +
|
||||||
"E\020\001\022\016\n\nDELEGATION\020\002\022\017\n\013SYNTHESIZED\020\003\":\n\014" +
|
"ue_parameter\030\007 \003(\0132;.org.jetbrains.kotli" +
|
||||||
"CallableKind\022\007\n\003FUN\020\000\022\007\n\003VAL\020\001\022\007\n\003VAR\020\002\022" +
|
"n.serialization.Callable.ValueParameter\022" +
|
||||||
"\017\n\013CONSTRUCTOR\020\003*\005\010d\020\310\001*-\n\010Modality\022\t\n\005F" +
|
"=\n\013return_type\030\010 \002(\0132(.org.jetbrains.kot" +
|
||||||
"INAL\020\000\022\010\n\004OPEN\020\001\022\014\n\010ABSTRACT\020\002*b\n\nVisibi" +
|
"lin.serialization.Type\032\263\001\n\016ValueParamete" +
|
||||||
"lity\022\014\n\010INTERNAL\020\000\022\013\n\007PRIVATE\020\001\022\r\n\tPROTE" +
|
"r\022\r\n\005flags\030\001 \001(\005\022\014\n\004name\030\002 \002(\005\0226\n\004type\030\003",
|
||||||
"CTED\020\002\022\n\n\006PUBLIC\020\003\022\023\n\017PRIVATE_TO_THIS\020\004\022",
|
" \002(\0132(.org.jetbrains.kotlin.serializatio" +
|
||||||
"\t\n\005LOCAL\020\005B\022B\rDebugProtoBuf\210\001\000"
|
"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 =
|
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||||
|
|||||||
+3
@@ -28,6 +28,9 @@ public class JavaClassDataFinder(
|
|||||||
) : ClassDataFinder {
|
) : ClassDataFinder {
|
||||||
override fun findClassData(classId: ClassId): ClassData? {
|
override fun findClassData(classId: ClassId): ClassData? {
|
||||||
val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) ?: return null
|
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
|
val data = deserializedDescriptorResolver.readData(kotlinJvmBinaryClass, KotlinClassHeader.Kind.CLASS) ?: return null
|
||||||
return JvmProtoBufUtil.readClassDataFrom(data)
|
return JvmProtoBufUtil.readClassDataFrom(data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ package org.jetbrains.kotlin.name;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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 {
|
public final class ClassId {
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ClassId topLevel(@NotNull FqName topLevelFqName) {
|
public static ClassId topLevel(@NotNull FqName topLevelFqName) {
|
||||||
@@ -26,15 +35,18 @@ public final class ClassId {
|
|||||||
|
|
||||||
private final FqName packageFqName;
|
private final FqName packageFqName;
|
||||||
private final FqNameUnsafe relativeClassName;
|
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;
|
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.relativeClassName = relativeClassName;
|
||||||
|
this.local = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassId(@NotNull FqName packageFqName, @NotNull Name topLevelName) {
|
public ClassId(@NotNull FqName packageFqName, @NotNull Name topLevelName) {
|
||||||
this(packageFqName, FqNameUnsafe.topLevel(topLevelName));
|
this(packageFqName, FqNameUnsafe.topLevel(topLevelName), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -47,14 +59,18 @@ public final class ClassId {
|
|||||||
return relativeClassName;
|
return relativeClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isLocal() {
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassId createNestedClassId(@NotNull Name name) {
|
public ClassId createNestedClassId(@NotNull Name name) {
|
||||||
return new ClassId(getPackageFqName(), relativeClassName.child(name));
|
return new ClassId(getPackageFqName(), relativeClassName.child(name), local);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassId getOuterClassId() {
|
public ClassId getOuterClassId() {
|
||||||
return new ClassId(getPackageFqName(), relativeClassName.parent());
|
return new ClassId(getPackageFqName(), relativeClassName.parent(), local);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNestedClass() {
|
public boolean isNestedClass() {
|
||||||
@@ -74,16 +90,16 @@ public final class ClassId {
|
|||||||
|
|
||||||
ClassId id = (ClassId) o;
|
ClassId id = (ClassId) o;
|
||||||
|
|
||||||
if (!packageFqName.equals(id.packageFqName)) return false;
|
return packageFqName.equals(id.packageFqName) &&
|
||||||
if (!relativeClassName.equals(id.relativeClassName)) return false;
|
relativeClassName.equals(id.relativeClassName) &&
|
||||||
|
local == id.local;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = packageFqName.hashCode();
|
int result = packageFqName.hashCode();
|
||||||
result = 31 * result + relativeClassName.hashCode();
|
result = 31 * result + relativeClassName.hashCode();
|
||||||
|
result = 31 * result + Boolean.valueOf(local).hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ message QualifiedNameTable {
|
|||||||
enum Kind {
|
enum Kind {
|
||||||
CLASS = 0;
|
CLASS = 0;
|
||||||
PACKAGE = 1;
|
PACKAGE = 1;
|
||||||
|
LOCAL = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-32
@@ -29,7 +29,8 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
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 {
|
public class DescriptorSerializer {
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ public class DescriptorSerializer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static DescriptorSerializer createTopLevel(@NotNull SerializerExtension extension) {
|
public static DescriptorSerializer createTopLevel(@NotNull SerializerExtension extension) {
|
||||||
return new DescriptorSerializer(new StringTable(), new Interner<TypeParameterDescriptor>(), extension);
|
return new DescriptorSerializer(new StringTable(extension), new Interner<TypeParameterDescriptor>(), extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -210,42 +211,14 @@ public class DescriptorSerializer {
|
|||||||
builder.addValueParameter(local.valueParameter(valueParameterDescriptor));
|
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);
|
extension.serializeCallable(descriptor, builder, stringTable);
|
||||||
|
|
||||||
return builder;
|
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) {
|
private static int getAccessorFlags(@NotNull PropertyAccessorDescriptor accessor) {
|
||||||
return Flags.getAccessorFlags(
|
return Flags.getAccessorFlags(
|
||||||
hasAnnotations(accessor),
|
hasAnnotations(accessor),
|
||||||
|
|||||||
@@ -855,6 +855,10 @@ public final class ProtoBuf {
|
|||||||
* <code>PACKAGE = 1;</code>
|
* <code>PACKAGE = 1;</code>
|
||||||
*/
|
*/
|
||||||
PACKAGE(1, 1),
|
PACKAGE(1, 1),
|
||||||
|
/**
|
||||||
|
* <code>LOCAL = 2;</code>
|
||||||
|
*/
|
||||||
|
LOCAL(2, 2),
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -865,6 +869,10 @@ public final class ProtoBuf {
|
|||||||
* <code>PACKAGE = 1;</code>
|
* <code>PACKAGE = 1;</code>
|
||||||
*/
|
*/
|
||||||
public static final int PACKAGE_VALUE = 1;
|
public static final int PACKAGE_VALUE = 1;
|
||||||
|
/**
|
||||||
|
* <code>LOCAL = 2;</code>
|
||||||
|
*/
|
||||||
|
public static final int LOCAL_VALUE = 2;
|
||||||
|
|
||||||
|
|
||||||
public final int getNumber() { return value; }
|
public final int getNumber() { return value; }
|
||||||
@@ -873,6 +881,7 @@ public final class ProtoBuf {
|
|||||||
switch (value) {
|
switch (value) {
|
||||||
case 0: return CLASS;
|
case 0: return CLASS;
|
||||||
case 1: return PACKAGE;
|
case 1: return PACKAGE;
|
||||||
|
case 2: return LOCAL;
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,4 +52,9 @@ public abstract class SerializerExtension {
|
|||||||
@NotNull StringTable stringTable
|
@NotNull StringTable stringTable
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getLocalClassName(@NotNull ClassDescriptor descriptor) {
|
||||||
|
throw new UnsupportedOperationException("Local classes are unsupported: " + descriptor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ public class StringTable {
|
|||||||
|
|
||||||
private final Interner<String> strings = new Interner<String>();
|
private final Interner<String> strings = new Interner<String>();
|
||||||
private final Interner<FqNameProto> qualifiedNames = new Interner<FqNameProto>();
|
private final Interner<FqNameProto> qualifiedNames = new Interner<FqNameProto>();
|
||||||
|
private final SerializerExtension extension;
|
||||||
|
|
||||||
|
public StringTable(@NotNull SerializerExtension extension) {
|
||||||
|
this.extension = extension;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<String> getStrings() {
|
public List<String> getStrings() {
|
||||||
@@ -89,23 +94,33 @@ public class StringTable {
|
|||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
builder.setKind(QualifiedName.Kind.CLASS);
|
builder.setKind(QualifiedName.Kind.CLASS);
|
||||||
}
|
}
|
||||||
builder.setShortName(getSimpleNameIndex(descriptor.getName()));
|
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
|
int shortName;
|
||||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||||
|
shortName = getSimpleNameIndex(descriptor.getName());
|
||||||
PackageFragmentDescriptor fragment = (PackageFragmentDescriptor) containingDeclaration;
|
PackageFragmentDescriptor fragment = (PackageFragmentDescriptor) containingDeclaration;
|
||||||
if (!fragment.getFqName().isRoot()) {
|
if (!fragment.getFqName().isRoot()) {
|
||||||
builder.setParentQualifiedName(getFqNameIndex(fragment.getFqName()));
|
builder.setParentQualifiedName(getFqNameIndex(fragment.getFqName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||||
|
shortName = getSimpleNameIndex(descriptor.getName());
|
||||||
ClassDescriptor outerClass = (ClassDescriptor) containingDeclaration;
|
ClassDescriptor outerClass = (ClassDescriptor) containingDeclaration;
|
||||||
builder.setParentQualifiedName(getFqNameIndex(outerClass));
|
builder.setParentQualifiedName(getFqNameIndex(outerClass));
|
||||||
}
|
}
|
||||||
else {
|
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));
|
return qualifiedNames.intern(new FqNameProto(builder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-34
@@ -17,13 +17,14 @@
|
|||||||
package org.jetbrains.kotlin.serialization.deserialization;
|
package org.jetbrains.kotlin.serialization.deserialization;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.name.ClassId;
|
import org.jetbrains.kotlin.name.ClassId;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName;
|
import static org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName;
|
||||||
|
|
||||||
public class NameResolver {
|
public class NameResolver {
|
||||||
@@ -61,42 +62,30 @@ public class NameResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassId getClassId(int index) {
|
public ClassId getClassId(int index) {
|
||||||
QualifiedName fqNameProto = qualifiedNames.getQualifiedName(index);
|
LinkedList<String> packageFqName = new LinkedList<String>();
|
||||||
assert fqNameProto.getKind() == ProtoBuf.QualifiedNameTable.QualifiedName.Kind.CLASS : "Not a class fqName: " + fqNameProto.getKind();
|
LinkedList<String> relativeClassName = new LinkedList<String>();
|
||||||
|
boolean local = false;
|
||||||
|
|
||||||
StringBuilder relativeClassName = new StringBuilder();
|
while (index != -1) {
|
||||||
QualifiedName packageFqNameProto = renderFqName(relativeClassName, fqNameProto, QualifiedName.Kind.CLASS);
|
QualifiedName proto = qualifiedNames.getQualifiedName(index);
|
||||||
|
String shortName = strings.getString(proto.getShortName());
|
||||||
FqName packageFqName;
|
switch (proto.getKind()) {
|
||||||
if (packageFqNameProto != null) {
|
case CLASS:
|
||||||
StringBuilder sb = new StringBuilder();
|
relativeClassName.addFirst(shortName);
|
||||||
QualifiedName mustBeNull = renderFqName(sb, packageFqNameProto, QualifiedName.Kind.PACKAGE);
|
break;
|
||||||
assert mustBeNull == null : "Prefix of an fqName must be all of kind PACKAGE";
|
case PACKAGE:
|
||||||
|
packageFqName.addFirst(shortName);
|
||||||
packageFqName = new FqName(sb.toString());
|
break;
|
||||||
}
|
case LOCAL:
|
||||||
else {
|
relativeClassName.addFirst(shortName);
|
||||||
packageFqName = FqName.ROOT;
|
local = true;
|
||||||
}
|
break;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index = proto.getParentQualifiedName();
|
||||||
}
|
}
|
||||||
sb.append(strings.getString(fqNameProto.getShortName()));
|
|
||||||
return result;
|
return new ClassId(FqName.fromSegments(packageFqName), FqNameUnsafe.fromSegments(relativeClassName), local);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+8
-2
@@ -90,8 +90,14 @@ public class TypeDeserializer(
|
|||||||
typeParameterDescriptors().get(proto.getId())?.getTypeConstructor() ?:
|
typeParameterDescriptors().get(proto.getId())?.getTypeConstructor() ?:
|
||||||
parent?.typeParameterTypeConstructor(proto)
|
parent?.typeParameterTypeConstructor(proto)
|
||||||
|
|
||||||
private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? =
|
private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? {
|
||||||
c.components.moduleDescriptor.findClassAcrossModuleDependencies(c.nameResolver.getClassId(fqNameIndex))
|
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<ProtoBuf.Type.Argument>): List<TypeProjection> =
|
fun typeArguments(protos: List<ProtoBuf.Type.Argument>): List<TypeProjection> =
|
||||||
protos.map { proto ->
|
protos.map { proto ->
|
||||||
|
|||||||
Reference in New Issue
Block a user