[API Usage] Support type refinement from expect class to type aliases
It's necessary when expect class is actualized via typealias To support it properly, we need to return AbbriviatedType instead of SimpleTypeImpl, thus scopeFactory is not enough anymore
This commit is contained in:
committed by
Dmitry Savvinov
parent
04717b57c9
commit
9c27abde7f
+2
-2
@@ -580,7 +580,7 @@ open class WrappedClassDescriptor(
|
||||
|
||||
|
||||
private val _defaultType: SimpleType by lazy {
|
||||
TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope) { unsubstitutedMemberScope }
|
||||
TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope, KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY)
|
||||
}
|
||||
|
||||
override fun getDefaultType(): SimpleType = _defaultType
|
||||
@@ -691,7 +691,7 @@ open class WrappedEnumEntryDescriptor(
|
||||
|
||||
|
||||
private val _defaultType: SimpleType by lazy {
|
||||
TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope) { unsubstitutedMemberScope }
|
||||
TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope, KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY)
|
||||
}
|
||||
|
||||
override fun getDefaultType(): SimpleType = _defaultType
|
||||
|
||||
@@ -102,8 +102,16 @@ internal object RawSubstitution : TypeSubstitution() {
|
||||
return when (declaration) {
|
||||
is TypeParameterDescriptor -> eraseType(declaration.getErasedUpperBound())
|
||||
is ClassDescriptor -> {
|
||||
val declarationForUpper =
|
||||
type.upperIfFlexible().constructor.declarationDescriptor
|
||||
|
||||
check(declarationForUpper is ClassDescriptor) {
|
||||
"For some reason declaration for upper bound is not a class " +
|
||||
"but \"$declarationForUpper\" while for lower it's \"$declaration\""
|
||||
}
|
||||
|
||||
val (lower, isRawL) = eraseInflexibleBasedOnClassDescriptor(type.lowerIfFlexible(), declaration, lowerTypeAttr)
|
||||
val (upper, isRawU) = eraseInflexibleBasedOnClassDescriptor(type.upperIfFlexible(), declaration, upperTypeAttr)
|
||||
val (upper, isRawU) = eraseInflexibleBasedOnClassDescriptor(type.upperIfFlexible(), declarationForUpper, upperTypeAttr)
|
||||
|
||||
if (isRawL || isRawU) {
|
||||
RawTypeImpl(lower, upper)
|
||||
@@ -135,17 +143,18 @@ internal object RawSubstitution : TypeSubstitution() {
|
||||
|
||||
val memberScope = declaration.getMemberScope(RawSubstitution)
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
type.annotations, type.constructor,
|
||||
type.constructor.parameters.map { parameter ->
|
||||
type.annotations, declaration.typeConstructor,
|
||||
declaration.typeConstructor.parameters.map { parameter ->
|
||||
computeProjection(parameter, attr)
|
||||
},
|
||||
type.isMarkedNullable, memberScope
|
||||
) factory@{ kotlinTypeRefiner ->
|
||||
val classId = (declaration as? ClassDescriptor)?.classId ?: return@factory memberScope
|
||||
val classId = (declaration as? ClassDescriptor)?.classId ?: return@factory null
|
||||
@UseExperimental(TypeRefinement::class)
|
||||
val refinedClassDescriptor = kotlinTypeRefiner.findClassAcrossModuleDependencies(classId) ?: return@factory null
|
||||
if (refinedClassDescriptor == declaration) return@factory null
|
||||
|
||||
kotlinTypeRefiner
|
||||
.findClassAcrossModuleDependencies(classId)
|
||||
?.getRefinedMemberScopeIfPossible(RawSubstitution, moduleDescriptor) ?: memberScope
|
||||
eraseInflexibleBasedOnClassDescriptor(type, refinedClassDescriptor, attr).first
|
||||
} to true
|
||||
}
|
||||
|
||||
|
||||
+20
-6
@@ -46,16 +46,30 @@ public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor
|
||||
public SimpleType invoke() {
|
||||
return TypeUtils.makeUnsubstitutedType(
|
||||
AbstractClassDescriptor.this, getUnsubstitutedMemberScope(),
|
||||
new Function1<KotlinTypeRefiner, MemberScope>() {
|
||||
new Function1<KotlinTypeRefiner, SimpleType>() {
|
||||
@Override
|
||||
public MemberScope invoke(KotlinTypeRefiner kotlinTypeRefiner) {
|
||||
ClassDescriptor descriptor = kotlinTypeRefiner.refineDescriptor(AbstractClassDescriptor.this);
|
||||
if (descriptor == null) return getUnsubstitutedMemberScope(kotlinTypeRefiner);
|
||||
public SimpleType invoke(KotlinTypeRefiner kotlinTypeRefiner) {
|
||||
ClassifierDescriptor descriptor = kotlinTypeRefiner.refineDescriptor(AbstractClassDescriptor.this);
|
||||
// If we've refined descriptor
|
||||
if (descriptor == null) return defaultType.invoke();
|
||||
|
||||
if (descriptor instanceof TypeAliasDescriptor) {
|
||||
return KotlinTypeFactory.computeExpandedType(
|
||||
(TypeAliasDescriptor) descriptor,
|
||||
TypeUtils.getDefaultTypeProjections(descriptor.getTypeConstructor().getParameters())
|
||||
);
|
||||
}
|
||||
|
||||
if (descriptor instanceof ModuleAwareClassDescriptor) {
|
||||
return ((ModuleAwareClassDescriptor) descriptor).getUnsubstitutedMemberScope(kotlinTypeRefiner);
|
||||
TypeConstructor refinedConstructor = descriptor.getTypeConstructor().refine(kotlinTypeRefiner);
|
||||
return TypeUtils.makeUnsubstitutedType(
|
||||
refinedConstructor,
|
||||
((ModuleAwareClassDescriptor) descriptor).getUnsubstitutedMemberScope(kotlinTypeRefiner),
|
||||
this
|
||||
);
|
||||
}
|
||||
return descriptor.getUnsubstitutedMemberScope();
|
||||
|
||||
return descriptor.getDefaultType();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
+2
-7
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
abstract class AbstractTypeAliasDescriptor(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
@@ -96,11 +95,7 @@ abstract class AbstractTypeAliasDescriptor(
|
||||
@UseExperimental(TypeRefinement::class)
|
||||
protected fun computeDefaultType(): SimpleType =
|
||||
TypeUtils.makeUnsubstitutedType(this, classDescriptor?.unsubstitutedMemberScope ?: MemberScope.Empty) { kotlinTypeRefiner ->
|
||||
classDescriptor
|
||||
?.let { kotlinTypeRefiner.refineDescriptor(it) }
|
||||
?.safeAs<ClassDescriptor>()
|
||||
?.unsubstitutedMemberScope
|
||||
?: MemberScope.Empty
|
||||
kotlinTypeRefiner.refineDescriptor(this)?.defaultType
|
||||
}
|
||||
|
||||
private val typeConstructor = object : TypeConstructor {
|
||||
@@ -127,6 +122,6 @@ abstract class AbstractTypeAliasDescriptor(
|
||||
// There must be @TypeRefinement, but there is a bug with anonymous objects and experimental annotations
|
||||
// See KT-31728
|
||||
@UseExperimental(TypeRefinement::class)
|
||||
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): TypeConstructor? = this
|
||||
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): TypeConstructor = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class IntersectionTypeConstructor(typesToIntersect: Collection<KotlinType>) : Ty
|
||||
KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
Annotations.EMPTY, this, listOf(), false, this.createScopeForKotlinType()
|
||||
) { kotlinTypeRefiner ->
|
||||
this.refine(kotlinTypeRefiner).createScopeForKotlinType()
|
||||
this.refine(kotlinTypeRefiner).createType()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = hashCode
|
||||
|
||||
@@ -16,18 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.getRefinedMemberScopeIfPossible
|
||||
import org.jetbrains.kotlin.descriptors.impl.getRefinedUnsubstitutedMemberScopeIfPossible
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getKotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
typealias RefinedTypeFactory = (KotlinTypeRefiner) -> SimpleType?
|
||||
|
||||
@@ -40,29 +40,17 @@ object KotlinTypeFactory {
|
||||
arguments: List<TypeProjection>,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner? = null
|
||||
): MemberScope {
|
||||
val basicDescriptor = constructor.declarationDescriptor
|
||||
val classId = basicDescriptor.safeAs<ClassifierDescriptorWithTypeParameters>()?.classId
|
||||
val descriptor =
|
||||
if (classId != null)
|
||||
kotlinTypeRefiner?.findClassAcrossModuleDependencies(classId) ?: basicDescriptor
|
||||
else basicDescriptor
|
||||
|
||||
val descriptor = constructor.declarationDescriptor
|
||||
return when (descriptor) {
|
||||
is TypeParameterDescriptor -> descriptor.getDefaultType().memberScope
|
||||
is ClassDescriptor -> {
|
||||
val refinedConstructor =
|
||||
if (descriptor != basicDescriptor)
|
||||
descriptor.typeConstructor
|
||||
else
|
||||
constructor
|
||||
|
||||
val refinerToUse = kotlinTypeRefiner ?: descriptor.module.getKotlinTypeRefiner()
|
||||
if (arguments.isEmpty())
|
||||
descriptor.getRefinedUnsubstitutedMemberScopeIfPossible(refinerToUse)
|
||||
else
|
||||
// REVIEW
|
||||
descriptor.getRefinedMemberScopeIfPossible(
|
||||
TypeConstructorSubstitution.create(refinedConstructor, arguments),
|
||||
TypeConstructorSubstitution.create(constructor, arguments),
|
||||
refinerToUse
|
||||
)
|
||||
}
|
||||
@@ -72,11 +60,14 @@ object KotlinTypeFactory {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
@UseExperimental(TypeRefinement::class)
|
||||
fun simpleType(
|
||||
annotations: Annotations,
|
||||
constructor: TypeConstructor,
|
||||
arguments: List<TypeProjection>,
|
||||
nullable: Boolean
|
||||
nullable: Boolean,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner? = null
|
||||
): SimpleType {
|
||||
if (annotations.isEmpty() && arguments.isEmpty() && !nullable && constructor.declarationDescriptor != null) {
|
||||
return constructor.declarationDescriptor!!.defaultType
|
||||
@@ -84,13 +75,45 @@ object KotlinTypeFactory {
|
||||
|
||||
return simpleTypeWithNonTrivialMemberScope(
|
||||
annotations, constructor, arguments, nullable,
|
||||
computeMemberScope(constructor, arguments)
|
||||
) { moduleDescriptor ->
|
||||
computeMemberScope(constructor, arguments, moduleDescriptor)
|
||||
computeMemberScope(constructor, arguments, kotlinTypeRefiner)
|
||||
) f@{ refiner ->
|
||||
val expandedTypeOrRefinedConstructor = refineConstructor(constructor, refiner, arguments) ?: return@f null
|
||||
expandedTypeOrRefinedConstructor.expandedType?.let { return@f it }
|
||||
|
||||
simpleType(annotations, expandedTypeOrRefinedConstructor.refinedConstructor!!, arguments, nullable, refiner)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun TypeAliasDescriptor.computeExpandedType(arguments: List<TypeProjection>): SimpleType {
|
||||
return TypeAliasExpander(TypeAliasExpansionReportStrategy.DO_NOTHING, false).expand(
|
||||
TypeAliasExpansion.create(null, this, arguments), Annotations.EMPTY
|
||||
)
|
||||
}
|
||||
|
||||
@TypeRefinement
|
||||
private fun refineConstructor(
|
||||
constructor: TypeConstructor,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner,
|
||||
arguments: List<TypeProjection>
|
||||
): ExpandedTypeOrRefinedConstructor? {
|
||||
val basicDescriptor = constructor.declarationDescriptor
|
||||
val descriptor = basicDescriptor?.let { kotlinTypeRefiner.refineDescriptor(it) } ?: return null
|
||||
|
||||
if (descriptor == basicDescriptor) return null
|
||||
|
||||
if (descriptor is TypeAliasDescriptor) {
|
||||
return ExpandedTypeOrRefinedConstructor(descriptor.computeExpandedType(arguments), null)
|
||||
}
|
||||
|
||||
val refinedConstructor = descriptor.typeConstructor.refine(kotlinTypeRefiner)
|
||||
return ExpandedTypeOrRefinedConstructor(null, refinedConstructor)
|
||||
}
|
||||
|
||||
private class ExpandedTypeOrRefinedConstructor(val expandedType: SimpleType?, val refinedConstructor: TypeConstructor?)
|
||||
|
||||
@JvmStatic
|
||||
@UseExperimental(TypeRefinement::class)
|
||||
fun simpleTypeWithNonTrivialMemberScope(
|
||||
annotations: Annotations,
|
||||
constructor: TypeConstructor,
|
||||
@@ -98,13 +121,23 @@ object KotlinTypeFactory {
|
||||
nullable: Boolean,
|
||||
memberScope: MemberScope
|
||||
): SimpleType =
|
||||
SimpleTypeImpl(constructor, arguments, nullable, memberScope, { memberScope })
|
||||
.let {
|
||||
if (annotations.isEmpty())
|
||||
it
|
||||
else
|
||||
AnnotatedSimpleType(it, annotations)
|
||||
}
|
||||
SimpleTypeImpl(constructor, arguments, nullable, memberScope) { kotlinTypeRefiner ->
|
||||
val expandedTypeOrRefinedConstructor = refineConstructor(constructor, kotlinTypeRefiner, arguments) ?: return@SimpleTypeImpl null
|
||||
expandedTypeOrRefinedConstructor.expandedType?.let { return@SimpleTypeImpl it }
|
||||
|
||||
simpleTypeWithNonTrivialMemberScope(
|
||||
annotations,
|
||||
expandedTypeOrRefinedConstructor.refinedConstructor!!,
|
||||
arguments,
|
||||
nullable,
|
||||
memberScope
|
||||
)
|
||||
}.let {
|
||||
if (annotations.isEmpty())
|
||||
it
|
||||
else
|
||||
AnnotatedSimpleType(it, annotations)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun simpleTypeWithNonTrivialMemberScope(
|
||||
@@ -113,9 +146,9 @@ object KotlinTypeFactory {
|
||||
arguments: List<TypeProjection>,
|
||||
nullable: Boolean,
|
||||
memberScope: MemberScope,
|
||||
scopeFactory: (KotlinTypeRefiner) -> MemberScope
|
||||
refinedTypeFactory: RefinedTypeFactory
|
||||
): SimpleType =
|
||||
SimpleTypeImpl(constructor, arguments, nullable, memberScope, scopeFactory)
|
||||
SimpleTypeImpl(constructor, arguments, nullable, memberScope, refinedTypeFactory)
|
||||
.let {
|
||||
if (annotations.isEmpty())
|
||||
it
|
||||
@@ -164,7 +197,7 @@ private class SimpleTypeImpl(
|
||||
override val arguments: List<TypeProjection>,
|
||||
override val isMarkedNullable: Boolean,
|
||||
override val memberScope: MemberScope,
|
||||
private val scopeFactory: (KotlinTypeRefiner) -> MemberScope
|
||||
private val refinedTypeFactory: RefinedTypeFactory
|
||||
) : SimpleType() {
|
||||
@TypeRefinement
|
||||
override val hasNotTrivialRefinementFactory: Boolean get() = true
|
||||
@@ -191,12 +224,7 @@ private class SimpleTypeImpl(
|
||||
|
||||
@TypeRefinement
|
||||
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): SimpleType {
|
||||
if (constructor.declarationDescriptor?.module?.getKotlinTypeRefiner() === kotlinTypeRefiner) return this
|
||||
|
||||
return SimpleTypeImpl(
|
||||
constructor.refine(kotlinTypeRefiner) ?: constructor,
|
||||
arguments, isMarkedNullable, scopeFactory(kotlinTypeRefiner), scopeFactory
|
||||
)
|
||||
return refinedTypeFactory(kotlinTypeRefiner) ?: this
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,12 +203,21 @@ public class TypeUtils {
|
||||
@NotNull
|
||||
public static SimpleType makeUnsubstitutedType(
|
||||
ClassifierDescriptor classifierDescriptor, MemberScope unsubstitutedMemberScope,
|
||||
Function1<KotlinTypeRefiner, MemberScope> scopeFactory
|
||||
Function1<KotlinTypeRefiner, SimpleType> refinedTypeFactory
|
||||
) {
|
||||
if (ErrorUtils.isError(classifierDescriptor)) {
|
||||
return ErrorUtils.createErrorType("Unsubstituted type for " + classifierDescriptor);
|
||||
}
|
||||
TypeConstructor typeConstructor = classifierDescriptor.getTypeConstructor();
|
||||
return makeUnsubstitutedType(typeConstructor, unsubstitutedMemberScope, refinedTypeFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SimpleType makeUnsubstitutedType(
|
||||
@NotNull TypeConstructor typeConstructor,
|
||||
@NotNull MemberScope unsubstitutedMemberScope,
|
||||
@NotNull Function1<KotlinTypeRefiner, SimpleType> refinedTypeFactory
|
||||
) {
|
||||
List<TypeProjection> arguments = getDefaultTypeProjections(typeConstructor.getParameters());
|
||||
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||
Annotations.Companion.getEMPTY(),
|
||||
@@ -216,7 +225,7 @@ public class TypeUtils {
|
||||
arguments,
|
||||
false,
|
||||
unsubstitutedMemberScope,
|
||||
scopeFactory
|
||||
refinedTypeFactory
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user