[Invariant fix] Avoid re-resolving declared descriptors in lazy member scopes
It becomes necessary after scopes/types refinement Without it being applied the code might fail with slice-rewrite errors KT-32841
This commit is contained in:
committed by
Dmitry Savvinov
parent
ab9ff786d7
commit
5c2c7e7776
+46
-11
@@ -32,14 +32,14 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.util.*
|
||||
|
||||
abstract class AbstractLazyMemberScope<out D : DeclarationDescriptor, out DP : DeclarationProvider>
|
||||
protected constructor(
|
||||
protected val c: LazyClassContext,
|
||||
protected val declarationProvider: DP,
|
||||
protected val thisDescriptor: D,
|
||||
protected val trace: BindingTrace
|
||||
protected val trace: BindingTrace,
|
||||
protected val mainScope: AbstractLazyMemberScope<D, DP>? = null
|
||||
) : MemberScopeImpl() {
|
||||
|
||||
protected val storageManager: StorageManager = c.storageManager
|
||||
@@ -52,7 +52,14 @@ protected constructor(
|
||||
private val typeAliasDescriptors: MemoizedFunctionToNotNull<Name, Collection<TypeAliasDescriptor>> =
|
||||
storageManager.createMemoizedFunction { doGetTypeAliases(it) }
|
||||
|
||||
private val declaredFunctionDescriptors: MemoizedFunctionToNotNull<Name, Collection<SimpleFunctionDescriptor>> =
|
||||
storageManager.createMemoizedFunction { getDeclaredFunctions(it) }
|
||||
private val declaredPropertyDescriptors: MemoizedFunctionToNotNull<Name, Collection<PropertyDescriptor>> =
|
||||
storageManager.createMemoizedFunction { getDeclaredProperties(it) }
|
||||
|
||||
private fun doGetClasses(name: Name): List<ClassDescriptor> {
|
||||
mainScope?.classDescriptors?.invoke(name)?.let { return it }
|
||||
|
||||
val result = linkedSetOf<ClassDescriptor>()
|
||||
declarationProvider.getClassOrObjectDeclarations(name).mapTo(result) {
|
||||
val isExternal = it.modifierList?.hasModifier(KtTokens.EXTERNAL_KEYWORD) ?: false
|
||||
@@ -86,8 +93,22 @@ protected constructor(
|
||||
}
|
||||
|
||||
private fun doGetFunctions(name: Name): Collection<SimpleFunctionDescriptor> {
|
||||
val result = linkedSetOf<SimpleFunctionDescriptor>()
|
||||
val result = LinkedHashSet(declaredFunctionDescriptors.invoke(name))
|
||||
|
||||
getNonDeclaredFunctions(name, result)
|
||||
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
private fun getDeclaredFunctions(
|
||||
name: Name
|
||||
): Collection<SimpleFunctionDescriptor> {
|
||||
// TODO: do we really need to copy descriptors?
|
||||
if (mainScope != null) return mainScope.declaredFunctionDescriptors(name).map {
|
||||
it.newCopyBuilder().setPreserveSourceElement().build()!!
|
||||
}
|
||||
|
||||
val result = linkedSetOf<SimpleFunctionDescriptor>()
|
||||
val declarations = declarationProvider.getFunctionDeclarations(name)
|
||||
for (functionDeclaration in declarations) {
|
||||
result.add(
|
||||
@@ -101,9 +122,7 @@ protected constructor(
|
||||
)
|
||||
}
|
||||
|
||||
getNonDeclaredFunctions(name, result)
|
||||
|
||||
return result.toList()
|
||||
return result
|
||||
}
|
||||
|
||||
protected abstract fun getScopeForMemberDeclarationResolution(declaration: KtDeclaration): LexicalScope
|
||||
@@ -120,6 +139,21 @@ protected constructor(
|
||||
}
|
||||
|
||||
private fun doGetProperties(name: Name): Collection<PropertyDescriptor> {
|
||||
val result = LinkedHashSet(declaredPropertyDescriptors(name))
|
||||
|
||||
getNonDeclaredProperties(name, result)
|
||||
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
private fun getDeclaredProperties(
|
||||
name: Name
|
||||
): Collection<PropertyDescriptor> {
|
||||
// TODO: do we really need to copy descriptors?
|
||||
if (mainScope != null) return mainScope.declaredPropertyDescriptors(name).map {
|
||||
it.newCopyBuilder().setPreserveSourceElement().build()!!
|
||||
}
|
||||
|
||||
val result = LinkedHashSet<PropertyDescriptor>()
|
||||
|
||||
val declarations = declarationProvider.getPropertyDeclarations(name)
|
||||
@@ -149,9 +183,7 @@ protected constructor(
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
|
||||
getNonDeclaredProperties(name, result)
|
||||
|
||||
return result.toList()
|
||||
return result
|
||||
}
|
||||
|
||||
protected abstract fun getNonDeclaredProperties(name: Name, result: MutableSet<PropertyDescriptor>)
|
||||
@@ -161,8 +193,10 @@ protected constructor(
|
||||
return typeAliasDescriptors(name)
|
||||
}
|
||||
|
||||
private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> =
|
||||
declarationProvider.getTypeAliasDeclarations(name).map { ktTypeAlias ->
|
||||
private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> {
|
||||
mainScope?.typeAliasDescriptors?.invoke(name)?.let { return it }
|
||||
|
||||
return declarationProvider.getTypeAliasDeclarations(name).map { ktTypeAlias ->
|
||||
c.descriptorResolver.resolveTypeAliasDescriptor(
|
||||
thisDescriptor,
|
||||
getScopeForMemberDeclarationResolution(ktTypeAlias),
|
||||
@@ -170,6 +204,7 @@ protected constructor(
|
||||
trace
|
||||
)
|
||||
}.toList()
|
||||
}
|
||||
|
||||
protected fun computeDescriptorsFromDeclaredElements(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
|
||||
+12
-1
@@ -317,7 +317,18 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
this,
|
||||
c.getStorageManager(),
|
||||
c.getKotlinTypeChecker().getKotlinTypeRefiner(),
|
||||
kotlinTypeRefiner -> new LazyClassMemberScope(c, declarationProvider, this, c.getTrace(), kotlinTypeRefiner)
|
||||
kotlinTypeRefiner -> {
|
||||
LazyClassMemberScope scopeForDeclaredMembers =
|
||||
!kotlinTypeRefiner.isRefinementNeededForModule(c.getModuleDescriptor())
|
||||
? null
|
||||
// TODO: or kotlinTypeRefiner.getModuleDescriptor()
|
||||
: scopesHolderForClass.getScope(c.getKotlinTypeChecker().getKotlinTypeRefiner());
|
||||
|
||||
return new LazyClassMemberScope(
|
||||
c, declarationProvider, this, c.getTrace(), kotlinTypeRefiner,
|
||||
scopeForDeclaredMembers
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+14
-8
@@ -51,8 +51,11 @@ open class LazyClassMemberScope(
|
||||
declarationProvider: ClassMemberDeclarationProvider,
|
||||
thisClass: ClassDescriptorWithResolutionScopes,
|
||||
trace: BindingTrace,
|
||||
private val kotlinTypeRefiner: KotlinTypeRefiner = c.kotlinTypeChecker.kotlinTypeRefiner
|
||||
) : AbstractLazyMemberScope<ClassDescriptorWithResolutionScopes, ClassMemberDeclarationProvider>(c, declarationProvider, thisClass, trace) {
|
||||
private val kotlinTypeRefiner: KotlinTypeRefiner = c.kotlinTypeChecker.kotlinTypeRefiner,
|
||||
scopeForDeclaredMembers: LazyClassMemberScope? = null
|
||||
) : AbstractLazyMemberScope<ClassDescriptorWithResolutionScopes, ClassMemberDeclarationProvider>(
|
||||
c, declarationProvider, thisClass, trace, scopeForDeclaredMembers
|
||||
) {
|
||||
|
||||
private val descriptorsFromDeclaredElements = storageManager.createLazyValue {
|
||||
computeDescriptorsFromDeclaredElements(
|
||||
@@ -374,10 +377,12 @@ open class LazyClassMemberScope(
|
||||
|
||||
val parameter = primaryConstructorParameters.get(valueParameterDescriptor.index)
|
||||
if (parameter.hasValOrVar()) {
|
||||
val propertyDescriptor = c.descriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
||||
// TODO: can't test because we get types from cache for this case
|
||||
thisDescriptor, valueParameterDescriptor, thisDescriptor.scopeForConstructorHeaderResolution, parameter, trace
|
||||
)
|
||||
val propertyDescriptor =
|
||||
trace.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter)
|
||||
?: c.descriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
||||
// TODO: can't test because we get types from cache for this case
|
||||
thisDescriptor, valueParameterDescriptor, thisDescriptor.scopeForConstructorHeaderResolution, parameter, trace
|
||||
)
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
}
|
||||
@@ -438,12 +443,13 @@ open class LazyClassMemberScope(
|
||||
}
|
||||
|
||||
fun getConstructors(): Collection<ClassConstructorDescriptor> {
|
||||
val result = secondaryConstructors()
|
||||
val result = (mainScope as LazyClassMemberScope?)?.secondaryConstructors?.invoke() ?: secondaryConstructors()
|
||||
val primaryConstructor = getPrimaryConstructor()
|
||||
return if (primaryConstructor == null) result else result + primaryConstructor
|
||||
}
|
||||
|
||||
fun getPrimaryConstructor(): ClassConstructorDescriptor? = primaryConstructor()
|
||||
fun getPrimaryConstructor(): ClassConstructorDescriptor? =
|
||||
(mainScope as LazyClassMemberScope?)?.primaryConstructor?.invoke() ?: primaryConstructor()
|
||||
|
||||
protected open fun resolvePrimaryConstructor(): ClassConstructorDescriptor? {
|
||||
val classOrObject = declarationProvider.correspondingClassOrObject ?: return null
|
||||
|
||||
Reference in New Issue
Block a user