Add ClassDescriptor.getInlineClassRepresentation
This will be used at least in the JVM backend instead of the current approach where we're loading the primary constructor's first parameter, which isn't good enough since primary constructor can be private, and we can't rely on private declarations in case they're declared in another module.
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
|
||||
class InlineClassRepresentation<Type : SimpleTypeMarker>(
|
||||
val underlyingPropertyName: Name,
|
||||
val underlyingType: Type,
|
||||
)
|
||||
+2
@@ -195,6 +195,8 @@ class LazyJavaClassDescriptor(
|
||||
emptyList()
|
||||
}
|
||||
|
||||
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
|
||||
|
||||
override fun toString() = "Lazy Java class ${this.fqNameUnsafe}"
|
||||
|
||||
private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor(c.storageManager) {
|
||||
|
||||
+1
-1
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* A [ClassDescriptor] representing the fictitious class for a function type, such as kotlin.Function1 or kotlin.reflect.KFunction2.
|
||||
@@ -88,6 +87,7 @@ class FunctionClassDescriptor(
|
||||
override val annotations: Annotations get() = Annotations.EMPTY
|
||||
override fun getSource(): SourceElement = SourceElement.NO_SOURCE
|
||||
override fun getSealedSubclasses() = emptyList<ClassDescriptor>()
|
||||
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
|
||||
|
||||
override fun getDeclaredTypeParameters() = parameters
|
||||
|
||||
|
||||
@@ -97,6 +97,9 @@ public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters,
|
||||
@NotNull
|
||||
Collection<ClassDescriptor> getSealedSubclasses();
|
||||
|
||||
@Nullable
|
||||
InlineClassRepresentation<SimpleType> getInlineClassRepresentation();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
ClassDescriptor getOriginal();
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
|
||||
@@ -83,6 +84,7 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo
|
||||
override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null
|
||||
override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
|
||||
override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList()
|
||||
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
|
||||
|
||||
override fun toString() = "class $name (not found)"
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.storage.StorageManager;
|
||||
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
|
||||
|
||||
@@ -174,4 +175,10 @@ public class ClassDescriptorImpl extends ClassDescriptorBase {
|
||||
public Collection<ClassDescriptor> getSealedSubclasses() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
||||
import org.jetbrains.kotlin.storage.StorageManager;
|
||||
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
|
||||
import org.jetbrains.kotlin.utils.Printer;
|
||||
@@ -192,6 +193,12 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private class EnumEntryScope extends MemberScopeImpl {
|
||||
private final MemoizedFunctionToNotNull<Name, Collection<? extends SimpleFunctionDescriptor>> functions;
|
||||
private final MemoizedFunctionToNotNull<Name, Collection<? extends PropertyDescriptor>> properties;
|
||||
|
||||
+16
-1
@@ -314,10 +314,25 @@ public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor
|
||||
return original.getSealedSubclasses();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
|
||||
InlineClassRepresentation<SimpleType> representation = original.getInlineClassRepresentation();
|
||||
//noinspection ConstantConditions
|
||||
return representation == null ? null : new InlineClassRepresentation<SimpleType>(
|
||||
representation.getUnderlyingPropertyName(),
|
||||
substituteSimpleType(getInlineClassRepresentation().getUnderlyingType())
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SimpleType getDefaultFunctionTypeForSamInterface() {
|
||||
SimpleType type = original.getDefaultFunctionTypeForSamInterface();
|
||||
return substituteSimpleType(original.getDefaultFunctionTypeForSamInterface());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SimpleType substituteSimpleType(@Nullable SimpleType type) {
|
||||
if (type == null || originalSubstitutor.isEmpty()) return type;
|
||||
|
||||
TypeSubstitutor substitutor = getSubstitutor();
|
||||
|
||||
@@ -189,6 +189,12 @@ public class MutableClassDescriptor extends ClassDescriptorBase {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DeclarationDescriptorImpl.toString(this);
|
||||
|
||||
+31
-4
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.incremental.record
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
@@ -68,6 +65,7 @@ class DeserializedClassDescriptor(
|
||||
private val constructors = c.storageManager.createLazyValue { computeConstructors() }
|
||||
private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() }
|
||||
private val sealedSubclasses = c.storageManager.createLazyValue { computeSubclassesForSealedClass() }
|
||||
private val inlineClassRepresentation = c.storageManager.createNullableLazyValue { computeInlineClassRepresentation() }
|
||||
|
||||
internal val thisAsProtoContainer: ProtoContainer.Class = ProtoContainer.Class(
|
||||
classProto, c.nameResolver, c.typeTable, sourceElement,
|
||||
@@ -170,6 +168,35 @@ class DeserializedClassDescriptor(
|
||||
|
||||
override fun getSealedSubclasses() = sealedSubclasses()
|
||||
|
||||
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = inlineClassRepresentation()
|
||||
|
||||
private fun computeInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? {
|
||||
if (!isInlineClass()) return null
|
||||
|
||||
val propertyName = when {
|
||||
classProto.hasInlineClassUnderlyingPropertyName() ->
|
||||
c.nameResolver.getName(classProto.inlineClassUnderlyingPropertyName)
|
||||
!metadataVersion.isAtLeast(1, 5, 1) -> {
|
||||
// Before 1.5, inline classes did not have underlying property name & type in the metadata.
|
||||
// However, they were experimental, so supposedly this logic can be removed at some point in the future.
|
||||
val constructor = unsubstitutedPrimaryConstructor ?: error("Inline class has no primary constructor: $this")
|
||||
constructor.valueParameters.first().name
|
||||
}
|
||||
else -> error("Inline class has no underlying property name in metadata: $this")
|
||||
}
|
||||
|
||||
val type = classProto.inlineClassUnderlyingType(c.typeTable)?.let(c.typeDeserializer::simpleType)
|
||||
?: run {
|
||||
val underlyingProperty =
|
||||
memberScope.getContributedVariables(propertyName, NoLookupLocation.FROM_DESERIALIZATION)
|
||||
.singleOrNull { it.extensionReceiverParameter == null }
|
||||
?: error("Inline class has no underlying property: $this")
|
||||
underlyingProperty.type as SimpleType
|
||||
}
|
||||
|
||||
return InlineClassRepresentation(propertyName, type)
|
||||
}
|
||||
|
||||
override fun toString() =
|
||||
"deserialized ${if (isExpect) "expect " else ""}class $name" // not using descriptor renderer to preserve laziness
|
||||
|
||||
|
||||
Reference in New Issue
Block a user