[Core API] Introduce KotlinType.refine

The most interesting part happens in SimpleType.refine, other types
either don't implement refinement at all (they return just 'this',
mainly it's some special types, like ErrorType and such) or implement
it trivially via recursion (those are "composite" types)

SimpleType.refine captures so-called refinement factory, which is essentially
an injected callback which tells how to reconstruct the type with new
(refined) memberScope.

We have to inject callback because we express quite different types with
SimpleTypeImpl, and some of them need different refinement logic.
Another possible implementation approach (more invasive one) would be
to extract those types in separate subtypes of KotlinType and implement
'refine' via overrides.

The most meaningful callbacks are injected from
'AbstractClassDescriptor.defaultType' and from 'KotlinTypeFactory'.
This commit is contained in:
Dmitry Savvinov
2019-07-10 13:47:16 +03:00
parent c12f5f6055
commit 1d61d75225
21 changed files with 364 additions and 39 deletions
@@ -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<KotlinType> lazyValue;
private DeferredType(@NotNull NotNullLazyValue<KotlinType> lazyValue) {
super();
this.lazyValue = lazyValue;
}
@NotNull
@Override
public KotlinType refine(@NotNull KotlinTypeRefiner kotlinTypeRefiner) {
return new DeferredType(new NotNullLazyValue<KotlinType>() {
@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();
}
@@ -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
@@ -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<Nothing>
// in T -> Comparable<Nothing>
TypeProjectionImpl(Variance.INVARIANT, parameter.builtIns.nothingType)
else if (erasedUpperBound.constructor.parameters.isNotEmpty())
// T : Enum<E> -> out Enum<*>
// T : Enum<E> -> out Enum<*>
TypeProjectionImpl(Variance.OUT_VARIANCE, erasedUpperBound)
else
// T : String -> *
// T : String -> *
makeStarProjection(parameter, attr)
}
}
@@ -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)
}
@@ -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<SimpleType>() {
@Override
public SimpleType invoke() {
return TypeUtils.makeUnsubstitutedType(AbstractClassDescriptor.this, getUnsubstitutedMemberScope());
return TypeUtils.makeUnsubstitutedType(
AbstractClassDescriptor.this, getUnsubstitutedMemberScope(),
new Function1<KotlinTypeRefiner, MemberScope>() {
@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<MemberScope>() {
@@ -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<TypeParameterDescriptor>
@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<ClassDescriptor>()
?.unsubstitutedMemberScope
?: MemberScope.Empty
}
private val typeConstructor = object : TypeConstructor {
override fun getDeclarationDescriptor(): TypeAliasDescriptor =
@@ -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)
@@ -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
}
@@ -63,10 +63,13 @@ class IntersectionTypeConstructor(typesToIntersect: Collection<KotlinType>) : 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
@@ -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
@@ -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<TypeProjection>): MemberScope {
val descriptor = constructor.declarationDescriptor
val EMPTY_REFINED_TYPE_FACTORY: RefinedTypeFactory = { _ -> null }
@UseExperimental(TypeRefinement::class)
private fun computeMemberScope(
constructor: TypeConstructor,
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
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<TypeProjection>,
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<TypeProjection>,
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
}
@TypeRefinement
override fun replaceDelegate(delegate: SimpleType) = NotNullSimpleType(delegate)
}
@@ -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<TypeProjection> 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
@@ -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))
}
@@ -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"
}
}
@TypeRefinement
override fun refine(kotlinTypeRefiner: KotlinTypeRefiner) = this
}
@@ -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);
}
@@ -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));
}
}
@@ -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<KotlinTypeRefiner, MemberScope> 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
);
}
@@ -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) {
@@ -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<UnwrappedType>? = null) :
@@ -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
}
@@ -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
}