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.Unit;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.renderer.AnnotationArgumentsRenderingPolicy; import org.jetbrains.kotlin.renderer.AnnotationArgumentsRenderingPolicy;
@@ -49,52 +50,77 @@ public class MemberComparator implements Comparator<DeclarationDescriptor> {
private MemberComparator() { private MemberComparator() {
} }
private static int getDeclarationPriority(DeclarationDescriptor descriptor) { public static class NameAndTypeMemberComparator implements Comparator<DeclarationDescriptor> {
if (isEnumEntry(descriptor)) { public static final NameAndTypeMemberComparator INSTANCE = new NameAndTypeMemberComparator();
return 8;
private NameAndTypeMemberComparator() {
} }
else if (descriptor instanceof ConstructorDescriptor) {
return 7; private static int getDeclarationPriority(DeclarationDescriptor descriptor) {
} if (isEnumEntry(descriptor)) {
else if (descriptor instanceof PropertyDescriptor) { return 8;
if (((PropertyDescriptor)descriptor).getExtensionReceiverParameter() == null) {
return 6;
} }
else { else if (descriptor instanceof ConstructorDescriptor) {
return 5; return 7;
} }
} else if (descriptor instanceof PropertyDescriptor) {
else if (descriptor instanceof FunctionDescriptor) { if (((PropertyDescriptor) descriptor).getExtensionReceiverParameter() == null) {
if (((FunctionDescriptor)descriptor).getExtensionReceiverParameter() == null) { return 6;
return 4; }
else {
return 5;
}
} }
else { else if (descriptor instanceof FunctionDescriptor) {
return 3; 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 @Override
public int compare(DeclarationDescriptor o1, DeclarationDescriptor o2) { public int compare(DeclarationDescriptor o1, DeclarationDescriptor o2) {
int prioritiesCompareTo = getDeclarationPriority(o2) - getDeclarationPriority(o1); Integer typeAndNameCompareResult = NameAndTypeMemberComparator.compareInternal(o1, o2);
if (prioritiesCompareTo != 0) { if (typeAndNameCompareResult != null) {
return prioritiesCompareTo; return typeAndNameCompareResult;
}
if (isEnumEntry(o1) && isEnumEntry(o2)) {
//never reorder enum entries
return 0;
}
int namesCompareTo = o1.getName().compareTo(o2.getName());
if (namesCompareTo != 0) {
return namesCompareTo;
} }
if (o1 instanceof TypeAliasDescriptor && o2 instanceof TypeAliasDescriptor) { 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) result.addAll(subResult)
} }