[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
+3
-2
@@ -377,9 +377,10 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
newVisibility: Visibility,
|
||||
original: PropertyDescriptor?,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
newName: Name
|
||||
newName: Name,
|
||||
source: SourceElement
|
||||
): PropertyDescriptorImpl {
|
||||
return MyPropertyDescriptor(newOwner, this, annotations, newModality, newVisibility, isVar, newName, kind, source).apply {
|
||||
return MyPropertyDescriptor(newOwner, this, annotations, newModality, newVisibility, isVar, newName, kind, this.source).apply {
|
||||
getMethod = this@MyPropertyDescriptor.getMethod
|
||||
setMethod = this@MyPropertyDescriptor.setMethod
|
||||
}
|
||||
|
||||
+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
|
||||
|
||||
+3
-2
@@ -81,10 +81,11 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
|
||||
@NotNull Visibility newVisibility,
|
||||
@Nullable PropertyDescriptor original,
|
||||
@NotNull Kind kind,
|
||||
@NotNull Name newName
|
||||
@NotNull Name newName,
|
||||
@NotNull SourceElement source
|
||||
) {
|
||||
return new JavaPropertyDescriptor(
|
||||
newOwner, getAnnotations(), newModality, newVisibility, isVar(), newName, SourceElement.NO_SOURCE, original,
|
||||
newOwner, getAnnotations(), newModality, newVisibility, isVar(), newName, source, original,
|
||||
kind, isStaticFinal,
|
||||
singleUserData);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,9 @@ public interface CallableMemberDescriptor extends CallableDescriptor, MemberDesc
|
||||
@NotNull
|
||||
CopyBuilder<D> setOriginal(@Nullable CallableMemberDescriptor original);
|
||||
|
||||
@NotNull
|
||||
CopyBuilder<D> setPreserveSourceElement();
|
||||
|
||||
@Nullable
|
||||
D build();
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
||||
CopyBuilder<D> setSignatureChange();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CopyBuilder<D> setPreserveSourceElement();
|
||||
|
||||
@NotNull
|
||||
|
||||
+20
-3
@@ -252,6 +252,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
private Modality modality = getModality();
|
||||
private Visibility visibility = getVisibility();
|
||||
private PropertyDescriptor original = null;
|
||||
private boolean preserveSourceElement = false;
|
||||
private Kind kind = getKind();
|
||||
private TypeSubstitution substitution = TypeSubstitution.EMPTY;
|
||||
private boolean copyOverrides = true;
|
||||
@@ -273,6 +274,13 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setPreserveSourceElement() {
|
||||
preserveSourceElement = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CopyConfiguration setModality(@NotNull Modality modality) {
|
||||
@@ -352,11 +360,19 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
return new CopyConfiguration();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SourceElement getSourceToUseForCopy(boolean preserveSource, @Nullable PropertyDescriptor original) {
|
||||
return preserveSource
|
||||
? (original != null ? original : getOriginal()).getSource()
|
||||
: SourceElement.NO_SOURCE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PropertyDescriptor doSubstitute(@NotNull CopyConfiguration copyConfiguration) {
|
||||
PropertyDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
|
||||
copyConfiguration.owner, copyConfiguration.modality, copyConfiguration.visibility,
|
||||
copyConfiguration.original, copyConfiguration.kind, copyConfiguration.name);
|
||||
copyConfiguration.original, copyConfiguration.kind, copyConfiguration.name,
|
||||
getSourceToUseForCopy(copyConfiguration.preserveSourceElement, copyConfiguration.original));
|
||||
|
||||
List<TypeParameterDescriptor> originalTypeParameters =
|
||||
copyConfiguration.newTypeParameters == null ? getTypeParameters() : copyConfiguration.newTypeParameters;
|
||||
@@ -486,10 +502,11 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
@NotNull Visibility newVisibility,
|
||||
@Nullable PropertyDescriptor original,
|
||||
@NotNull Kind kind,
|
||||
@NotNull Name newName
|
||||
@NotNull Name newName,
|
||||
@NotNull SourceElement source
|
||||
) {
|
||||
return new PropertyDescriptorImpl(
|
||||
newOwner, original, getAnnotations(), newModality, newVisibility, isVar(), newName, kind, SourceElement.NO_SOURCE,
|
||||
newOwner, original, getAnnotations(), newModality, newVisibility, isVar(), newName, kind, source,
|
||||
isLateInit(), isConst(), isExpect(), isActual(), isExternal(), isDelegated()
|
||||
);
|
||||
}
|
||||
|
||||
+2
-1
@@ -164,7 +164,8 @@ class DeserializedPropertyDescriptor(
|
||||
newVisibility: Visibility,
|
||||
original: PropertyDescriptor?,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
newName: Name
|
||||
newName: Name,
|
||||
source: SourceElement
|
||||
): PropertyDescriptorImpl {
|
||||
return DeserializedPropertyDescriptor(
|
||||
newOwner, original, annotations, newModality, newVisibility, isVar, newName, kind, isLateInit, isConst, isExternal,
|
||||
|
||||
Reference in New Issue
Block a user