Instance field generation in objects
This commit is contained in:
@@ -17,37 +17,34 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isNonCompanionObject;
|
||||
|
||||
public class FieldInfo {
|
||||
|
||||
private static final CompanionObjectMapping COMPANION_OBJECT_MAPPING = new CompanionObjectMapping(JvmPlatform.INSTANCE$.getBuiltIns());
|
||||
@NotNull
|
||||
public static FieldInfo createForCompanionSingleton(@NotNull ClassDescriptor companionObject, @NotNull JetTypeMapper typeMapper) {
|
||||
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(companionObject, ClassDescriptor.class);
|
||||
assert ownerDescriptor != null : "Owner not found for class: " + companionObject;
|
||||
Type ownerType = typeMapper.mapType(ownerDescriptor);
|
||||
return new FieldInfo(ownerType, typeMapper.mapType(companionObject), companionObject.getName().asString(), true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
|
||||
return createForSingleton(classDescriptor, typeMapper, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) {
|
||||
if (!classDescriptor.getKind().isSingleton()) {
|
||||
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
||||
}
|
||||
|
||||
if (isNonCompanionObject(classDescriptor) || COMPANION_OBJECT_MAPPING.hasMappingToObject(classDescriptor)) {
|
||||
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);
|
||||
}
|
||||
Type type = typeMapper.mapType(classDescriptor);
|
||||
return new FieldInfo(type, type, oldSingleton ? JvmAbi.DEPRECATED_INSTANCE_FIELD : JvmAbi.INSTANCE_FIELD, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -984,12 +984,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateFieldForSingleton() {
|
||||
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) return;
|
||||
if (isEnumEntry(descriptor)) return;
|
||||
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
if (isObject(descriptor)) {
|
||||
StackValue.Field field = StackValue.singleton(descriptor, typeMapper);
|
||||
v.newField(OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.Field oldField = StackValue.oldSingleton(descriptor, typeMapper);
|
||||
v.newField(OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_DEPRECATED, oldField.name, oldField.type.getDescriptor(), null, null);
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
|
||||
// Invoke the object constructor but ignore the result because INSTANCE$ will be initialized in the first line of <init>
|
||||
@@ -1007,7 +1012,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JetObjectDeclaration companionObject = CollectionsKt.firstOrNull(((JetClass) myClass).getCompanionObjects());
|
||||
assert companionObject != null : "Companion object not found: " + myClass.getText();
|
||||
|
||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||
StackValue.Field field = StackValue.singletonForCompanion(companionObjectDescriptor, typeMapper);
|
||||
v.newField(OtherOrigin(companionObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
@@ -1065,13 +1070,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
|
||||
CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
|
||||
);
|
||||
generateMethodCallTo(constructor, null, codegen.v);
|
||||
codegen.v.dup();
|
||||
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
|
||||
StackValue.singleton(companionObject, typeMapper).store(instance, codegen.v, true);
|
||||
StackValue.singletonForCompanion(companionObject, typeMapper)
|
||||
.store(StackValue.singleton(companionObject, typeMapper), codegen.v, true);
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
|
||||
@@ -1138,8 +1138,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor,
|
||||
getDelegationConstructorCall(bindingContext, constructorDescriptor));
|
||||
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
if (isObject(descriptor)) {
|
||||
StackValue.singleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.oldSingleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
|
||||
}
|
||||
}
|
||||
|
||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
|
||||
@@ -163,7 +163,7 @@ public class PackageCodegen {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<DeserializedCallableMemberDescriptor> callables = Lists.newArrayList();
|
||||
for (DeclarationDescriptor member : packageFragment.getMemberScope().getDescriptors(DescriptorKindFilter.CALLABLES, JetScope.ALL_NAME_FILTER)) {
|
||||
for (DeclarationDescriptor member : packageFragment.getMemberScope().getDescriptors(DescriptorKindFilter.CALLABLES, JetScope.Companion.getALL_NAME_FILTER())) {
|
||||
if (member instanceof DeserializedCallableMemberDescriptor) {
|
||||
callables.add((DeserializedCallableMemberDescriptor) member);
|
||||
}
|
||||
|
||||
@@ -576,6 +576,14 @@ public abstract class StackValue {
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper));
|
||||
}
|
||||
|
||||
public static Field singletonForCompanion(ClassDescriptor companionObject, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createForCompanionSingleton(companionObject, typeMapper));
|
||||
}
|
||||
|
||||
public static Field oldSingleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true));
|
||||
}
|
||||
|
||||
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
|
||||
return new OperationStackValue(type, lambda);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user