package dyvil.tools.compiler.util;

import dyvil.tools.compiler.ast.member.IMember;
import dyvil.tools.compiler.ast.method.IMethod;
import dyvil.tools.compiler.ast.type.IType;
import dyvil.tools.compiler.ast.type.builtin.Types;
import dyvil.tools.parsing.Name;

import java.util.Comparator;

public class MemberSorter
{
	public static final Comparator<? super IMember> MEMBER_COMPARATOR = MemberSorter::compareMembers;
	public static final Comparator<? super IMethod> METHOD_COMPARATOR = MemberSorter::compareMethods;

	public static int compareNames(Name name1, Name name2)
	{
		return name1.qualified.compareToIgnoreCase(name2.qualified);
	}

	public static int compareMembers(IMember member1, IMember member2)
	{
		return compareNames(member1.getName(), member2.getName());
	}

	public static int compareMethods(IMethod method1, IMethod method2)
	{
		final int n = compareMembers(method1, method2);
		if (n != 0)
		{
			return n;
		}
		if (method1.checkOverride(method2, null))
		{
			return compareTypes(method1.getType(), method2.getType());
		}

		return method1.getSignature().compareTo(method2.getSignature());
	}

	public static int compareTypes(IType type1, IType type2)
	{
		// TODO implement a faster alternative to avoid useless type copying
		type1 = type1.asParameterType();
		type2 = type2.asParameterType();

		if (Types.isSuperType(type1, type2))
		{
			if (Types.isSuperType(type2, type1))
			{
				return 0; // same type
			}

			return 1; // type2 is more specific than type1
		}
		if (Types.isSuperType(type2, type1))
		{
			return -1; // type2 is less specific than type1
		}
		return compareNames(type1.getName(), type2.getName());
	}
}

@@ -894,16 +894,33 @@
 ethod2);
+ // compare names
 %0A%09%09if (n
@@ -953,16 +953,17 @@
 %7D%0A%09%09if (
+!
 method1.
@@ -1010,65 +1010,312 @@
 urn 
-compareTypes(method1.getType(), method2.getType());%0A
+method1.getSignature().compareTo(method2.getSignature());%0A%09%09%7D%0A%0A%09%09final IType type1 = method1.getType().asParameterType();%0A%09%09final IType type2 = method2.getType().asParameterType();%0A%0A%09%09if (Types.isSuperType(type1, type2))%0A%09%09%7B%0A%09%09%09if (Types.isSuperType(type2, type1))%0A%09%09%09%7B%0A%09%09%09%09return 0; // same type%0A%09
 %09%09%7D%0A%0A
+%09
 %09%09re
@@ -1323,60 +1323,201 @@
 urn 
-method1.getSignature().compareTo(method2.getSignatur
+1; // type2 is more specific than type1%0A%09%09%7D%0A%09%09if (Types.isSuperType(type2, type1))%0A%09%09%7B%0A%09%09%09return -1; // type2 is less specific than type1%0A%09%09%7D%0A%09%09return compareNames(type1.getName(), type2.getNam
 e())
@@ -2011,54 +2011,9 @@
 urn 
-compareNames(type1.getName(), type2.getName())
+0
 ;%0A%09%7D

Fix Overload Resolution