diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/WrappedDescriptors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/WrappedDescriptors.kt index b68847ab0b1..c1ca78317af 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/WrappedDescriptors.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/descriptors/WrappedDescriptors.kt @@ -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 diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt index 6905e443dc5..e29b6fd343d 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt @@ -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 } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java index 57bbc594436..a45eb8853cb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java @@ -46,16 +46,30 @@ public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor public SimpleType invoke() { return TypeUtils.makeUnsubstitutedType( AbstractClassDescriptor.this, getUnsubstitutedMemberScope(), - new Function1() { + new Function1() { @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(); } } ); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractTypeAliasDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractTypeAliasDescriptor.kt index e27714124ba..69ee9878b10 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractTypeAliasDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractTypeAliasDescriptor.kt @@ -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() - ?.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 } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt index bd25acb6458..a5871b9b762 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt @@ -68,7 +68,7 @@ class IntersectionTypeConstructor(typesToIntersect: Collection) : Ty KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( Annotations.EMPTY, this, listOf(), false, this.createScopeForKotlinType() ) { kotlinTypeRefiner -> - this.refine(kotlinTypeRefiner).createScopeForKotlinType() + this.refine(kotlinTypeRefiner).createType() } override fun hashCode(): Int = hashCode diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt index 25d43c2c769..78607a33815 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt @@ -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, kotlinTypeRefiner: KotlinTypeRefiner? = null ): MemberScope { - val basicDescriptor = constructor.declarationDescriptor - val classId = basicDescriptor.safeAs()?.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, - 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): 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 + ): 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, 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, 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 } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 3c38b061231..1031c466a63 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -203,12 +203,21 @@ public class TypeUtils { @NotNull public static SimpleType makeUnsubstitutedType( ClassifierDescriptor classifierDescriptor, MemberScope unsubstitutedMemberScope, - Function1 scopeFactory + Function1 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 refinedTypeFactory + ) { List arguments = getDefaultTypeProjections(typeConstructor.getParameters()); return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( Annotations.Companion.getEMPTY(), @@ -216,7 +225,7 @@ public class TypeUtils { arguments, false, unsubstitutedMemberScope, - scopeFactory + refinedTypeFactory ); }