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:
@@ -32,16 +32,16 @@ public class FieldInfo {
|
||||
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
||||
}
|
||||
|
||||
ClassDescriptor ownerDescriptor = kind == ClassKind.OBJECT
|
||||
? classDescriptor
|
||||
: DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
||||
assert ownerDescriptor != null : "Owner not found for class: " + classDescriptor;
|
||||
Type ownerType = typeMapper.mapType(ownerDescriptor);
|
||||
|
||||
String fieldName = kind == ClassKind.ENUM_ENTRY
|
||||
? classDescriptor.getName().asString()
|
||||
: classDescriptor.getKind() == ClassKind.CLASS_OBJECT ? JvmAbi.CLASS_OBJECT_FIELD : JvmAbi.INSTANCE_FIELD;
|
||||
return new FieldInfo(ownerType, typeMapper.mapType(classDescriptor), fieldName, true);
|
||||
if (kind == ClassKind.OBJECT) {
|
||||
Type type = typeMapper.mapType(classDescriptor);
|
||||
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
|
||||
}
|
||||
else {
|
||||
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
||||
assert ownerDescriptor != null : "Owner not found for class: " + classDescriptor;
|
||||
Type ownerType = typeMapper.mapType(ownerDescriptor);
|
||||
return new FieldInfo(ownerType, typeMapper.mapType(classDescriptor), classDescriptor.getName().asString(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -958,7 +958,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateFieldForSingleton() {
|
||||
if (isEnumEntry(descriptor)) return;
|
||||
if (isEnumEntry(descriptor) || isClassObject(descriptor)) return;
|
||||
|
||||
ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor();
|
||||
ClassDescriptor fieldTypeDescriptor;
|
||||
|
||||
@@ -59,7 +59,6 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isClassObject;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.TraitImpl;
|
||||
@@ -242,9 +241,7 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
String outerClassInternalName =
|
||||
containing instanceof ClassDescriptor ? typeMapper.mapClass((ClassDescriptor) containing).getInternalName() : null;
|
||||
|
||||
String innerName = isClassObject(innerClass)
|
||||
? JvmAbi.CLASS_OBJECT_CLASS_NAME
|
||||
: innerClass.getName().isSpecial() ? null : innerClass.getName().asString();
|
||||
String innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().asString();
|
||||
|
||||
String innerClassInternalName = typeMapper.mapClass(innerClass).getInternalName();
|
||||
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass));
|
||||
|
||||
+2
-1
@@ -213,7 +213,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
assert classDescriptor != null : String.format("No class found in binding context for: \n---\n%s\n---\n",
|
||||
JetPsiUtil.getElementTextWithContext(classObject));
|
||||
|
||||
String name = peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
//TODO_R: remove visitClassObject
|
||||
String name = getName(classDescriptor);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
classStack.push(classDescriptor);
|
||||
|
||||
@@ -80,7 +80,8 @@ public final class PsiCodegenPredictor {
|
||||
|
||||
if (declaration instanceof JetClassObject) {
|
||||
// Get parent and assign Class object prefix
|
||||
return parentInternalName + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
//TODO_R: getName() nullable
|
||||
return parentInternalName + "$" + ((JetClassObject) declaration).getObjectDeclaration().getName();
|
||||
}
|
||||
|
||||
if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) ||
|
||||
|
||||
@@ -339,14 +339,7 @@ public class JetTypeMapper {
|
||||
assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
|
||||
|
||||
String containerInternalName = computeAsmTypeImpl((ClassDescriptor) container);
|
||||
switch (klass.getKind()) {
|
||||
case ENUM_ENTRY:
|
||||
return containerInternalName;
|
||||
case CLASS_OBJECT:
|
||||
return containerInternalName + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
default:
|
||||
return containerInternalName + "$" + name;
|
||||
}
|
||||
return klass.getKind() == ClassKind.ENUM_ENTRY ? containerInternalName : containerInternalName + "$" + name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user