boolean (PsiMethod method1, PsiSubstitutor substitutor1, PsiMethod method2, PsiSubstitutor substitutor2) { //method1 has more general parameter types then method2 if (!method1.getName().equals(method2.getName())) return false; PsiParameter[] params1 = method1.getParameterList().getParameters(); PsiParameter[] params2 = method2.getParameterList().getParameters(); if (params1.length != params2.length) return false; for (int i = 0; i < params2.length; i++) { PsiType pType1 = params1[i].getType(); if (pType1 instanceof PsiEllipsisType) { pType1 = ((PsiEllipsisType)pType1).getComponentType().createArrayType(); } PsiType pType2 = params2[i].getType(); if (pType2 instanceof PsiEllipsisType) { pType2 = ((PsiEllipsisType)pType2).getComponentType().createArrayType(); } PsiType type1 = TypeConversionUtil.erasure(substitutor1.substitute(pType1)); PsiType type2 = TypeConversionUtil.erasure(substitutor2.substitute(pType2)); if (!type1.equals(type2)) return false; } if (method1 instanceof GrGdkMethod && method2 instanceof GrGdkMethod) { PsiType t1 = substitutor1.substitute(((GrGdkMethod)method1).getReceiverType()); PsiType t2 = substitutor2.substitute(((GrGdkMethod)method2).getReceiverType()); if (!t1.equals(t2)) { if (t1 instanceof PsiClassType) t1 = TypeConversionUtil.erasure(t1); if (t2 instanceof PsiClassType) t2 = TypeConversionUtil.erasure(t2); //method1 is more general than method2 return t1.isAssignableFrom(t2); } } if (GdkMethodUtil.isMacro(method1)) { // macro expansion happens during compilation, so macros always win overload resolution return false; } return true; }