From c20d565d931d1173fa17b8784b082ec1a5c10d92 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 25 Jun 2019 18:31:24 +0300 Subject: [PATCH] [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 --- .../SyntheticClassOrObjectDescriptor.kt | 3 +- .../lazy/descriptors/LazyClassDescriptor.java | 24 +++++--- .../lazy/descriptors/LazyClassMemberScope.kt | 6 +- .../functions/FunctionClassDescriptor.kt | 3 +- .../kotlin/descriptors/NotFoundClasses.kt | 3 +- .../descriptors/ScopesHolderForClass.kt | 56 +++++++++++++++++++ .../impl/AbstractClassDescriptor.java | 39 +++++++++---- .../descriptors/impl/ClassDescriptorImpl.java | 3 +- .../EnumEntrySyntheticClassDescriptor.java | 3 +- .../impl/LazySubstitutingClassDescriptor.java | 43 ++++++++++---- .../impl/ModuleAwareClassDescriptor.kt | 45 +++++++++++++++ .../impl/MutableClassDescriptor.java | 3 +- .../jetbrains/kotlin/types/ErrorUtils.java | 6 +- .../DeserializedClassDescriptor.kt | 13 ++++- .../scripting/resolve/LazyScriptDescriptor.kt | 22 +++++--- .../ScriptProvidedPropertiesDescriptor.kt | 5 +- 16 files changed, 225 insertions(+), 52 deletions(-) create mode 100644 core/descriptors/src/org/jetbrains/kotlin/descriptors/ScopesHolderForClass.kt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleAwareClassDescriptor.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt index dd20f2e8001..2b08cde5dfa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt @@ -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() init { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 06513e7087f..56e4c6d7283 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -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 companionObjectDescriptor; private final MemoizedFunctionToNotNull extraCompanionObjectDescriptors; - private final LazyClassMemberScope unsubstitutedMemberScope; + private final ScopesHolderForClass scopesHolderForClass; private final MemberScope staticScope; private final NullableLazyValue 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 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 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 getConstructors() { - return unsubstitutedMemberScope.getConstructors(); + return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getConstructors(); } @Override public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() { - return unsubstitutedMemberScope.getPrimaryConstructor(); + return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getPrimaryConstructor(); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index 3d0fe63e311..c6d89ee41d9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -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(c, declarationProvider, thisClass, trace) { private val descriptorsFromDeclaredElements = storageManager.createLazyValue { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt index f479cfcbdb9..ee9853c09a1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_R 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 java.util.* /** @@ -82,7 +83,7 @@ class FunctionClassDescriptor( override fun getTypeConstructor(): TypeConstructor = typeConstructor - override fun getUnsubstitutedMemberScope() = memberScope + override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = memberScope override fun getCompanionObjectDescriptor() = null override fun getConstructors() = emptyList() diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt index 2148fec45a0..5a52f6ab1d1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.ClassTypeConstructorImpl import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner class NotFoundClasses(private val storageManager: StorageManager, private val module: ModuleDescriptor) { /** @@ -73,7 +74,7 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo override fun isExternal() = false override val annotations: Annotations get() = Annotations.EMPTY - override fun getUnsubstitutedMemberScope() = MemberScope.Empty + override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = MemberScope.Empty override fun getStaticScope() = MemberScope.Empty override fun getConstructors(): Collection = emptySet() override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScopesHolderForClass.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScopesHolderForClass.kt new file mode 100644 index 00000000000..c6b31d25355 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScopesHolderForClass.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors + +import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.storage.getValue +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.refinement.TypeRefinement + +class ScopesHolderForClass private constructor( + private val classDescriptor: ClassDescriptor, + storageManager: StorageManager, + private val scopeFactory: (KotlinTypeRefiner) -> T, + private val kotlinTypeRefinerForOwnerModule: KotlinTypeRefiner +) { + private val scopeForOwnerModule by storageManager.createLazyValue { + scopeFactory(kotlinTypeRefinerForOwnerModule) + } + + @UseExperimental(TypeRefinement::class) + fun getScope(kotlinTypeRefiner: KotlinTypeRefiner): T { + /* + * That check doesn't break anything, because scopeForOwnerModule _will_ anyway refine supertypes from module of + * class descriptor. + * + * Without that fastpass there is problem wit recursion types such that: + * + * interface A> + * + * interface B : B + * + * In this case (without check) we start compute default type of class descriptor B, go to isRefinementNeededForTypeConstructor, + * ask for supertypes of B, see A, ask default type of class B and fail with recursion problem + */ + if (!kotlinTypeRefiner.isRefinementNeededForModule(classDescriptor.module)) return scopeForOwnerModule + + if (!kotlinTypeRefiner.isRefinementNeededForTypeConstructor(classDescriptor.typeConstructor)) return scopeForOwnerModule + return kotlinTypeRefiner.getOrPutScopeForClass(classDescriptor) { scopeFactory(kotlinTypeRefiner) } + } + + companion object { + fun create( + classDescriptor: ClassDescriptor, + storageManager: StorageManager, + kotlinTypeRefinerForOwnerModule: KotlinTypeRefiner, + scopeFactory: (KotlinTypeRefiner) -> T + ): ScopesHolderForClass { + return ScopesHolderForClass(classDescriptor, storageManager, scopeFactory, kotlinTypeRefinerForOwnerModule) + } + } +} 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 59d62742da0..a1812029037 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java @@ -18,20 +18,21 @@ package org.jetbrains.kotlin.descriptors.impl; import kotlin.jvm.functions.Function0; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.ClassDescriptor; -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor; -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor; +import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.*; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import java.util.List; -public abstract class AbstractClassDescriptor implements ClassDescriptor { +public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor { private final Name name; protected final NotNullLazyValue defaultType; private final NotNullLazyValue unsubstitutedInnerClassesScope; @@ -85,23 +86,41 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { @NotNull @Override - public MemberScope getMemberScope(@NotNull List typeArguments) { + public MemberScope getMemberScope(@NotNull List typeArguments, @NotNull KotlinTypeRefiner kotlinTypeRefiner) { assert typeArguments.size() == getTypeConstructor().getParameters().size() : "Illegal number of type arguments: expected " + getTypeConstructor().getParameters().size() + " but was " + typeArguments.size() + " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters(); - if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope(); + if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope(kotlinTypeRefiner); TypeSubstitutor substitutor = TypeConstructorSubstitution.create(getTypeConstructor(), typeArguments).buildSubstitutor(); - return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor); + return new SubstitutingScope(getUnsubstitutedMemberScope(kotlinTypeRefiner), substitutor); + } + + @NotNull + @Override + public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution, @NotNull KotlinTypeRefiner kotlinTypeRefiner) { + if (typeSubstitution.isEmpty()) return getUnsubstitutedMemberScope(kotlinTypeRefiner); + + TypeSubstitutor substitutor = TypeSubstitutor.create(typeSubstitution); + return new SubstitutingScope(getUnsubstitutedMemberScope(kotlinTypeRefiner), substitutor); + } + + @NotNull + @Override + public MemberScope getMemberScope(@NotNull List typeArguments) { + return getMemberScope(typeArguments, DescriptorUtilsKt.getKotlinTypeRefiner(DescriptorUtils.getContainingModule(this))); } @NotNull @Override public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) { - if (typeSubstitution.isEmpty()) return getUnsubstitutedMemberScope(); + return getMemberScope(typeSubstitution, DescriptorUtilsKt.getKotlinTypeRefiner(DescriptorUtils.getContainingModule(this))); + } - TypeSubstitutor substitutor = TypeSubstitutor.create(typeSubstitution); - return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor); + @NotNull + @Override + public MemberScope getUnsubstitutedMemberScope() { + return getUnsubstitutedMemberScope(DescriptorUtilsKt.getKotlinTypeRefiner(DescriptorUtils.getContainingModule(this))); } @NotNull diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java index 18ecd13197a..a0cc195df4a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.ClassTypeConstructorImpl; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeConstructor; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import java.util.Collection; import java.util.Collections; @@ -79,7 +80,7 @@ public class ClassDescriptorImpl extends ClassDescriptorBase { @NotNull @Override - public MemberScope getUnsubstitutedMemberScope() { + public MemberScope getUnsubstitutedMemberScope(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { return unsubstitutedMemberScope; } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java index f7ee014dde5..f12108b9dac 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.ClassTypeConstructorImpl; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeConstructor; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.utils.Printer; import java.util.*; @@ -76,7 +77,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { @NotNull @Override - public MemberScope getUnsubstitutedMemberScope() { + public MemberScope getUnsubstitutedMemberScope(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { return scope; } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java index aa45dbbaa04..2e61b652896 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java @@ -12,24 +12,27 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope; import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.types.*; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class LazySubstitutingClassDescriptor implements ClassDescriptor { - private final ClassDescriptor original; +public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor { + private final ModuleAwareClassDescriptor original; private final TypeSubstitutor originalSubstitutor; private TypeSubstitutor newSubstitutor; private List typeConstructorParameters; private List declaredTypeParameters; private TypeConstructor typeConstructor; - public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor) { + public LazySubstitutingClassDescriptor(ModuleAwareClassDescriptor descriptor, TypeSubstitutor substitutor) { this.original = descriptor; this.originalSubstitutor = substitutor; } @@ -82,28 +85,46 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { @NotNull @Override - public MemberScope getMemberScope(@NotNull List typeArguments) { - MemberScope memberScope = original.getMemberScope(typeArguments); + public MemberScope getMemberScope(@NotNull List typeArguments, @NotNull KotlinTypeRefiner kotlinTypeRefiner) { + MemberScope memberScope = original.getMemberScope(typeArguments, kotlinTypeRefiner); if (originalSubstitutor.isEmpty()) { return memberScope; } return new SubstitutingScope(memberScope, getSubstitutor()); } + @NotNull + @Override + public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution, @NotNull KotlinTypeRefiner kotlinTypeRefiner) { + MemberScope memberScope = original.getMemberScope(typeSubstitution, kotlinTypeRefiner); + if (originalSubstitutor.isEmpty()) { + return memberScope; + } + return new SubstitutingScope(memberScope, getSubstitutor()); + } + + @NotNull + @Override + public MemberScope getMemberScope(@NotNull List typeArguments) { + return getMemberScope(typeArguments, DescriptorUtilsKt.getKotlinTypeRefiner(DescriptorUtils.getContainingModule(this))); + } + @NotNull @Override public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) { - MemberScope memberScope = original.getMemberScope(typeSubstitution); - if (originalSubstitutor.isEmpty()) { - return memberScope; - } - return new SubstitutingScope(memberScope, getSubstitutor()); + return getMemberScope(typeSubstitution, DescriptorUtilsKt.getKotlinTypeRefiner(DescriptorUtils.getContainingModule(this))); } @NotNull @Override public MemberScope getUnsubstitutedMemberScope() { - MemberScope memberScope = original.getUnsubstitutedMemberScope(); + return getUnsubstitutedMemberScope(DescriptorUtilsKt.getKotlinTypeRefiner(DescriptorUtils.getContainingModule(original))); + } + + @NotNull + @Override + public MemberScope getUnsubstitutedMemberScope(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { + MemberScope memberScope = original.getUnsubstitutedMemberScope(kotlinTypeRefiner); if (originalSubstitutor.isEmpty()) { return memberScope; } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleAwareClassDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleAwareClassDescriptor.kt new file mode 100644 index 00000000000..7df140ca4a4 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleAwareClassDescriptor.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.descriptors.impl + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.impl.ModuleAwareClassDescriptor.Companion.getRefinedMemberScopeIfPossible +import org.jetbrains.kotlin.descriptors.impl.ModuleAwareClassDescriptor.Companion.getRefinedUnsubstitutedMemberScopeIfPossible +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.TypeProjection +import org.jetbrains.kotlin.types.TypeSubstitution +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner + +abstract class ModuleAwareClassDescriptor : ClassDescriptor { + protected abstract fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope + protected abstract fun getMemberScope(typeSubstitution: TypeSubstitution, kotlinTypeRefiner: KotlinTypeRefiner): MemberScope + protected abstract fun getMemberScope(typeArguments: List, kotlinTypeRefiner: KotlinTypeRefiner): MemberScope + + companion object { + internal fun ClassDescriptor.getRefinedUnsubstitutedMemberScopeIfPossible( + kotlinTypeRefiner: KotlinTypeRefiner + ): MemberScope = + (this as? ModuleAwareClassDescriptor)?.getUnsubstitutedMemberScope(kotlinTypeRefiner) ?: this.unsubstitutedMemberScope + + internal fun ClassDescriptor.getRefinedMemberScopeIfPossible( + typeSubstitution: TypeSubstitution, + kotlinTypeRefiner: KotlinTypeRefiner + ): MemberScope = + (this as? ModuleAwareClassDescriptor)?.getMemberScope(typeSubstitution, kotlinTypeRefiner) ?: this.getMemberScope( + typeSubstitution + ) + } +} + +fun ClassDescriptor.getRefinedUnsubstitutedMemberScopeIfPossible( + kotlinTypeRefiner: KotlinTypeRefiner +): MemberScope = getRefinedUnsubstitutedMemberScopeIfPossible(kotlinTypeRefiner) + +fun ClassDescriptor.getRefinedMemberScopeIfPossible( + typeSubstitution: TypeSubstitution, + kotlinTypeRefiner: KotlinTypeRefiner +): MemberScope = getRefinedMemberScopeIfPossible(typeSubstitution, kotlinTypeRefiner) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java index 532c2f216c4..5884475ee1b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.name.Name; 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 java.util.*; @@ -162,7 +163,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase { @Override @NotNull - public MemberScope getUnsubstitutedMemberScope() { + public MemberScope getUnsubstitutedMemberScope(@NotNull KotlinTypeRefiner kotlinTypeRefiner) { return MemberScope.Empty.INSTANCE; // used for getDefaultType } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index c2c2183a869..ec66fbc6f06 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -35,7 +35,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.storage.LockBasedStorageManager; +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.types.error.ErrorSimpleFunctionDescriptorImpl; +import org.jetbrains.kotlin.types.refinement.TypeRefinement; import org.jetbrains.kotlin.utils.Printer; import java.util.Collection; @@ -372,13 +374,13 @@ public class ErrorUtils { @NotNull @Override - public MemberScope getMemberScope(@NotNull List typeArguments) { + public MemberScope getMemberScope(@NotNull List typeArguments, @NotNull KotlinTypeRefiner kotlinTypeRefiner) { return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeArguments); } @NotNull @Override - public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) { + public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution, @NotNull KotlinTypeRefiner kotlinTypeRefiner) { return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeSubstitution); } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 772946a73ac..be3d7e34718 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -27,6 +27,8 @@ import org.jetbrains.kotlin.serialization.deserialization.* 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 +import org.jetbrains.kotlin.types.refinement.TypeRefinement import java.util.* class DeserializedClassDescriptor( @@ -52,7 +54,11 @@ class DeserializedClassDescriptor( private val staticScope = if (kind == ClassKind.ENUM_CLASS) StaticScopeForKotlinEnum(c.storageManager, this) else MemberScope.Empty private val typeConstructor = DeserializedClassTypeConstructor() - private val memberScope = DeserializedClassMemberScope() + + private val memberScopeHolder = + ScopesHolderForClass.create(this, c.storageManager, c.components.kotlinTypeChecker.kotlinTypeRefiner, this::DeserializedClassMemberScope) + + private val memberScope get() = memberScopeHolder.getScope(c.components.kotlinTypeChecker.kotlinTypeRefiner) private val enumEntries = if (kind == ClassKind.ENUM_CLASS) EnumEntryClassDescriptors() else null private val containingDeclaration = outerContext.containingDeclaration @@ -98,7 +104,8 @@ class DeserializedClassDescriptor( override fun isExternal() = Flags.IS_EXTERNAL_CLASS.get(classProto.flags) - override fun getUnsubstitutedMemberScope(): MemberScope = memberScope + override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = + memberScopeHolder.getScope(kotlinTypeRefiner) override fun getStaticScope() = staticScope @@ -200,7 +207,7 @@ class DeserializedClassDescriptor( get() = SupertypeLoopChecker.EMPTY } - private inner class DeserializedClassMemberScope : DeserializedMemberScope( + private inner class DeserializedClassMemberScope(private val kotlinTypeRefiner: KotlinTypeRefiner) : DeserializedMemberScope( c, classProto.functionList, classProto.propertyList, classProto.typeAliasList, classProto.nestedClassNameList.map(c.nameResolver::getName).let { { it } } // workaround KT-13454 ) { diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt index 303cb5f7dc0..7694ba43318 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassMemberScope import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind @@ -144,14 +145,19 @@ class LazyScriptDescriptor( override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R = visitor.visitScriptDescriptor(this, data) - override fun createMemberScope(c: LazyClassContext, declarationProvider: ClassMemberDeclarationProvider): LazyScriptClassMemberScope = - LazyScriptClassMemberScope( - // Must be a ResolveSession for scripts - c as ResolveSession, - declarationProvider, - this, - c.trace - ) + override fun createMemberScope( + c: LazyClassContext, + declarationProvider: ClassMemberDeclarationProvider + ): ScopesHolderForClass = + ScopesHolderForClass.create(this, c.storageManager, c.kotlinTypeChecker.kotlinTypeRefiner) { + LazyScriptClassMemberScope( + // Must be a ResolveSession for scripts + c as ResolveSession, + declarationProvider, + this, + c.trace + ) + } override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!! diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/ScriptProvidedPropertiesDescriptor.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/ScriptProvidedPropertiesDescriptor.kt index a3fbe8f7ecd..d5af8149958 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/ScriptProvidedPropertiesDescriptor.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/ScriptProvidedPropertiesDescriptor.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.utils.Printer import kotlin.script.experimental.api.ScriptCompilationConfiguration import kotlin.script.experimental.api.providedProperties @@ -42,7 +43,7 @@ class ScriptProvidedPropertiesDescriptor(script: LazyScriptDescriptor) : ) } - override fun getUnsubstitutedMemberScope(): MemberScope = memberScope() + override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = memberScope() val properties: () -> List = script.resolveSession.storageManager.createLazyValue { script.scriptCompilationConfiguration()[ScriptCompilationConfiguration.providedProperties].orEmpty().mapNotNull { (name, type) -> @@ -76,4 +77,4 @@ class ScriptProvidedPropertiesDescriptor(script: LazyScriptDescriptor) : p.println("Scope of script provided properties: $scriptId") } } -} \ No newline at end of file +}