KT-41859 Place classes after typealiases in DeserializedMemberScope

This way, the order in stubs and in deserialized text would be the same

On the next stub version bump, this fix should be reworked: the order
in the `DeserializedMemberScope` should be restored, and the order in
the stubs should be fixed to match the order in `MemberComparator`

^KT-41859 Fixed
This commit is contained in:
Roman Golyshev
2020-09-15 15:16:07 +03:00
parent cfd62c15bf
commit 945edfe987
5 changed files with 39 additions and 10 deletions
@@ -28,6 +28,7 @@ object KotlinStubVersions {
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
// TODO: Before updating this, please see the kdoc at DeserializedMemberScope.computeDescriptors and KT-41859
private const val BINARY_STUB_VERSION = 71
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
@@ -99,13 +99,24 @@ abstract class DeserializedMemberScope protected constructor(
return impl.getContributedVariables(name, location)
}
/**
* N.B. Currently the order of declarations here and in the [MemberComparator] is intentionally different:
* [MemberComparator] places classes first and typealiases second.
*
* However, `ClassClsStubBuilder` places typealiases first and classes second. This leads to
* Stub vs Psi mismatch error, when we have a class which have both inner typealiases and inner classes.
* This is unintentional and should be fixed.
*
* We do not want to update stubs versions prematurely, so we temporary mitigate the issue by making sure that
* order in stubs (in `ClassClsStubBuilder`) and here (in [DeserializedMemberScope]) is the same. As soon as the
* opportunity to bump the stubs version arises, we should fix the bug in the `ClassClsStubBuilder`, and
* fix the order here accordingly.
*/
protected fun computeDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
location: LookupLocation
): Collection<DeclarationDescriptor> {
//NOTE: descriptors should be in the same order they were serialized in
// see MemberComparator
val result = ArrayList<DeclarationDescriptor>(0)
if (kindFilter.acceptsKinds(DescriptorKindFilter.SINGLETON_CLASSIFIERS_MASK)) {
@@ -114,14 +125,6 @@ abstract class DeserializedMemberScope protected constructor(
impl.addFunctionsAndPropertiesTo(result, kindFilter, nameFilter, location)
if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) {
for (className in classNames) {
if (nameFilter(className)) {
result.addIfNotNull(deserializeClass(className))
}
}
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.TYPE_ALIASES_MASK)) {
for (typeAliasName in impl.typeAliasNames) {
if (nameFilter(typeAliasName)) {
@@ -130,6 +133,14 @@ abstract class DeserializedMemberScope protected constructor(
}
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) {
for (className in classNames) {
if (nameFilter(className)) {
result.addIfNotNull(deserializeClass(className))
}
}
}
return result.compact()
}
@@ -219,6 +219,7 @@ private class ClassClsStubBuilder(
}
}
// FIXME using this function breaks the order of `MemberComparator` (see KT-41859)
createDeclarationsStubs(
classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList, classProto.typeAliasList
)
@@ -15,6 +15,8 @@ annotation class Ann
class TypeAliases {
class OrderB
@Suppress("TOPLEVEL_TYPEALIASES_ONLY")
typealias B = (A) -> Unit
@@ -28,6 +30,8 @@ class TypeAliases {
fun order(path: String) {}
fun order(body: Z) {}
class OrderA
}
@@ -139,3 +139,15 @@ PsiJetFileStubImpl[package=test]
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=F]
CLASS[fqName=test.TypeAliases.OrderA, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=OrderA, superNames=[]]
MODIFIER_LIST[public final]
PRIMARY_CONSTRUCTOR
MODIFIER_LIST[public]
VALUE_PARAMETER_LIST
CLASS_BODY
CLASS[fqName=test.TypeAliases.OrderB, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=OrderB, superNames=[]]
MODIFIER_LIST[public final]
PRIMARY_CONSTRUCTOR
MODIFIER_LIST[public]
VALUE_PARAMETER_LIST
CLASS_BODY