diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/DeferredType.java b/compiler/frontend/src/org/jetbrains/kotlin/types/DeferredType.java index 5c7d348d7f2..0c06987bcfe 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/DeferredType.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/DeferredType.java @@ -22,6 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.StorageManager; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; +import org.jetbrains.kotlin.types.refinement.TypeRefinement; import org.jetbrains.kotlin.util.Box; import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException; @@ -43,7 +45,7 @@ public class DeferredType extends WrappedType { trace.record(DEFERRED_TYPE, new Box<>(deferredType)); return deferredType; } - + @NotNull /*package private*/ static DeferredType createRecursionIntolerant( @NotNull StorageManager storageManager, @@ -60,9 +62,38 @@ public class DeferredType extends WrappedType { private final NotNullLazyValue lazyValue; private DeferredType(@NotNull NotNullLazyValue lazyValue) { + super(); this.lazyValue = lazyValue; } + @NotNull + @Override + public KotlinType refine(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { + return new DeferredType(new NotNullLazyValue() { + @NotNull + @Override + public String renderDebugInformation() { + return lazyValue.renderDebugInformation(); + } + + @Override + public boolean isComputed() { + return lazyValue.isComputed(); + } + + @Override + public boolean isComputing() { + return lazyValue.isComputing(); + } + + @Override + @TypeRefinement + public KotlinType invoke() { + return kotlinTypeRefiner.refineType(lazyValue.invoke()); + } + }); + } + public boolean isComputing() { return lazyValue.isComputing(); } 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 6a5baaf0f32..b68847ab0b1 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) + TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope) { unsubstitutedMemberScope } } override fun getDefaultType(): SimpleType = _defaultType @@ -691,7 +691,7 @@ open class WrappedEnumEntryDescriptor( private val _defaultType: SimpleType by lazy { - TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope) + TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope) { unsubstitutedMemberScope } } 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 160a6ec0c87..6905e443dc5 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 @@ -24,9 +24,12 @@ import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererOptions import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.builtIns class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType(lowerBound, upperBound), RawType { @@ -80,6 +83,12 @@ class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType if (newLower == newUpper) return newLower return renderer.renderFlexibleType(newLower, newUpper, builtIns) } + + @TypeRefinement + @UseExperimental(TypeRefinement::class) + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): FlexibleType { + return RawTypeImpl(kotlinTypeRefiner.refineType(lowerBound) as SimpleType, kotlinTypeRefiner.refineType(upperBound) as SimpleType) + } } internal object RawSubstitution : TypeSubstitution() { @@ -124,13 +133,20 @@ internal object RawSubstitution : TypeSubstitution() { if (type.isError) return ErrorUtils.createErrorType("Raw error type: ${type.constructor}") to false + val memberScope = declaration.getMemberScope(RawSubstitution) return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( type.annotations, type.constructor, type.constructor.parameters.map { parameter -> computeProjection(parameter, attr) }, - type.isMarkedNullable, declaration.getMemberScope(RawSubstitution) - ) to true + type.isMarkedNullable, memberScope + ) factory@{ kotlinTypeRefiner -> + val classId = (declaration as? ClassDescriptor)?.classId ?: return@factory memberScope + + kotlinTypeRefiner + .findClassAcrossModuleDependencies(classId) + ?.getRefinedMemberScopeIfPossible(RawSubstitution, moduleDescriptor) ?: memberScope + } to true } fun computeProjection( @@ -150,13 +166,13 @@ internal object RawSubstitution : TypeSubstitution() { ) JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND, JavaTypeFlexibility.INFLEXIBLE -> { if (!parameter.variance.allowsOutPosition) - // in T -> Comparable + // in T -> Comparable TypeProjectionImpl(Variance.INVARIANT, parameter.builtIns.nothingType) else if (erasedUpperBound.constructor.parameters.isNotEmpty()) - // T : Enum -> out Enum<*> + // T : Enum -> out Enum<*> TypeProjectionImpl(Variance.OUT_VARIANCE, erasedUpperBound) else - // T : String -> * + // T : String -> * makeStarProjection(parameter, attr) } } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index 1ec73eecced..2aba640720e 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext import org.jetbrains.kotlin.types.model.KotlinTypeMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.createProjection import org.jetbrains.kotlin.types.typeUtil.isTypeParameter @@ -253,4 +254,7 @@ internal class NotNullTypeParameter(override val delegate: SimpleType) : NotNull override fun replaceAnnotations(newAnnotations: Annotations) = NotNullTypeParameter(delegate.replaceAnnotations(newAnnotations)) override fun makeNullableAsSpecified(newNullability: Boolean) = if (newNullability) delegate.makeNullableAsSpecified(true) else this + + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = NotNullTypeParameter(delegate) } 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 a1812029037..57bbc594436 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.descriptors.impl; import kotlin.jvm.functions.Function0; +import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.name.Name; @@ -43,7 +44,21 @@ public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor this.defaultType = storageManager.createLazyValue(new Function0() { @Override public SimpleType invoke() { - return TypeUtils.makeUnsubstitutedType(AbstractClassDescriptor.this, getUnsubstitutedMemberScope()); + return TypeUtils.makeUnsubstitutedType( + AbstractClassDescriptor.this, getUnsubstitutedMemberScope(), + new Function1() { + @Override + public MemberScope invoke(KotlinTypeRefiner kotlinTypeRefiner) { + ClassDescriptor descriptor = kotlinTypeRefiner.refineDescriptor(AbstractClassDescriptor.this); + if (descriptor == null) return getUnsubstitutedMemberScope(kotlinTypeRefiner); + + if (descriptor instanceof ModuleAwareClassDescriptor) { + return ((ModuleAwareClassDescriptor) descriptor).getUnsubstitutedMemberScope(kotlinTypeRefiner); + } + return descriptor.getUnsubstitutedMemberScope(); + } + } + ); } }); this.unsubstitutedInnerClassesScope = storageManager.createLazyValue(new Function0() { 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 74473890d7f..e27714124ba 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractTypeAliasDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractTypeAliasDescriptor.kt @@ -21,9 +21,13 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.resolve.descriptorUtil.classId 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 org.jetbrains.kotlin.types.refinement.TypeRefinement +import org.jetbrains.kotlin.utils.addToStdlib.safeAs abstract class AbstractTypeAliasDescriptor( containingDeclaration: DeclarationDescriptor, @@ -89,8 +93,15 @@ abstract class AbstractTypeAliasDescriptor( protected abstract fun getTypeConstructorTypeParameters(): List + @UseExperimental(TypeRefinement::class) protected fun computeDefaultType(): SimpleType = - TypeUtils.makeUnsubstitutedType(this, classDescriptor?.unsubstitutedMemberScope ?: MemberScope.Empty) + TypeUtils.makeUnsubstitutedType(this, classDescriptor?.unsubstitutedMemberScope ?: MemberScope.Empty) { kotlinTypeRefiner -> + classDescriptor + ?.let { kotlinTypeRefiner.refineDescriptor(it) } + ?.safeAs() + ?.unsubstitutedMemberScope + ?: MemberScope.Empty + } private val typeConstructor = object : TypeConstructor { override fun getDeclarationDescriptor(): TypeAliasDescriptor = diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt index 04a4f973e91..404a58d0b38 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt @@ -24,8 +24,10 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.Variance.IN_VARIANCE import org.jetbrains.kotlin.types.Variance.OUT_VARIANCE +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor import org.jetbrains.kotlin.types.model.CapturedTypeMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.builtIns interface CapturedTypeConstructor : TypeConstructor { @@ -102,6 +104,10 @@ class CapturedType( override fun replaceAnnotations(newAnnotations: Annotations): CapturedType = CapturedType(typeProjection, constructor, isMarkedNullable, newAnnotations) + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = + CapturedType(typeProjection.refine(kotlinTypeRefiner), constructor, isMarkedNullable, annotations) } fun createCapturedType(typeProjection: TypeProjection): KotlinType = CapturedType(typeProjection) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt index 487f3e5423e..f07d2ede12b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorType.kt @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.types import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.refinement.TypeRefinement open class ErrorType @JvmOverloads internal constructor( override val constructor: TypeConstructor, @@ -35,6 +37,9 @@ open class ErrorType @JvmOverloads internal constructor( override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = ErrorType(constructor, memberScope, arguments, newNullability) + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = this } class UnresolvedType( @@ -46,4 +51,7 @@ class UnresolvedType( ) : ErrorType(constructor, memberScope, arguments, isMarkedNullable) { override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = UnresolvedType(presentableName, constructor, memberScope, arguments, newNullability) + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = this } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt index 533cc63f58c..bd25acb6458 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt @@ -63,10 +63,13 @@ class IntersectionTypeConstructor(typesToIntersect: Collection) : Ty return intersectedTypes == other.intersectedTypes } + @UseExperimental(TypeRefinement::class) fun createType(): SimpleType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( Annotations.EMPTY, this, listOf(), false, this.createScopeForKotlinType() - ) + ) { kotlinTypeRefiner -> + this.refine(kotlinTypeRefiner).createScopeForKotlinType() + } override fun hashCode(): Int = hashCode diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt index 489ed6bbd89..7f8caf554a0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt @@ -21,11 +21,13 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererOptions import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.StrictEqualityTypeChecker import org.jetbrains.kotlin.types.model.FlexibleTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.kotlin.types.model.TypeArgumentListMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement /** * [KotlinType] has only two direct subclasses: [WrappedType] and [UnwrappedType]. @@ -53,6 +55,28 @@ sealed class KotlinType : Annotated, KotlinTypeMarker { abstract fun unwrap(): UnwrappedType + /** + * Returns refined type using passed KotlinTypeRefiner + * + * Refined type has its member scope refined + * + * Note #1: supertypes and type arguments ARE NOT refined! + * + * Note #2: Correct subtyping or equality for refined types from different Refiners *is not guaranteed* + * + * Implementation notice: + * Basically, this is a simple form of double-dispatching, used to incapsulate + * structure of specific type-implementations, which means that compound types most probably would like + * to implement it by recursively calling [refine] on components. + * A very few "basic" types (like [SimpleTypeImpl]) implement it by actually adjusting + * content using passed refiner and other low-level methods + */ + @TypeRefinement + abstract fun refine(kotlinTypeRefiner: KotlinTypeRefiner): KotlinType + + @TypeRefinement + open val hasNotTrivialRefinementFactory: Boolean get() = false + /* '0' means "hashCode wasn't computed" Note #1. We don't use 'null' as a sign of "uncomputed value" to avoid boxing, @@ -139,6 +163,9 @@ sealed class UnwrappedType : KotlinType() { abstract fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType final override fun unwrap(): UnwrappedType = this + + @TypeRefinement + abstract override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): UnwrappedType } /** @@ -150,6 +177,9 @@ abstract class SimpleType : UnwrappedType(), SimpleTypeMarker, TypeArgumentListM abstract override fun replaceAnnotations(newAnnotations: Annotations): SimpleType abstract override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType + @TypeRefinement + abstract override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): SimpleType + override fun toString(): String { return buildString { for (annotation in annotations) { @@ -185,6 +215,9 @@ abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleTy override val memberScope: MemberScope get() = delegate.memberScope override fun toString(): String = DescriptorRenderer.DEBUG_TEXT.renderType(this) + + @TypeRefinement + abstract override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): FlexibleType } val KotlinType.isError: Boolean diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt index 18f20bd57c0..25d43c2c769 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt @@ -16,24 +16,55 @@ package org.jetbrains.kotlin.types -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.* 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.NewKotlinTypeChecker +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? object KotlinTypeFactory { - private fun computeMemberScope(constructor: TypeConstructor, arguments: List): MemberScope { - val descriptor = constructor.declarationDescriptor + val EMPTY_REFINED_TYPE_FACTORY: RefinedTypeFactory = { _ -> null } + + @UseExperimental(TypeRefinement::class) + private fun computeMemberScope( + constructor: TypeConstructor, + 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 + 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.defaultType.memberScope + descriptor.getRefinedUnsubstitutedMemberScopeIfPossible(refinerToUse) else - descriptor.getMemberScope(TypeConstructorSubstitution.create(constructor, arguments)) + // REVIEW + descriptor.getRefinedMemberScopeIfPossible( + TypeConstructorSubstitution.create(refinedConstructor, arguments), + refinerToUse + ) } is TypeAliasDescriptor -> ErrorUtils.createErrorScope("Scope for abbreviation: ${descriptor.name}", true) else -> throw IllegalStateException("Unsupported classifier: $descriptor for constructor: $constructor") @@ -52,12 +83,11 @@ object KotlinTypeFactory { } return simpleTypeWithNonTrivialMemberScope( - annotations, - constructor, - arguments, - nullable, + annotations, constructor, arguments, nullable, computeMemberScope(constructor, arguments) - ) + ) { moduleDescriptor -> + computeMemberScope(constructor, arguments, moduleDescriptor) + } } @JvmStatic @@ -68,7 +98,24 @@ object KotlinTypeFactory { nullable: Boolean, memberScope: MemberScope ): SimpleType = - SimpleTypeImpl(constructor, arguments, nullable, memberScope) + SimpleTypeImpl(constructor, arguments, nullable, memberScope, { memberScope }) + .let { + if (annotations.isEmpty()) + it + else + AnnotatedSimpleType(it, annotations) + } + + @JvmStatic + fun simpleTypeWithNonTrivialMemberScope( + annotations: Annotations, + constructor: TypeConstructor, + arguments: List, + nullable: Boolean, + memberScope: MemberScope, + scopeFactory: (KotlinTypeRefiner) -> MemberScope + ): SimpleType = + SimpleTypeImpl(constructor, arguments, nullable, memberScope, scopeFactory) .let { if (annotations.isEmpty()) it @@ -116,8 +163,12 @@ private class SimpleTypeImpl( override val constructor: TypeConstructor, override val arguments: List, override val isMarkedNullable: Boolean, - override val memberScope: MemberScope + override val memberScope: MemberScope, + private val scopeFactory: (KotlinTypeRefiner) -> MemberScope ) : SimpleType() { + @TypeRefinement + override val hasNotTrivialRefinementFactory: Boolean get() = true + override val annotations: Annotations get() = Annotations.EMPTY override fun replaceAnnotations(newAnnotations: Annotations) = @@ -127,16 +178,26 @@ private class SimpleTypeImpl( AnnotatedSimpleType(this, newAnnotations) override fun makeNullableAsSpecified(newNullability: Boolean) = when { - newNullability == isMarkedNullable -> this - newNullability -> NullableSimpleType(this) - else -> NotNullSimpleType(this) - } + newNullability == isMarkedNullable -> this + newNullability -> NullableSimpleType(this) + else -> NotNullSimpleType(this) + } init { if (memberScope is ErrorUtils.ErrorScope) { throw IllegalStateException("SimpleTypeImpl should not be created for error type: $memberScope\n$constructor") } } + + @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 + ) + } } abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() { @@ -155,14 +216,23 @@ abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : Del private class AnnotatedSimpleType( delegate: SimpleType, override val annotations: Annotations -) : DelegatingSimpleTypeImpl(delegate) +) : DelegatingSimpleTypeImpl(delegate) { + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = AnnotatedSimpleType(delegate, annotations) +} private class NullableSimpleType(delegate: SimpleType) : DelegatingSimpleTypeImpl(delegate) { override val isMarkedNullable: Boolean get() = true + + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = NullableSimpleType(delegate) } private class NotNullSimpleType(delegate: SimpleType) : DelegatingSimpleTypeImpl(delegate) { override val isMarkedNullable: Boolean get() = false -} \ No newline at end of file + + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = NotNullSimpleType(delegate) +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt index efd4080bb79..4882e66ef8e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/SpecialTypes.kt @@ -20,9 +20,11 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor import org.jetbrains.kotlin.types.checker.NullabilityChecker import org.jetbrains.kotlin.types.model.DefinitelyNotNullTypeMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.canHaveUndefinedNullability abstract class DelegatingSimpleType : SimpleType() { @@ -33,6 +35,13 @@ abstract class DelegatingSimpleType : SimpleType() { override val arguments: List get() = delegate.arguments override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable override val memberScope: MemberScope get() = delegate.memberScope + + @TypeRefinement + abstract fun replaceDelegate(delegate: SimpleType): DelegatingSimpleType + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): SimpleType = + replaceDelegate(kotlinTypeRefiner.refineType(delegate) as SimpleType) } class AbbreviatedType(override val delegate: SimpleType, val abbreviation: SimpleType) : DelegatingSimpleType() { @@ -43,6 +52,17 @@ class AbbreviatedType(override val delegate: SimpleType, val abbreviation: Simpl override fun makeNullableAsSpecified(newNullability: Boolean) = AbbreviatedType(delegate.makeNullableAsSpecified(newNullability), abbreviation.makeNullableAsSpecified(newNullability)) + + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = AbbreviatedType(delegate, abbreviation) + + @TypeRefinement + @UseExperimental(TypeRefinement::class) + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): AbbreviatedType = + AbbreviatedType( + kotlinTypeRefiner.refineType(delegate) as SimpleType, + kotlinTypeRefiner.refineType(abbreviation) as SimpleType + ) } fun KotlinType.getAbbreviatedType(): AbbreviatedType? = unwrap() as? AbbreviatedType @@ -53,12 +73,21 @@ fun SimpleType.withAbbreviation(abbreviatedType: SimpleType): SimpleType { return AbbreviatedType(this, abbreviatedType) } -class LazyWrappedType(storageManager: StorageManager, computation: () -> KotlinType): WrappedType() { +class LazyWrappedType( + private val storageManager: StorageManager, + private val computation: () -> KotlinType +) : WrappedType() { private val lazyValue = storageManager.createLazyValue(computation) override val delegate: KotlinType get() = lazyValue() override fun isComputed(): Boolean = lazyValue.isComputed() + + @TypeRefinement + @UseExperimental(TypeRefinement::class) + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = LazyWrappedType(storageManager) { + kotlinTypeRefiner.refineType(computation()) + } } class DefinitelyNotNullType private constructor(val original: SimpleType) : DelegatingSimpleType(), CustomTypeVariable, @@ -108,6 +137,9 @@ class DefinitelyNotNullType private constructor(val original: SimpleType) : Dele if (newNullability) delegate.makeNullableAsSpecified(newNullability) else this override fun toString(): String = "$delegate!!" + + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = DefinitelyNotNullType(delegate) } val KotlinType.isDefinitelyNotNullType: Boolean diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt index c9b0a256468..eca738f72cd 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt @@ -16,13 +16,14 @@ package org.jetbrains.kotlin.types -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.refinement.TypeRefinement class StarProjectionImpl( - private val typeParameter: TypeParameterDescriptor + private val typeParameter: TypeParameterDescriptor ) : TypeProjectionBase() { override fun isStarProjection() = true @@ -34,6 +35,11 @@ class StarProjectionImpl( } override fun getType() = _type + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): TypeProjection = + TypeBasedStarProjectionImpl(kotlinTypeRefiner.refineType(type)) + } fun TypeParameterDescriptor.starProjectionType(): KotlinType { @@ -58,4 +64,8 @@ class TypeBasedStarProjectionImpl( override fun getProjectionKind() = Variance.OUT_VARIANCE override fun getType() = _type + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): TypeProjection = + TypeBasedStarProjectionImpl(kotlinTypeRefiner.refineType(_type)) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt index 9096e70788f..85e3d81a2bc 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt @@ -7,7 +7,9 @@ package org.jetbrains.kotlin.types import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.model.StubTypeMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement // This type is used as a stub for postponed type variables, which are important for coroutine inference class StubType( @@ -37,4 +39,7 @@ class StubType( override fun toString(): String { return "NonFixed: $originalTypeVariable" } -} \ No newline at end of file + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = this +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjection.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjection.java index 24a4aafe6ed..b31841fd09e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjection.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjection.java @@ -17,7 +17,9 @@ package org.jetbrains.kotlin.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.types.model.TypeArgumentMarker; +import org.jetbrains.kotlin.types.refinement.TypeRefinement; public interface TypeProjection extends TypeArgumentMarker { @NotNull @@ -27,4 +29,8 @@ public interface TypeProjection extends TypeArgumentMarker { KotlinType getType(); boolean isStarProjection(); + + @NotNull + @TypeRefinement + TypeProjection refine(@NotNull KotlinTypeRefiner kotlinTypeRefiner); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjectionImpl.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjectionImpl.java index 920bbe4194c..9ae2b9c550e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjectionImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeProjectionImpl.java @@ -17,6 +17,8 @@ package org.jetbrains.kotlin.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; +import org.jetbrains.kotlin.types.refinement.TypeRefinement; public class TypeProjectionImpl extends TypeProjectionBase { private final Variance projection; @@ -47,4 +49,11 @@ public class TypeProjectionImpl extends TypeProjectionBase { public boolean isStarProjection() { return false; } + + @NotNull + @Override + @TypeRefinement + public TypeProjection refine(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { + return new TypeProjectionImpl(projection, kotlinTypeRefiner.refineType(type)); + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 66e37d9a706..3c38b061231 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -22,7 +22,9 @@ import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor; import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor; +import org.jetbrains.kotlin.types.refinement.TypeRefinement; import java.util.*; @@ -60,6 +62,20 @@ public class TypeUtils { public String toString() { return name; } + + @NotNull + @Override + @TypeRefinement + public DelegatingSimpleType replaceDelegate(@NotNull SimpleType delegate) { + throw new IllegalStateException(name); + } + + @NotNull + @Override + @TypeRefinement + public SpecialType refine(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { + return this; + } } @NotNull @@ -185,7 +201,10 @@ public class TypeUtils { } @NotNull - public static SimpleType makeUnsubstitutedType(ClassifierDescriptor classifierDescriptor, MemberScope unsubstitutedMemberScope) { + public static SimpleType makeUnsubstitutedType( + ClassifierDescriptor classifierDescriptor, MemberScope unsubstitutedMemberScope, + Function1 scopeFactory + ) { if (ErrorUtils.isError(classifierDescriptor)) { return ErrorUtils.createErrorType("Unsubstituted type for " + classifierDescriptor); } @@ -196,7 +215,8 @@ public class TypeUtils { typeConstructor, arguments, false, - unsubstitutedMemberScope + unsubstitutedMemberScope, + scopeFactory ); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt index d1a6c5a8e60..e6729c60264 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt @@ -19,6 +19,8 @@ package org.jetbrains.kotlin.types import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererOptions +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.refinement.TypeRefinement interface TypeWithEnhancement { val origin: UnwrappedType @@ -38,6 +40,17 @@ class SimpleTypeWithEnhancement( override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = origin.makeNullableAsSpecified(newNullability).wrapEnhancement(enhancement.unwrap().makeNullableAsSpecified(newNullability)) as SimpleType + + @TypeRefinement + override fun replaceDelegate(delegate: SimpleType) = SimpleTypeWithEnhancement(delegate, enhancement) + + @TypeRefinement + @UseExperimental(TypeRefinement::class) + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): SimpleTypeWithEnhancement = + SimpleTypeWithEnhancement( + kotlinTypeRefiner.refineType(delegate) as SimpleType, + kotlinTypeRefiner.refineType(enhancement) + ) } class FlexibleTypeWithEnhancement( @@ -60,6 +73,14 @@ class FlexibleTypeWithEnhancement( } override val delegate: SimpleType get() = origin.delegate + + @TypeRefinement + @UseExperimental(TypeRefinement::class) + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = + FlexibleTypeWithEnhancement( + kotlinTypeRefiner.refineType(origin) as FlexibleType, + kotlinTypeRefiner.refineType(enhancement) + ) } fun KotlinType.getEnhancement(): KotlinType? = when (this) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt index 94da3aa9416..39a31919b33 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/NewCapturedType.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.model.CaptureStatus import org.jetbrains.kotlin.types.model.CapturedTypeMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.utils.DO_NOTHING_2 @@ -139,6 +140,16 @@ class NewCapturedType( override fun makeNullableAsSpecified(newNullability: Boolean) = NewCapturedType(captureStatus, constructor, lowerType, annotations, newNullability) + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = + NewCapturedType( + captureStatus, + constructor.refine(kotlinTypeRefiner), + lowerType?.let { kotlinTypeRefiner.refineType(it).unwrap() }, + annotations, + isMarkedNullable + ) } class NewCapturedTypeConstructor(override val projection: TypeProjection, private var supertypes: List? = null) : diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt index 0fd5245fa39..7722549a206 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt @@ -18,12 +18,13 @@ package org.jetbrains.kotlin.types import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.container.DefaultImplementation -import org.jetbrains.kotlin.container.PlatformExtensionsClashResolver import org.jetbrains.kotlin.container.PlatformSpecificExtension import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererOptions +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.model.DynamicTypeMarker +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.builtIns @DefaultImplementation(impl = DynamicTypesSettings::class) @@ -55,4 +56,7 @@ class DynamicType( override fun replaceAnnotations(newAnnotations: Annotations): DynamicType = DynamicType(delegate.builtIns, newAnnotations) override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String = "dynamic" + + @TypeRefinement + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = this } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt index fc4b57f70aa..37c2f83f3cb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererOptions import org.jetbrains.kotlin.types.checker.ErrorTypesAreEqualToAnything import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.typeUtil.builtIns @@ -134,4 +136,12 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl override fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType = KotlinTypeFactory.flexibleType(lowerBound.makeNullableAsSpecified(newNullability), upperBound.makeNullableAsSpecified(newNullability)) + + @TypeRefinement + @UseExperimental(TypeRefinement::class) + override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = + KotlinTypeFactory.flexibleType( + kotlinTypeRefiner.refineType(lowerBound) as SimpleType, + kotlinTypeRefiner.refineType(upperBound) as SimpleType + ) as FlexibleType }