[Core API] Introduce API for getting scopes with refinement

- All refinement-related methods are incapsulated in
ModuleAwareClassDescriptor

- most of classes implement it trivially by retning unchanged scope

- LazyClassDescriptor and DeserializedClassDescriptor have non-trivial
implementations of the refinement-related methods

- General idea is to return new scope which captures refiner and will
later use it to get correct content of itself (currently, refiner is
unused, and will be used for that in later commits)

- In order to not repeat similar work, those new instances of scopes are
cached in ScopeHolderForClass, which is essentially a cache of form
KotlinTypeRefiner -> MemberScope
This commit is contained in:
Denis Zharkov
2019-06-25 18:31:24 +03:00
committed by Dmitry Savvinov
parent d08bed888c
commit c20d565d93
16 changed files with 225 additions and 52 deletions
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
/*
* This class introduces all attributes that are needed for synthetic classes/object so far.
@@ -88,7 +89,7 @@ class SyntheticClassOrObjectDescriptor(
override fun getConstructors() = listOf(_unsubstitutedPrimaryConstructor()) + secondaryConstructors
override fun getDeclaredTypeParameters() = typeParameters
override fun getStaticScope() = MemberScope.Empty
override fun getUnsubstitutedMemberScope() = unsubstitutedMemberScope
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = unsubstitutedMemberScope
override fun getSealedSubclasses() = emptyList<ClassDescriptor>()
init {
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.storage.NotNullLazyValue;
import org.jetbrains.kotlin.storage.NullableLazyValue;
import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
import java.util.ArrayList;
import java.util.Collection;
@@ -91,7 +92,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private final NullableLazyValue<ClassDescriptorWithResolutionScopes> companionObjectDescriptor;
private final MemoizedFunctionToNotNull<KtObjectDeclaration, ClassDescriptor> extraCompanionObjectDescriptors;
private final LazyClassMemberScope unsubstitutedMemberScope;
private final ScopesHolderForClass<LazyClassMemberScope> scopesHolderForClass;
private final MemberScope staticScope;
private final NullableLazyValue<Void> forceResolveAllContents;
@@ -127,7 +128,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
StorageManager storageManager = c.getStorageManager();
this.unsubstitutedMemberScope = createMemberScope(c, this.declarationProvider);
this.scopesHolderForClass = createMemberScope(c, this.declarationProvider);
this.kind = classLikeInfo.getClassKind();
this.staticScope = kind == ClassKind.ENUM_CLASS ? new StaticScopeForKotlinEnum(storageManager, this) : MemberScope.Empty.INSTANCE;
@@ -308,17 +309,22 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
// NOTE: Called from constructor!
@NotNull
protected LazyClassMemberScope createMemberScope(
protected ScopesHolderForClass<LazyClassMemberScope> createMemberScope(
@NotNull LazyClassContext c,
@NotNull ClassMemberDeclarationProvider declarationProvider
) {
return new LazyClassMemberScope(c, declarationProvider, this, c.getTrace());
return ScopesHolderForClass.Companion.create(
this,
c.getStorageManager(),
c.getKotlinTypeChecker().getKotlinTypeRefiner(),
kotlinTypeRefiner -> new LazyClassMemberScope(c, declarationProvider, this, c.getTrace(), kotlinTypeRefiner)
);
}
@NotNull
@Override
public MemberScope getUnsubstitutedMemberScope() {
return unsubstitutedMemberScope;
public MemberScope getUnsubstitutedMemberScope(@NotNull KotlinTypeRefiner kotlinTypeRefiner) {
return scopesHolderForClass.getScope(kotlinTypeRefiner);
}
@NotNull
@@ -367,7 +373,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@SuppressWarnings("unchecked")
public Collection<CallableMemberDescriptor> getDeclaredCallableMembers() {
return (Collection) CollectionsKt.filter(
DescriptorUtils.getAllDescriptors(unsubstitutedMemberScope),
DescriptorUtils.getAllDescriptors(getUnsubstitutedMemberScope()),
descriptor -> descriptor instanceof CallableMemberDescriptor
&& ((CallableMemberDescriptor) descriptor).getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE
);
@@ -382,12 +388,12 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@NotNull
@Override
public Collection<ClassConstructorDescriptor> getConstructors() {
return unsubstitutedMemberScope.getConstructors();
return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getConstructors();
}
@Override
public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return unsubstitutedMemberScope.getPrimaryConstructor();
return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getPrimaryConstructor();
}
@NotNull
@@ -40,14 +40,18 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.refinement.TypeRefinement
import java.util.*
open class LazyClassMemberScope(
c: LazyClassContext,
declarationProvider: ClassMemberDeclarationProvider,
thisClass: ClassDescriptorWithResolutionScopes,
trace: BindingTrace
trace: BindingTrace,
private val kotlinTypeRefiner: KotlinTypeRefiner = c.kotlinTypeChecker.kotlinTypeRefiner
) : AbstractLazyMemberScope<ClassDescriptorWithResolutionScopes, ClassMemberDeclarationProvider>(c, declarationProvider, thisClass, trace) {
private val descriptorsFromDeclaredElements = storageManager.createLazyValue {