001/* 002 * Copyright 2010-2013 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.jetbrains.jet.lang.resolve; 018 019import org.jetbrains.jet.lang.descriptors.*; 020import org.jetbrains.jet.renderer.DescriptorRenderer; 021 022import java.util.Comparator; 023import java.util.List; 024 025public class MemberComparator implements Comparator<DeclarationDescriptor> { 026 public static final MemberComparator INSTANCE = new MemberComparator(); 027 028 private MemberComparator() { 029 } 030 031 private static int getDeclarationPriority(DeclarationDescriptor descriptor) { 032 if (descriptor instanceof ConstructorDescriptor) { 033 return 6; 034 } 035 else if (descriptor instanceof PropertyDescriptor) { 036 if (((PropertyDescriptor)descriptor).getReceiverParameter() == null) { 037 return 5; 038 } 039 else { 040 return 4; 041 } 042 } 043 else if (descriptor instanceof FunctionDescriptor) { 044 if (((FunctionDescriptor)descriptor).getReceiverParameter() == null) { 045 return 3; 046 } 047 else { 048 return 2; 049 } 050 } 051 else if (descriptor instanceof ClassDescriptor) { 052 return 1; 053 } 054 return 0; 055 } 056 057 @Override 058 public int compare(DeclarationDescriptor o1, DeclarationDescriptor o2) { 059 int prioritiesCompareTo = getDeclarationPriority(o2) - getDeclarationPriority(o1); 060 if (prioritiesCompareTo != 0) { 061 return prioritiesCompareTo; 062 } 063 064 int namesCompareTo = o1.getName().compareTo(o2.getName()); 065 if (namesCompareTo != 0) { 066 return namesCompareTo; 067 } 068 069 if (!(o1 instanceof CallableDescriptor) || !(o2 instanceof CallableDescriptor)) { 070 assert false; 071 } 072 073 CallableDescriptor c1 = (CallableDescriptor)o1; 074 CallableDescriptor c2 = (CallableDescriptor)o2; 075 076 ReceiverParameterDescriptor c1ReceiverParameter = c1.getReceiverParameter(); 077 ReceiverParameterDescriptor c2ReceiverParameter = c2.getReceiverParameter(); 078 assert (c1ReceiverParameter != null) == (c2ReceiverParameter != null); 079 if (c1ReceiverParameter != null) { 080 String r1 = DescriptorRenderer.TEXT.renderType(c1ReceiverParameter.getType()); 081 String r2 = DescriptorRenderer.TEXT.renderType(c2ReceiverParameter.getType()); 082 int receiversCompareTo = r1.compareTo(r2); 083 if (receiversCompareTo != 0) { 084 return receiversCompareTo; 085 } 086 } 087 088 List<ValueParameterDescriptor> c1ValueParameters = c1.getValueParameters(); 089 List<ValueParameterDescriptor> c2ValueParameters = c2.getValueParameters(); 090 for (int i = 0; i < Math.min(c1ValueParameters.size(), c2ValueParameters.size()); i++) { 091 String p1 = DescriptorRenderer.TEXT.renderType(c1ValueParameters.get(i).getType()); 092 String p2 = DescriptorRenderer.TEXT.renderType(c2ValueParameters.get(i).getType()); 093 int parametersCompareTo = p1.compareTo(p2); 094 if (parametersCompareTo != 0) { 095 return parametersCompareTo; 096 } 097 } 098 099 int valueParametersNumberCompareTo = c1ValueParameters.size() - c2ValueParameters.size(); 100 if (valueParametersNumberCompareTo != 0) { 101 return valueParametersNumberCompareTo; 102 } 103 104 List<TypeParameterDescriptor> c1TypeParameters = c1.getTypeParameters(); 105 List<TypeParameterDescriptor> c2TypeParameters = c2.getTypeParameters(); 106 for (int i = 0; i < Math.min(c1TypeParameters.size(), c2TypeParameters.size()); i++) { 107 String p1 = DescriptorRenderer.TEXT.renderType(c1TypeParameters.get(i).getUpperBoundsAsType()); 108 String p2 = DescriptorRenderer.TEXT.renderType(c2TypeParameters.get(i).getUpperBoundsAsType()); 109 int parametersCompareTo = p1.compareTo(p2); 110 if (parametersCompareTo != 0) { 111 return parametersCompareTo; 112 } 113 } 114 115 int typeParametersCompareTo = c1TypeParameters.size() - c2TypeParameters.size(); 116 if (typeParametersCompareTo != 0) { 117 return typeParametersCompareTo; 118 } 119 120 if (c1 instanceof CallableMemberDescriptor && c2 instanceof CallableMemberDescriptor) { 121 CallableMemberDescriptor.Kind c1Kind = ((CallableMemberDescriptor) c1).getKind(); 122 CallableMemberDescriptor.Kind c2Kind = ((CallableMemberDescriptor) c2).getKind(); 123 return c1Kind.ordinal() - c2Kind.ordinal(); 124 } 125 126 return 0; 127 } 128}