[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:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user