[API Usage] Support refinement for Java classes' scope

Also, we should skip supertypes refinement for additional
    built-in members scope
This commit is contained in:
Dmitry Savvinov
2019-07-10 15:42:12 +03:00
parent b7e011a29b
commit 04717b57c9
4 changed files with 70 additions and 23 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.frontend.java.di
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsPackageFragmentProvider
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
@@ -100,10 +101,21 @@ class LazyJavaClassDescriptor(
private val typeConstructor = LazyJavaClassTypeConstructor()
override fun getTypeConstructor(): TypeConstructor = typeConstructor
private val unsubstitutedMemberScope = LazyJavaClassMemberScope(c, this, jClass)
override fun getUnsubstitutedMemberScope() = unsubstitutedMemberScope
private val unsubstitutedMemberScope =
LazyJavaClassMemberScope(c, this, jClass, skipRefinement = additionalSupertypeClassDescriptor != null)
private val innerClassesScope = InnerClassesScopeWrapper(getUnsubstitutedMemberScope())
private val scopeHolder =
ScopesHolderForClass.create(this, c.storageManager, c.components.kotlinTypeChecker.kotlinTypeRefiner) { kotlinTypeRefiner ->
LazyJavaClassMemberScope(
c, this, jClass,
skipRefinement = additionalSupertypeClassDescriptor != null,
mainScope = unsubstitutedMemberScope
)
}
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = scopeHolder.getScope(kotlinTypeRefiner)
private val innerClassesScope = InnerClassesScopeWrapper(unsubstitutedMemberScope)
override fun getUnsubstitutedInnerClassesScope(): MemberScope = innerClassesScope
private val staticScope = LazyJavaStaticClassScope(c, jClass, this)
@@ -113,6 +125,7 @@ class LazyJavaClassDescriptor(
override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
override fun getUnsubstitutedMemberScope() = super.getUnsubstitutedMemberScope() as LazyJavaClassMemberScope
override fun getConstructors() = unsubstitutedMemberScope.constructors()
override val annotations = c.resolveAnnotations(jClass)
@@ -67,8 +67,10 @@ import java.util.*
class LazyJavaClassMemberScope(
c: LazyJavaResolverContext,
override val ownerDescriptor: ClassDescriptor,
private val jClass: JavaClass
) : LazyJavaScope(c) {
private val jClass: JavaClass,
private val skipRefinement: Boolean,
mainScope: LazyJavaClassMemberScope? = null
) : LazyJavaScope(c, mainScope) {
override fun computeMemberIndex() = ClassDeclaredMemberIndex(jClass) { !it.isStatic }
@@ -431,9 +433,10 @@ class LazyJavaClassMemberScope(
}
private fun getFunctionsFromSupertypes(name: Name): Set<SimpleFunctionDescriptor> {
return ownerDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) {
it.memberScope.getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS)
}
return computeSupertypes()
.flatMapTo(LinkedHashSet()) {
it.memberScope.getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS)
}
}
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
@@ -548,11 +551,18 @@ class LazyJavaClassMemberScope(
}
private fun getPropertiesFromSupertypes(name: Name): Set<PropertyDescriptor> {
return ownerDescriptor.typeConstructor.supertypes.flatMap {
return computeSupertypes().flatMap {
it.memberScope.getContributedVariables(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS).map { p -> p }
}.toSet()
}
private fun computeSupertypes(): Collection<KotlinType> {
if (skipRefinement) return ownerDescriptor.typeConstructor.supertypes
@UseExperimental(TypeRefinement::class)
return c.components.kotlinTypeChecker.kotlinTypeRefiner.refineSupertypes(ownerDescriptor)
}
override fun resolveMethodSignature(
method: JavaMethod, methodTypeParameters: List<TypeParameterDescriptor>, returnType: KotlinType,
valueParameters: List<ValueParameterDescriptor>
@@ -728,7 +738,8 @@ class LazyJavaClassMemberScope(
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
recordLookup(name, location)
return nestedClasses(name)
return (mainScope as LazyJavaClassMemberScope?)?.nestedClasses?.invoke(name) ?: nestedClasses(name)
}
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
@@ -45,6 +45,8 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions
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.MemoizedFunctionToNotNull
import org.jetbrains.kotlin.storage.MemoizedFunctionToNullable
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.KotlinType
@@ -54,7 +56,10 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberScopeImpl() {
abstract class LazyJavaScope(
protected val c: LazyJavaResolverContext,
protected val mainScope: LazyJavaScope? = null
) : MemberScopeImpl() {
protected abstract val ownerDescriptor: DeclarationDescriptor
// this lazy value is not used at all in LazyPackageFragmentScopeForJavaPackage because we do not use caching there
@@ -79,17 +84,38 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
protected abstract fun getDispatchReceiverParameter(): ReceiverParameterDescriptor?
private val functions = c.storageManager.createMemoizedFunction<Name, Collection<SimpleFunctionDescriptor>> { name ->
val result = LinkedHashSet<SimpleFunctionDescriptor>()
private val declaredFunctions: MemoizedFunctionToNotNull<Name, Collection<SimpleFunctionDescriptor>> =
c.storageManager.createMemoizedFunction { name ->
if (mainScope != null) return@createMemoizedFunction mainScope.declaredFunctions(name)
for (method in declaredMemberIndex().findMethodsByName(name)) {
val descriptor = resolveMethodToFunctionDescriptor(method)
if (!descriptor.isVisibleAsFunction()) continue
val result = mutableListOf<SimpleFunctionDescriptor>()
c.components.javaResolverCache.recordMethod(method, descriptor)
result.add(descriptor)
for (method in declaredMemberIndex().findMethodsByName(name)) {
val descriptor = resolveMethodToFunctionDescriptor(method)
if (!descriptor.isVisibleAsFunction()) continue
c.components.javaResolverCache.recordMethod(method, descriptor)
result.add(descriptor)
}
result
}
private val declaredField: MemoizedFunctionToNullable<Name, PropertyDescriptor> =
c.storageManager.createMemoizedFunctionWithNullableValues { name ->
if (mainScope != null) return@createMemoizedFunctionWithNullableValues mainScope.declaredField(name)
val field = declaredMemberIndex().findFieldByName(name)
if (field != null && !field.isEnumEntry)
resolveProperty(field)
else
null
}
private val functions = c.storageManager.createMemoizedFunction<Name, Collection<SimpleFunctionDescriptor>> { name ->
val result = LinkedHashSet<SimpleFunctionDescriptor>(declaredFunctions(name))
result.retainMostSpecificInEachOverridableGroup()
computeNonDeclaredFunctions(result, name)
@@ -250,11 +276,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
private val properties = c.storageManager.createMemoizedFunction { name: Name ->
val properties = ArrayList<PropertyDescriptor>()
val field = declaredMemberIndex().findFieldByName(name)
if (field != null && !field.isEnumEntry) {
properties.add(resolveProperty(field))
}
properties.addIfNotNull(declaredField(name))
computeNonDeclaredProperties(name, properties)
if (DescriptorUtils.isAnnotationClass(ownerDescriptor))