- public static bool IsEqual (Type a, Type b)
- {
- if (a.Equals (b))
- return true;
-
- if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.IsGenericInstance) {
- //
- // `a' is a generic type definition's TypeBuilder and `b' is a
- // generic instance of the same type.
- //
- // Example:
- //
- // class Stack<T>
- // {
- // void Test (Stack<T> stack) { }
- // }
- //
- // The first argument of `Test' will be the generic instance
- // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
- //
- //
- // We hit this via Closure.Filter() for gen-82.cs.
- //
- if (a != b.GetGenericTypeDefinition ())
- return false;
-
- Type[] aparams = a.GetGenericArguments ();
- Type[] bparams = b.GetGenericArguments ();
-
- if (aparams.Length != bparams.Length)
- return false;
-
- for (int i = 0; i < aparams.Length; i++)
- if (!IsEqual (aparams [i], bparams [i]))
- return false;
-
- return true;
- }
-
- if (a.IsGenericParameter && b.IsGenericParameter) {
- if ((a.DeclaringMethod == null) || (b.DeclaringMethod == null))
- return false;
- return a.GenericParameterPosition == b.GenericParameterPosition;
- }
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
- return IsEqual (a.GetElementType (), b.GetElementType ());
- }
-
- if (a.IsGenericInstance && b.IsGenericInstance) {
- Type at = a.GetGenericTypeDefinition ();
- Type bt = b.GetGenericTypeDefinition ();
-
- if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
- return false;
-
- Type[] aargs = a.GetGenericArguments ();
- Type[] bargs = b.GetGenericArguments ();
-
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (!IsEqual (aargs [i], bargs [i]))
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- public static bool MayBecomeEqualGenericTypes (Type a, Type b)
- {
- if (a.IsGenericParameter) {
- //
- // If a is an array of a's type, they may never
- // become equal.
- //
- while (b.IsArray) {
- b = b.GetElementType ();
- if (a.Equals (b))
- return false;
- }
-
- //
- // If b is a generic parameter or an actual type,
- // they may become equal:
- //
- // class X<T,U> : I<T>, I<U>
- // class X<T> : I<T>, I<float>
- //
- if (b.IsGenericParameter || !b.IsGenericInstance)
- return true;
-
- //
- // We're now comparing a type parameter with a
- // generic instance. They may become equal unless
- // the type parameter appears anywhere in the
- // generic instance:
- //
- // class X<T,U> : I<T>, I<X<U>>
- // -> error because you could instanciate it as
- // X<X<int>,int>
- //
- // class X<T> : I<T>, I<X<T>> -> ok
- //
-
- Type[] bargs = GetTypeArguments (b);
- for (int i = 0; i < bargs.Length; i++) {
- if (a.Equals (bargs [i]))
- return false;
- }
-
- return true;
- }
-
- if (b.IsGenericParameter)
- return MayBecomeEqualGenericTypes (b, a);
-
- //
- // At this point, neither a nor b are a type parameter.
- //
- // If one of them is a generic instance, let
- // MayBecomeEqualGenericInstances() compare them (if the
- // other one is not a generic instance, they can never
- // become equal).
- //
-
- if (a.IsGenericInstance || b.IsGenericInstance)
- return MayBecomeEqualGenericInstances (a, b);
-
- //
- // If both of them are arrays.
- //
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
-
- a = a.GetElementType ();
- b = b.GetElementType ();
-
- return MayBecomeEqualGenericTypes (a, b);
- }
-
- //
- // Ok, two ordinary types.
- //
-
- return a.Equals (b);
- }
-
- //
- // Checks whether two generic instances may become equal for some
- // particular instantiation (26.3.1).
- //
- public static bool MayBecomeEqualGenericInstances (Type a, Type b)
- {
- if (!a.IsGenericInstance || !b.IsGenericInstance)
- return false;
- if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
- return false;
-
- Type[] aargs = GetTypeArguments (a);
- Type[] bargs = GetTypeArguments (b);
-
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (MayBecomeEqualGenericTypes (aargs [i], bargs [i]))
- return true;
- }
-
- return false;
- }
-
- public static bool IsEqualGenericInstance (Type type, Type parent)
- {
- int tcount = GetNumberOfTypeArguments (type);
- int pcount = GetNumberOfTypeArguments (parent);
-
- if (type.IsGenericInstance)
- type = type.GetGenericTypeDefinition ();
- if (parent.IsGenericInstance)
- parent = parent.GetGenericTypeDefinition ();
-
- if (tcount != pcount)
- return false;
-
- return type.Equals (parent);
- }
-
- public static bool IsSubclassOf (Type type, Type parent)