Use proto flag to determine companion field moved to interface

This commit is contained in:
Mikhael Bogdanov
2018-07-16 13:34:55 +02:00
parent e00b7a993f
commit 5b8df2f6f2
3 changed files with 31 additions and 8 deletions
@@ -10,15 +10,17 @@ import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget; import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget; import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
import org.jetbrains.kotlin.metadata.ProtoBuf;
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil;
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.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt; import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
@@ -116,10 +118,13 @@ public final class JvmAbi {
} }
public static boolean isInterfaceCompanionWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) { public static boolean isInterfaceCompanionWithBackingFieldsInOuter(@NotNull DeclarationDescriptor declarationDescriptor) {
DeclarationDescriptor interfaceClass = companionObject.getContainingDeclaration(); DeclarationDescriptor interfaceClass = declarationDescriptor.getContainingDeclaration();
if (!isInterface(interfaceClass) && !isAnnotationClass(interfaceClass)) return false; if (!isCompanionObject(declarationDescriptor) ||
Collection<DeclarationDescriptor> descriptors = ((ClassDescriptor) companionObject).getUnsubstitutedMemberScope() (!isInterface(interfaceClass) && !isAnnotationClass(interfaceClass))) {
return false;
}
Collection<DeclarationDescriptor> descriptors = ((ClassDescriptor) declarationDescriptor).getUnsubstitutedMemberScope()
.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.getALL_NAME_FILTER()); .getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.getALL_NAME_FILTER());
boolean hasJvmFieldAnnotation = false; boolean hasJvmFieldAnnotation = false;
for (DeclarationDescriptor next : descriptors) { for (DeclarationDescriptor next : descriptors) {
@@ -132,12 +137,20 @@ public final class JvmAbi {
return false; return false;
} }
if (!hasJvmFieldAnnotation(propertyDescriptor)) return false; if (!isMovedFromInterfaceCompanion(propertyDescriptor) && !hasJvmFieldAnnotation(propertyDescriptor)) return false;
hasJvmFieldAnnotation = true; hasJvmFieldAnnotation = true;
} }
return hasJvmFieldAnnotation; return hasJvmFieldAnnotation;
} }
private static boolean isMovedFromInterfaceCompanion(@NotNull PropertyDescriptor propertyDescriptor) {
if (propertyDescriptor instanceof DeserializedPropertyDescriptor) {
ProtoBuf.Property proto = ((DeserializedPropertyDescriptor) propertyDescriptor).getProto();
return JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto);
}
return false;
}
public static boolean isMappedIntrinsicCompanionObject(@NotNull ClassDescriptor companionObject) { public static boolean isMappedIntrinsicCompanionObject(@NotNull ClassDescriptor companionObject) {
return CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject(companionObject); return CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject(companionObject);
} }
@@ -120,6 +120,7 @@ object JvmProtoBufUtil {
return if (type.hasClassName()) ClassMapperLite.mapClass(nameResolver.getQualifiedClassName(type.className)) else null return if (type.hasClassName()) ClassMapperLite.mapClass(nameResolver.getQualifiedClassName(type.className)) else null
} }
@JvmStatic
fun isMovedFromInterfaceCompanion(proto: ProtoBuf.Property) = fun isMovedFromInterfaceCompanion(proto: ProtoBuf.Property) =
proto.getExtension(JvmProtoBuf.isMovedFromInterfaceCompanion).toInt().and(1) != 0 proto.getExtension(JvmProtoBuf.isMovedFromInterfaceCompanion).toInt().and(1) != 0
} }
@@ -33,6 +33,7 @@ import kotlin.reflect.KMutableProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
import kotlin.reflect.full.IllegalPropertyDelegateAccessException import kotlin.reflect.full.IllegalPropertyDelegateAccessException
import kotlin.reflect.jvm.internal.JvmPropertySignature.* import kotlin.reflect.jvm.internal.JvmPropertySignature.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
internal abstract class KPropertyImpl<out R> private constructor( internal abstract class KPropertyImpl<out R> private constructor(
override val container: KDeclarationContainerImpl, override val container: KDeclarationContainerImpl,
@@ -192,9 +193,17 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration) !DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
} }
fun isInsideInterfaceCompanionObjectWithJvmField(): Boolean { fun isInsideJvmInterfaceCompanionObject(): Boolean {
val possibleCompanionObject = property.descriptor.containingDeclaration val possibleCompanionObject = property.descriptor.containingDeclaration
return JvmAbi.isInterfaceCompanionWithBackingFieldsInOuter(possibleCompanionObject) return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
(DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration) ||
DescriptorUtils.isAnnotationClass(possibleCompanionObject.containingDeclaration))
}
fun isInsideInterfaceCompanionObjectWithJvmField(): Boolean {
val propertyDescriptor = property.descriptor
if (propertyDescriptor !is DeserializedPropertyDescriptor || !isInsideJvmInterfaceCompanionObject()) return false
return JvmProtoBufUtil.isMovedFromInterfaceCompanion(propertyDescriptor.proto)
} }
fun isJvmStaticProperty() = fun isJvmStaticProperty() =