[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