Don't resort deserialized descriptors based on renderer, preserve proto order

Use only names and types for sorting. Otherwise if deserialized descriptor
is rendered different from origin we might get Psi-Stub mismatch error.

Use the original proto order for declarations with same name and kind.

 #KT-20782 Fixed
 #EA-109887 Fixed
This commit is contained in:
Nikolay Krasko
2017-10-26 16:33:10 +03:00
parent 1408c4bd44
commit 2d7fe98e55
2 changed files with 61 additions and 35 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.renderer.AnnotationArgumentsRenderingPolicy;
@@ -49,52 +50,77 @@ public class MemberComparator implements Comparator<DeclarationDescriptor> {
private MemberComparator() {
}
private static int getDeclarationPriority(DeclarationDescriptor descriptor) {
if (isEnumEntry(descriptor)) {
return 8;
public static class NameAndTypeMemberComparator implements Comparator<DeclarationDescriptor> {
public static final NameAndTypeMemberComparator INSTANCE = new NameAndTypeMemberComparator();
private NameAndTypeMemberComparator() {
}
else if (descriptor instanceof ConstructorDescriptor) {
return 7;
}
else if (descriptor instanceof PropertyDescriptor) {
if (((PropertyDescriptor)descriptor).getExtensionReceiverParameter() == null) {
return 6;
private static int getDeclarationPriority(DeclarationDescriptor descriptor) {
if (isEnumEntry(descriptor)) {
return 8;
}
else {
return 5;
else if (descriptor instanceof ConstructorDescriptor) {
return 7;
}
}
else if (descriptor instanceof FunctionDescriptor) {
if (((FunctionDescriptor)descriptor).getExtensionReceiverParameter() == null) {
return 4;
else if (descriptor instanceof PropertyDescriptor) {
if (((PropertyDescriptor) descriptor).getExtensionReceiverParameter() == null) {
return 6;
}
else {
return 5;
}
}
else {
return 3;
else if (descriptor instanceof FunctionDescriptor) {
if (((FunctionDescriptor) descriptor).getExtensionReceiverParameter() == null) {
return 4;
}
else {
return 3;
}
}
else if (descriptor instanceof ClassDescriptor) {
return 2;
}
else if (descriptor instanceof TypeAliasDescriptor) {
return 1;
}
return 0;
}
else if (descriptor instanceof ClassDescriptor) {
return 2;
@Override
public int compare(DeclarationDescriptor o1, DeclarationDescriptor o2) {
Integer compareInternal = compareInternal(o1, o2);
return compareInternal != null ? compareInternal : 0;
}
else if (descriptor instanceof TypeAliasDescriptor) {
return 1;
@Nullable
private static Integer compareInternal(DeclarationDescriptor o1, DeclarationDescriptor o2) {
int prioritiesCompareTo = getDeclarationPriority(o2) - getDeclarationPriority(o1);
if (prioritiesCompareTo != 0) {
return prioritiesCompareTo;
}
if (isEnumEntry(o1) && isEnumEntry(o2)) {
//never reorder enum entries
return 0;
}
int namesCompareTo = o1.getName().compareTo(o2.getName());
if (namesCompareTo != 0) {
return namesCompareTo;
}
// Might be equal
return null;
}
return 0;
}
@Override
public int compare(DeclarationDescriptor o1, DeclarationDescriptor o2) {
int prioritiesCompareTo = getDeclarationPriority(o2) - getDeclarationPriority(o1);
if (prioritiesCompareTo != 0) {
return prioritiesCompareTo;
}
if (isEnumEntry(o1) && isEnumEntry(o2)) {
//never reorder enum entries
return 0;
}
int namesCompareTo = o1.getName().compareTo(o2.getName());
if (namesCompareTo != 0) {
return namesCompareTo;
Integer typeAndNameCompareResult = NameAndTypeMemberComparator.compareInternal(o1, o2);
if (typeAndNameCompareResult != null) {
return typeAndNameCompareResult;
}
if (o1 instanceof TypeAliasDescriptor && o2 instanceof TypeAliasDescriptor) {
@@ -207,7 +207,7 @@ abstract class DeserializedMemberScope protected constructor(
}
}
subResult.sortWith(MemberComparator.INSTANCE)
subResult.sortWith(MemberComparator.NameAndTypeMemberComparator.INSTANCE)
result.addAll(subResult)
}