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:
@@ -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";
|
||||
|
||||
+9
-9
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user