Rework class objects

Class objects have name "Default" by default
Do not produce synthetic class objects
Class objects have new semantics:
    class "A" has class object "B" if literal "A" can be used as a value of type "B"
Class objects act like ordinary nested objects
    i.e. are accessible from class scope via getClassifier()
Jvm backend: class object fields and class have the name of class object ("Default")
	as opposed to special "OBJECT$" and "object"
Serialization: only the name of class object is needed to serialize data
This commit is contained in:
Pavel V. Talanov
2015-01-14 15:34:33 +03:00
parent 4b6112d380
commit 0343fd8fc7
39 changed files with 254 additions and 1728 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
public final class JvmAbi {
/**
@@ -35,7 +36,7 @@ public final class JvmAbi {
public static final String GETTER_PREFIX = "get";
public static final String SETTER_PREFIX = "set";
public static final String CLASS_OBJECT_CLASS_NAME = "object";
public static final String CLASS_OBJECT_CLASS_NAME = SpecialNames.DEFAULT_NAME_FOR_DEFAULT_OBJECT.asString();
public static final String CLASS_OBJECT_SUFFIX = "$" + CLASS_OBJECT_CLASS_NAME;
public static final String DELEGATED_PROPERTY_NAME_SUFFIX = "$delegate";
@@ -43,7 +44,7 @@ public final class JvmAbi {
public static final String ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX = "$annotations";
public static final String INSTANCE_FIELD = "INSTANCE$";
public static final String CLASS_OBJECT_FIELD = "OBJECT$";
public static final String CLASS_OBJECT_FIELD = CLASS_OBJECT_CLASS_NAME;
public static final FqName K_OBJECT = new FqName("kotlin.jvm.internal.KObject");
public static final String KOTLIN_CLASS_FIELD_NAME = "$kotlinClass";
@@ -20,24 +20,25 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.*;
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 java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.name.SpecialNames.isClassObjectName;
public class DeserializedResolverUtils {
private DeserializedResolverUtils() {
}
//TODO_R: remove usages
@NotNull
public static FqName kotlinFqNameToJavaFqName(@NotNull FqNameUnsafe kotlinFqName) {
List<Name> segments = kotlinFqName.pathSegments();
List<String> correctedSegments = new ArrayList<String>(segments.size());
for (Name segment : segments) {
correctedSegments.add(isClassObjectName(segment) ? JvmAbi.CLASS_OBJECT_CLASS_NAME : segment.getIdentifier());
correctedSegments.add(segment.getIdentifier());
}
return FqName.fromSegments(correctedSegments);
}
@@ -47,6 +48,7 @@ public class DeserializedResolverUtils {
return new ClassId(kotlinClassId.getPackageFqName(), kotlinFqNameToJavaFqName(kotlinClassId.getRelativeClassName()).toUnsafe());
}
//TODO_R: remove usages
@NotNull
public static FqNameUnsafe javaFqNameToKotlinFqName(@NotNull FqName javaFqName) {
if (javaFqName.isRoot()) {
@@ -56,14 +58,12 @@ public class DeserializedResolverUtils {
List<Name> correctedSegments = new ArrayList<Name>(segments.size());
correctedSegments.add(segments.get(0));
for (int i = 1; i < segments.size(); i++) {
Name segment = segments.get(i);
boolean isClassObjectName = segment.asString().equals(JvmAbi.CLASS_OBJECT_CLASS_NAME);
Name correctedSegment = isClassObjectName ? SpecialNames.getClassObjectName(segments.get(i - 1)) : segment;
correctedSegments.add(correctedSegment);
correctedSegments.add(segments.get(i));
}
return FqNameUnsafe.fromSegments(correctedSegments);
}
//TODO_R: remove usages
@NotNull
public static ClassId javaClassIdToKotlinClassId(@NotNull ClassId javaClassId) {
return new ClassId(javaClassId.getPackageFqName(), javaFqNameToKotlinFqName(javaClassId.getRelativeClassName().toSafe()));
@@ -51,7 +51,6 @@ public class JvmClassName {
return byFqNameWithoutInnerClasses(new FqName(fqName));
}
private final static String CLASS_OBJECT_REPLACE_GUARD = "<class_object>";
private final static String TRAIT_IMPL_REPLACE_GUARD = "<trait_impl>";
// Internal name: kotlin/Map$Entry
@@ -71,12 +70,10 @@ public class JvmClassName {
public FqName getFqNameForClassNameWithoutDollars() {
if (fqName == null) {
String fqName = internalName
.replace(JvmAbi.CLASS_OBJECT_CLASS_NAME, CLASS_OBJECT_REPLACE_GUARD)
.replace(JvmAbi.TRAIT_IMPL_CLASS_NAME, TRAIT_IMPL_REPLACE_GUARD)
.replace('$', '.')
.replace('/', '.')
.replace(TRAIT_IMPL_REPLACE_GUARD, JvmAbi.TRAIT_IMPL_CLASS_NAME)
.replace(CLASS_OBJECT_REPLACE_GUARD, JvmAbi.CLASS_OBJECT_CLASS_NAME);
.replace(TRAIT_IMPL_REPLACE_GUARD, JvmAbi.TRAIT_IMPL_CLASS_NAME);
this.fqName = new FqName(fqName);
}
return fqName;
@@ -24,22 +24,10 @@ public object BuiltInsSerializationUtil {
private val PACKAGE_FILE_NAME = ".kotlin_package"
private val STRING_TABLE_FILE_NAME = ".kotlin_string_table"
private val CLASS_NAMES_FILE_NAME = ".kotlin_class_names"
private val CLASS_OBJECT_NAME = "object"
private fun relativeClassNameToFilePath(className: FqNameUnsafe): String? {
return FqName.fromSegments(className.pathSegments().map { segment ->
when {
SpecialNames.isClassObjectName(segment) -> CLASS_OBJECT_NAME
!segment.isSpecial() -> segment.getIdentifier()
else -> return null
}
}).asString()
}
platformStatic public fun getClassMetadataPath(classId: ClassId): String? {
val filePath = relativeClassNameToFilePath(classId.getRelativeClassName())
if (filePath == null) return null
return packageFqNameToPath(classId.getPackageFqName()) + "/" + filePath + "." + CLASS_METADATA_FILE_EXTENSION
return packageFqNameToPath(classId.getPackageFqName()) + "/" + classId.getRelativeClassName().asString() +
"." + CLASS_METADATA_FILE_EXTENSION
}
platformStatic public fun getPackageFilePath(fqName: FqName): String =
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.OverridingUtil;
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
@@ -44,12 +43,11 @@ import java.util.HashSet;
import java.util.Set;
public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
private final ClassKind kind;
private final TypeConstructor typeConstructor;
private final ConstructorDescriptor primaryConstructor;
private final JetScope scope;
private final JetScope staticScope = new StaticScopeForKotlinClass(this);
private final EnumEntrySyntheticClassDescriptor classObjectDescriptor;
private final ClassDescriptor classObjectDescriptor;
private final NotNullLazyValue<Collection<Name>> enumMemberNames;
/**
@@ -66,7 +64,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
) {
JetType enumType = enumClass.getDefaultType();
return new EnumEntrySyntheticClassDescriptor(storageManager, enumClass, enumType, name, ClassKind.ENUM_ENTRY, enumMemberNames, source);
return new EnumEntrySyntheticClassDescriptor(storageManager, enumClass, enumType, name, enumMemberNames, source);
}
private EnumEntrySyntheticClassDescriptor(
@@ -74,12 +72,11 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
@NotNull ClassDescriptor containingClass,
@NotNull JetType supertype,
@NotNull Name name,
@NotNull ClassKind kind,
@NotNull NotNullLazyValue<Collection<Name>> enumMemberNames,
@NotNull SourceElement source
) {
super(storageManager, containingClass, name, source);
this.kind = kind;
assert containingClass.getKind() == ClassKind.ENUM_CLASS;
this.typeConstructor =
TypeConstructorImpl.createForClass(this, getAnnotations(), true, "enum entry", Collections.<TypeParameterDescriptor>emptyList(),
@@ -92,11 +89,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
primaryConstructor.setReturnType(getDefaultType());
this.primaryConstructor = primaryConstructor;
this.classObjectDescriptor =
kind == ClassKind.CLASS_OBJECT
? null
: new EnumEntrySyntheticClassDescriptor(storageManager, this, getDefaultType(), SpecialNames.getClassObjectName(name),
ClassKind.CLASS_OBJECT, enumMemberNames, SourceElement.NO_SOURCE);
this.classObjectDescriptor = containingClass;
}
@NotNull
@@ -132,7 +125,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
@NotNull
@Override
public ClassKind getKind() {
return kind;
return ClassKind.ENUM_ENTRY;
}
@NotNull
@@ -23,7 +23,7 @@ public class SpecialNames {
public static final Name NO_NAME_PROVIDED = Name.special("<no name provided>");
public static final Name ROOT_PACKAGE = Name.special("<root package>");
private static final String CLASS_OBJECT_FOR = "<class-object-for-";
public static final Name DEFAULT_NAME_FOR_DEFAULT_OBJECT = Name.identifier("Default");
// This name is used as a key for the case when something has no name _due to a syntactic error_
// Example: fun (x: Int) = 5
@@ -36,15 +36,5 @@ public class SpecialNames {
return name != null && !name.isSpecial() ? name : SAFE_IDENTIFIER_FOR_NO_NAME;
}
@NotNull
public static Name getClassObjectName(@NotNull Name className) {
return Name.special(CLASS_OBJECT_FOR + className.asString() + ">");
}
public static boolean isClassObjectName(@NotNull Name name) {
return name.isSpecial() && name.asString().startsWith(CLASS_OBJECT_FOR);
}
private SpecialNames() {}
}
+2 -8
View File
@@ -179,14 +179,8 @@ message Class {
required int32 fq_name = 3;
message ClassObject {
// If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
// Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
optional Class data = 1;
}
// This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
optional ClassObject class_object = 4;
// If this field is present, it contains the name of default object.
optional int32 class_object_name = 4;
repeated TypeParameter type_parameter = 5;
repeated Type supertype = 6;
@@ -131,8 +131,8 @@ public class DescriptorSerializer {
}
ClassDescriptor classObject = classDescriptor.getClassObjectDescriptor();
if (classObject != null) {
builder.setClassObject(classObjectProto(classObject));
if (classObject != null && isClassObject(classObject)) {
builder.setClassObjectName(stringTable.getSimpleNameIndex(classObject.getName()));
}
extension.serializeClass(classDescriptor, builder, stringTable);
@@ -140,15 +140,6 @@ public class DescriptorSerializer {
return builder;
}
@NotNull
private ProtoBuf.Class.ClassObject classObjectProto(@NotNull ClassDescriptor classObject) {
if (isObject(classObject.getContainingDeclaration())) {
return ProtoBuf.Class.ClassObject.newBuilder().setData(classProto(classObject)).build();
}
return ProtoBuf.Class.ClassObject.getDefaultInstance();
}
@NotNull
public ProtoBuf.Callable.Builder callableProto(@NotNull CallableMemberDescriptor descriptor) {
ProtoBuf.Callable.Builder builder = ProtoBuf.Callable.newBuilder();
@@ -7336,23 +7336,23 @@ public final class ProtoBuf {
*/
int getFqName();
// optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;
// optional int32 class_object_name = 4;
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
boolean hasClassObject();
boolean hasClassObjectName();
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject getClassObject();
int getClassObjectName();
// repeated .org.jetbrains.kotlin.serialization.TypeParameter type_parameter = 5;
/**
@@ -7518,17 +7518,9 @@ public final class ProtoBuf {
fqName_ = input.readInt32();
break;
}
case 34: {
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.Builder subBuilder = null;
if (((bitField0_ & 0x00000008) == 0x00000008)) {
subBuilder = classObject_.toBuilder();
}
classObject_ = input.readMessage(org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(classObject_);
classObject_ = subBuilder.buildPartial();
}
case 32: {
bitField0_ |= 0x00000008;
classObjectName_ = input.readInt32();
break;
}
case 42: {
@@ -7760,437 +7752,6 @@ public final class ProtoBuf {
// @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.Class.Kind)
}
public interface ClassObjectOrBuilder
extends com.google.protobuf.MessageLiteOrBuilder {
// optional .org.jetbrains.kotlin.serialization.Class data = 1;
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
boolean hasData();
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
org.jetbrains.kotlin.serialization.ProtoBuf.Class getData();
}
/**
* Protobuf type {@code org.jetbrains.kotlin.serialization.Class.ClassObject}
*/
public static final class ClassObject extends
com.google.protobuf.GeneratedMessageLite
implements ClassObjectOrBuilder {
// Use ClassObject.newBuilder() to construct.
private ClassObject(com.google.protobuf.GeneratedMessageLite.Builder builder) {
super(builder);
}
private ClassObject(boolean noInit) {}
private static final ClassObject defaultInstance;
public static ClassObject getDefaultInstance() {
return defaultInstance;
}
public ClassObject getDefaultInstanceForType() {
return defaultInstance;
}
private ClassObject(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
initFields();
int mutable_bitField0_ = 0;
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
default: {
if (!parseUnknownField(input,
extensionRegistry, tag)) {
done = true;
}
break;
}
case 10: {
org.jetbrains.kotlin.serialization.ProtoBuf.Class.Builder subBuilder = null;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
subBuilder = data_.toBuilder();
}
data_ = input.readMessage(org.jetbrains.kotlin.serialization.ProtoBuf.Class.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(data_);
data_ = subBuilder.buildPartial();
}
bitField0_ |= 0x00000001;
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e.getMessage()).setUnfinishedMessage(this);
} finally {
makeExtensionsImmutable();
}
}
public static com.google.protobuf.Parser<ClassObject> PARSER =
new com.google.protobuf.AbstractParser<ClassObject>() {
public ClassObject parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new ClassObject(input, extensionRegistry);
}
};
@java.lang.Override
public com.google.protobuf.Parser<ClassObject> getParserForType() {
return PARSER;
}
private int bitField0_;
// optional .org.jetbrains.kotlin.serialization.Class data = 1;
public static final int DATA_FIELD_NUMBER = 1;
private org.jetbrains.kotlin.serialization.ProtoBuf.Class data_;
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public boolean hasData() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public org.jetbrains.kotlin.serialization.ProtoBuf.Class getData() {
return data_;
}
private void initFields() {
data_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance();
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
if (hasData()) {
if (!getData().isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
memoizedIsInitialized = 1;
return true;
}
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeMessage(1, data_);
}
}
private int memoizedSerializedSize = -1;
public int getSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(1, data_);
}
memoizedSerializedSize = size;
return size;
}
private static final long serialVersionUID = 0L;
@java.lang.Override
protected java.lang.Object writeReplace()
throws java.io.ObjectStreamException {
return super.writeReplace();
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input, extensionRegistry);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
}
public static org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
}
public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject prototype) {
return newBuilder().mergeFrom(prototype);
}
public Builder toBuilder() { return newBuilder(this); }
/**
* Protobuf type {@code org.jetbrains.kotlin.serialization.Class.ClassObject}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageLite.Builder<
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject, Builder>
implements org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObjectOrBuilder {
// Construct using org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
}
private static Builder create() {
return new Builder();
}
public Builder clear() {
super.clear();
data_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance();
bitField0_ = (bitField0_ & ~0x00000001);
return this;
}
public Builder clone() {
return create().mergeFrom(buildPartial());
}
public org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject getDefaultInstanceForType() {
return org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance();
}
public org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject build() {
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
public org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject buildPartial() {
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject result = new org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject(this);
int from_bitField0_ = bitField0_;
int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
to_bitField0_ |= 0x00000001;
}
result.data_ = data_;
result.bitField0_ = to_bitField0_;
return result;
}
public Builder mergeFrom(org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject other) {
if (other == org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance()) return this;
if (other.hasData()) {
mergeData(other.getData());
}
return this;
}
public final boolean isInitialized() {
if (hasData()) {
if (!getData().isInitialized()) {
return false;
}
}
return true;
}
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject) e.getUnfinishedMessage();
throw e;
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
// optional .org.jetbrains.kotlin.serialization.Class data = 1;
private org.jetbrains.kotlin.serialization.ProtoBuf.Class data_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance();
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public boolean hasData() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public org.jetbrains.kotlin.serialization.ProtoBuf.Class getData() {
return data_;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public Builder setData(org.jetbrains.kotlin.serialization.ProtoBuf.Class value) {
if (value == null) {
throw new NullPointerException();
}
data_ = value;
bitField0_ |= 0x00000001;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public Builder setData(
org.jetbrains.kotlin.serialization.ProtoBuf.Class.Builder builderForValue) {
data_ = builderForValue.build();
bitField0_ |= 0x00000001;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public Builder mergeData(org.jetbrains.kotlin.serialization.ProtoBuf.Class value) {
if (((bitField0_ & 0x00000001) == 0x00000001) &&
data_ != org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance()) {
data_ =
org.jetbrains.kotlin.serialization.ProtoBuf.Class.newBuilder(data_).mergeFrom(value).buildPartial();
} else {
data_ = value;
}
bitField0_ |= 0x00000001;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class data = 1;</code>
*
* <pre>
* If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
* Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
* </pre>
*/
public Builder clearData() {
data_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance();
bitField0_ = (bitField0_ & ~0x00000001);
return this;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.Class.ClassObject)
}
static {
defaultInstance = new ClassObject(true);
defaultInstance.initFields();
}
// @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.Class.ClassObject)
}
public interface PrimaryConstructorOrBuilder
extends com.google.protobuf.MessageLiteOrBuilder {
@@ -8728,28 +8289,28 @@ public final class ProtoBuf {
return fqName_;
}
// optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;
public static final int CLASS_OBJECT_FIELD_NUMBER = 4;
private org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject classObject_;
// optional int32 class_object_name = 4;
public static final int CLASS_OBJECT_NAME_FIELD_NUMBER = 4;
private int classObjectName_;
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
public boolean hasClassObject() {
public boolean hasClassObjectName() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
public org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject getClassObject() {
return classObject_;
public int getClassObjectName() {
return classObjectName_;
}
// repeated .org.jetbrains.kotlin.serialization.TypeParameter type_parameter = 5;
@@ -8949,7 +8510,7 @@ public final class ProtoBuf {
flags_ = 0;
extraVisibility_ = "";
fqName_ = 0;
classObject_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance();
classObjectName_ = 0;
typeParameter_ = java.util.Collections.emptyList();
supertype_ = java.util.Collections.emptyList();
nestedClassName_ = java.util.Collections.emptyList();
@@ -8966,12 +8527,6 @@ public final class ProtoBuf {
memoizedIsInitialized = 0;
return false;
}
if (hasClassObject()) {
if (!getClassObject().isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
for (int i = 0; i < getTypeParameterCount(); i++) {
if (!getTypeParameter(i).isInitialized()) {
memoizedIsInitialized = 0;
@@ -9020,7 +8575,7 @@ public final class ProtoBuf {
output.writeInt32(3, fqName_);
}
if (((bitField0_ & 0x00000008) == 0x00000008)) {
output.writeMessage(4, classObject_);
output.writeInt32(4, classObjectName_);
}
for (int i = 0; i < typeParameter_.size(); i++) {
output.writeMessage(5, typeParameter_.get(i));
@@ -9063,7 +8618,7 @@ public final class ProtoBuf {
}
if (((bitField0_ & 0x00000008) == 0x00000008)) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(4, classObject_);
.computeInt32Size(4, classObjectName_);
}
for (int i = 0; i < typeParameter_.size(); i++) {
size += com.google.protobuf.CodedOutputStream
@@ -9196,7 +8751,7 @@ public final class ProtoBuf {
bitField0_ = (bitField0_ & ~0x00000002);
fqName_ = 0;
bitField0_ = (bitField0_ & ~0x00000004);
classObject_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance();
classObjectName_ = 0;
bitField0_ = (bitField0_ & ~0x00000008);
typeParameter_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000010);
@@ -9248,7 +8803,7 @@ public final class ProtoBuf {
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
to_bitField0_ |= 0x00000008;
}
result.classObject_ = classObject_;
result.classObjectName_ = classObjectName_;
if (((bitField0_ & 0x00000010) == 0x00000010)) {
typeParameter_ = java.util.Collections.unmodifiableList(typeParameter_);
bitField0_ = (bitField0_ & ~0x00000010);
@@ -9295,8 +8850,8 @@ public final class ProtoBuf {
if (other.hasFqName()) {
setFqName(other.getFqName());
}
if (other.hasClassObject()) {
mergeClassObject(other.getClassObject());
if (other.hasClassObjectName()) {
setClassObjectName(other.getClassObjectName());
}
if (!other.typeParameter_.isEmpty()) {
if (typeParameter_.isEmpty()) {
@@ -9360,12 +8915,6 @@ public final class ProtoBuf {
return false;
}
if (hasClassObject()) {
if (!getClassObject().isInitialized()) {
return false;
}
}
for (int i = 0; i < getTypeParameterCount(); i++) {
if (!getTypeParameter(i).isInitialized()) {
@@ -9616,88 +9165,52 @@ public final class ProtoBuf {
return this;
}
// optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;
private org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject classObject_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance();
// optional int32 class_object_name = 4;
private int classObjectName_ ;
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
public boolean hasClassObject() {
public boolean hasClassObjectName() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
public org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject getClassObject() {
return classObject_;
public int getClassObjectName() {
return classObjectName_;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
public Builder setClassObject(org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject value) {
if (value == null) {
throw new NullPointerException();
}
classObject_ = value;
public Builder setClassObjectName(int value) {
bitField0_ |= 0x00000008;
classObjectName_ = value;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
* <code>optional int32 class_object_name = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* If this field is present, it contains the name of default object.
* </pre>
*/
public Builder setClassObject(
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.Builder builderForValue) {
classObject_ = builderForValue.build();
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* </pre>
*/
public Builder mergeClassObject(org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject value) {
if (((bitField0_ & 0x00000008) == 0x00000008) &&
classObject_ != org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance()) {
classObject_ =
org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.newBuilder(classObject_).mergeFrom(value).buildPartial();
} else {
classObject_ = value;
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.Class.ClassObject class_object = 4;</code>
*
* <pre>
* This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
* </pre>
*/
public Builder clearClassObject() {
classObject_ = org.jetbrains.kotlin.serialization.ProtoBuf.Class.ClassObject.getDefaultInstance();
public Builder clearClassObjectName() {
bitField0_ = (bitField0_ & ~0x00000008);
classObjectName_ = 0;
return this;
}
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinClass
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.name.SpecialNames.getClassObjectName
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -111,18 +110,13 @@ public class DeserializedClassDescriptor(
}
private fun computeClassObjectDescriptor(): ClassDescriptor? {
if (!classProto.hasClassObject()) return null
if (getKind() == ClassKind.OBJECT) {
val classObjectProto = classProto.getClassObject()
if (!classObjectProto.hasData()) {
throw IllegalStateException("Object should have a serialized class object: $classId")
}
return DeserializedClassDescriptor(c, classObjectProto.getData(), c.nameResolver)
if (getKind() == ClassKind.OBJECT || getKind() == ClassKind.CLASS_OBJECT) {
return this
}
if (!classProto.hasClassObjectName()) return null
return c.components.deserializeClass(classId.createNestedClassId(getClassObjectName(getName())))
val classObjectName = c.nameResolver.getName(classProto.getClassObjectName())
return memberScope.getClassifier(classObjectName) as? ClassDescriptor
}
override fun getClassObjectDescriptor(): ClassDescriptor? = classObjectDescriptor()
@@ -22,22 +22,13 @@ import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.ClassId
private fun findInnerClass(classDescriptor: ClassDescriptor, name: Name): ClassDescriptor? {
return if (SpecialNames.isClassObjectName(name)) {
classDescriptor.getClassObjectDescriptor()
}
else {
classDescriptor.getUnsubstitutedInnerClassesScope().getClassifier(name) as? ClassDescriptor
}
}
public fun ModuleDescriptor.findClassAcrossModuleDependencies(classId: ClassId): ClassDescriptor? {
val packageViewDescriptor = getPackage(classId.getPackageFqName()) ?: return null
val segments = classId.getRelativeClassName().pathSegments()
val topLevelClass = packageViewDescriptor.getMemberScope().getClassifier(segments.first()) as? ClassDescriptor ?: return null
var result = topLevelClass
for (name in segments.subList(1, segments.size())) {
result = findInnerClass(result, name) ?: return null
result = result.getUnsubstitutedInnerClassesScope().getClassifier(name) as? ClassDescriptor ?: return null
}
return result
}