Explorar el Código

2009-12-17 Rodrigo Kumpera <[email protected]>

	* MonoGenericClass.cs (GetMethods): When the GTD is not a typebuilder,
	calling GetMethods on it will return everything we need so no need to
	do the crazy loop.
	The returned methods might contains some that are not from a generic type
	so we need to guard against this as well.

	* MonoGenericClass.cs (GetMethodsInternal): Guard against methods that don't
	belong to a GTD as well.

svn path=/trunk/mcs/; revision=148735
Rodrigo Kumpera hace 16 años
padre
commit
94fa86a676

+ 11 - 0
mcs/class/corlib/System.Reflection/ChangeLog

@@ -1,3 +1,14 @@
+2009-12-17 Rodrigo Kumpera  <[email protected]>
+
+	* MonoGenericClass.cs (GetMethods): When the GTD is not a typebuilder,
+	calling GetMethods on it will return everything we need so no need to
+	do the crazy loop.
+	The returned methods might contains some that are not from a generic type
+	so we need to guard against this as well.
+
+	* MonoGenericClass.cs (GetMethodsInternal): Guard against methods that don't
+	belong to a GTD as well.
+
 2009-12-14 Rodrigo Kumpera  <[email protected]>
 
 	* MonoGenericClass.cs: Remove IsByRef hack.

+ 33 - 21
mcs/class/corlib/System.Reflection/MonoGenericClass.cs

@@ -352,27 +352,35 @@ namespace System.Reflection
 			// Walk up our class hierarchy and retrieve methods from our
 			// parent classes.
 			//
-
-			Type current_type = this;
-			do {
-				MonoGenericClass gi = current_type as MonoGenericClass;
-				if (gi != null)
-					l.AddRange (gi.GetMethodsInternal (bf, this));
-				else if (current_type is TypeBuilder)
-					l.AddRange (current_type.GetMethods (bf));
-				else {
-					// If we encounter a `MonoType', its
-					// GetMethodsByName() will return all the methods
-					// from its parent type(s), so we can stop here.
-					MonoType mt = (MonoType) current_type;
-					l.AddRange (mt.GetMethodsByName (null, bf, false, this));
-					break;
+			if (!(generic_type is TypeBuilder)) {
+				foreach (var method in generic_type.GetMethods (bf)) {
+					var m = method;
+					if (m.DeclaringType.IsGenericTypeDefinition)
+						m = TypeBuilder.GetMethod (this, m);
+					l.Add (m);
 				}
-
-				if ((bf & BindingFlags.DeclaredOnly) != 0)
-					break;
-				current_type = current_type.BaseType;
-			} while (current_type != null);
+			} else {
+				Type current_type = this;
+				do {
+					MonoGenericClass gi = current_type as MonoGenericClass;
+					if (gi != null)
+						l.AddRange (gi.GetMethodsInternal (bf, this));
+					else if (current_type is TypeBuilder)
+						l.AddRange (current_type.GetMethods (bf));
+					else {
+						// If we encounter a `MonoType', its
+						// GetMethodsByName() will return all the methods
+						// from its parent type(s), so we can stop here.
+						MonoType mt = (MonoType) current_type;
+						l.AddRange (mt.GetMethodsByName (null, bf, false, this));
+						break;
+					}
+
+					if ((bf & BindingFlags.DeclaredOnly) != 0)
+						break;
+					current_type = current_type.BaseType;
+				} while (current_type != null);
+			}
 
 			MethodInfo[] result = new MethodInfo [l.Count];
 			l.CopyTo (result);
@@ -381,6 +389,9 @@ namespace System.Reflection
 
 		MethodInfo[] GetMethodsInternal (BindingFlags bf, MonoGenericClass reftype)
 		{
+			if (reftype != this)
+				bf |= BindingFlags.DeclaredOnly; /*To avoid duplicates*/
+
 			MethodInfo[] methods = GetMethodsFromGTDWithHint (bf);
 			if (methods.Length == 0)
 				return new MethodInfo [0];
@@ -415,7 +426,8 @@ namespace System.Reflection
 				}
 				if (!match)
 					continue;
-				c = TypeBuilder.GetMethod (this, c);
+				if (c.DeclaringType.IsGenericTypeDefinition)
+					c = TypeBuilder.GetMethod (this, c);
 				l.Add (c);
 			}