internal static MethodBase FindMostDerivedMatch(MethodBase [] match) { int highLevel = 0; int matchId = -1; int count = match.Length; for (int current = 0; current < count; current++) { MethodBase m = match [current]; int level = GetDerivedLevel(m.DeclaringType); if (level == highLevel) { throw new AmbiguousMatchException(); } // If the argument types differ we // have an ambigous match, as well if (matchId >= 0) { ParameterInfo[] p1 = m.GetParametersInternal(); ParameterInfo[] p2 = match [matchId].GetParametersInternal(); bool equal = true; if (p1.Length != p2.Length) { equal = false; } else { int i; for (i = 0; i < p1.Length; ++i) { if (p1 [i].ParameterType != p2 [i].ParameterType) { equal = false; break; } } } if (!equal) { throw new AmbiguousMatchException(); } } if (level > highLevel) { highLevel = level; matchId = current; } } return(match[matchId]); }
MethodBase GetBetterMethod(MethodBase m1, MethodBase m2, Type [] types) { ParameterInfo [] pl1 = m1.GetParametersInternal(); ParameterInfo [] pl2 = m2.GetParametersInternal(); int prev = 0; for (int i = 0; i < pl1.Length; i++) { int cmp = CompareCloserType(pl1 [i].ParameterType, pl2 [i].ParameterType); if (cmp != 0 && prev != 0 && prev != cmp) { throw new AmbiguousMatchException(); } if (cmp != 0) { prev = cmp; } } if (prev != 0) { return(prev > 0 ? m2 : m1); } Type dt1 = m1.DeclaringType; Type dt2 = m2.DeclaringType; if (dt1 != dt2) { if (dt1.IsSubclassOf(dt2)) { return(m1); } if (dt2.IsSubclassOf(dt1)) { return(m2); } } bool va1 = (m1.CallingConvention & CallingConventions.VarArgs) != 0; bool va2 = (m2.CallingConvention & CallingConventions.VarArgs) != 0; if (va1 && !va2) { return(m2); } if (va2 && !va1) { return(m1); } throw new AmbiguousMatchException(); }
// probably belongs in ReorderArgumentArray static void AdjustArguments(MethodBase selected, ref object [] args) { var parameters = selected.GetParametersInternal(); var parameters_length = parameters.Length; if (parameters_length == 0) { return; } var last_parameter = parameters [parameters.Length - 1]; Type last_parameter_type = last_parameter.ParameterType; if (!Attribute.IsDefined(last_parameter, typeof(ParamArrayAttribute))) { return; } var args_length = args.Length; var param_args_count = args_length + 1 - parameters_length; var first_vararg_index = args_length - param_args_count; if (first_vararg_index < args_length) { var first_vararg = args [first_vararg_index]; if (first_vararg != null && first_vararg.GetType() == last_parameter_type) { return; } } var params_args = Array.CreateInstance(last_parameter_type.GetElementType(), param_args_count); for (int i = 0; i < param_args_count; i++) { params_args.SetValue(args [first_vararg_index + i], i); } var adjusted = new object [parameters_length]; Array.Copy(args, adjusted, parameters_length - 1); adjusted [adjusted.Length - 1] = params_args; args = adjusted; }
void ReorderParameters(string [] names, ref object [] args, MethodBase selected) { object [] newArgs = new object [args.Length]; Array.Copy(args, newArgs, args.Length); ParameterInfo [] plist = selected.GetParametersInternal(); for (int n = 0; n < names.Length; n++) { for (int p = 0; p < plist.Length; p++) { if (names [n] == plist [p].Name) { newArgs [p] = args [n]; break; } } } Array.Copy(newArgs, args, args.Length); }
internal void GetFullNameForStackTrace (StringBuilder sb, MethodBase mi) { ParameterInfo[] p = mi.GetParametersInternal (); sb.Append (mi.DeclaringType.ToString ()); sb.Append ("."); sb.Append (mi.Name); if (mi.IsGenericMethod) { Type[] gen_params = mi.GetGenericArguments (); sb.Append ("["); for (int j = 0; j < gen_params.Length; j++) { if (j > 0) sb.Append (","); sb.Append (gen_params [j].Name); } sb.Append ("]"); } sb.Append (" ("); for (int i = 0; i < p.Length; ++i) { if (i > 0) sb.Append (", "); Type pt = p[i].ParameterType; if (pt.IsClass && !String.IsNullOrEmpty (pt.Namespace)) { sb.Append (pt.Namespace); sb.Append ("."); } sb.Append (pt.Name); if (p [i].Name != null) { sb.Append (" "); sb.Append (p [i].Name); } } sb.Append (")"); }
// This method is also used with reflection by mono-symbolicate tool. // mono-symbolicate tool uses this method to check which method matches // the stack frame method signature. static void GetFullNameForStackTrace (StringBuilder sb, MethodBase mi) { var declaringType = mi.DeclaringType; if (declaringType.IsGenericType && !declaringType.IsGenericTypeDefinition) declaringType = declaringType.GetGenericTypeDefinition (); // Get generic definition var bindingflags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; foreach (var m in declaringType.GetMethods (bindingflags)) { if (m.MetadataToken == mi.MetadataToken) { mi = m; break; } } sb.Append (declaringType.ToString ()); sb.Append ("."); sb.Append (mi.Name); if (mi.IsGenericMethod) { Type[] gen_params = mi.GetGenericArguments (); sb.Append ("["); for (int j = 0; j < gen_params.Length; j++) { if (j > 0) sb.Append (","); sb.Append (gen_params [j].Name); } sb.Append ("]"); } ParameterInfo[] p = mi.GetParametersInternal (); sb.Append (" ("); for (int i = 0; i < p.Length; ++i) { if (i > 0) sb.Append (", "); Type pt = p[i].ParameterType; if (pt.IsGenericType && ! pt.IsGenericTypeDefinition) pt = pt.GetGenericTypeDefinition (); if (pt.IsClass && !String.IsNullOrEmpty (pt.Namespace)) { sb.Append (pt.Namespace); sb.Append ("."); } sb.Append (pt.Name); if (p [i].Name != null) { sb.Append (" "); sb.Append (p [i].Name); } } sb.Append (")"); }
MethodBase GetBetterMethod (MethodBase m1, MethodBase m2, Type [] types) { ParameterInfo [] pl1 = m1.GetParametersInternal (); ParameterInfo [] pl2 = m2.GetParametersInternal (); int prev = 0; for (int i = 0; i < pl1.Length; i++) { int cmp = CompareCloserType (pl1 [i].ParameterType, pl2 [i].ParameterType); if (cmp != 0 && prev != 0 && prev != cmp) throw new AmbiguousMatchException (); if (cmp != 0) prev = cmp; } if (prev != 0) return prev > 0 ? m2 : m1; Type dt1 = m1.DeclaringType; Type dt2 = m2.DeclaringType; if (dt1 != dt2) { if (dt1.IsSubclassOf(dt2)) return m1; if (dt2.IsSubclassOf(dt1)) return m2; } bool va1 = (m1.CallingConvention & CallingConventions.VarArgs) != 0; bool va2 = (m2.CallingConvention & CallingConventions.VarArgs) != 0; if (va1 && !va2) return m2; if (va2 && !va1) return m1; throw new AmbiguousMatchException (); }
void ReorderParameters (string [] names, ref object [] args, MethodBase selected) { object [] newArgs = new object [args.Length]; Array.Copy (args, newArgs, args.Length); ParameterInfo [] plist = selected.GetParametersInternal (); for (int n = 0; n < names.Length; n++) for (int p = 0; p < plist.Length; p++) { if (names [n] == plist [p].Name) { newArgs [p] = args [n]; break; } } Array.Copy (newArgs, args, args.Length); }
// probably belongs in ReorderArgumentArray static void AdjustArguments (MethodBase selected, ref object [] args) { var parameters = selected.GetParametersInternal (); var parameters_length = parameters.Length; if (parameters_length == 0) return; var last_parameter = parameters [parameters.Length - 1]; Type last_parameter_type = last_parameter.ParameterType; if (!Attribute.IsDefined (last_parameter, typeof (ParamArrayAttribute))) return; var args_length = args.Length; var param_args_count = args_length + 1 - parameters_length; var first_vararg_index = args_length - param_args_count; if (first_vararg_index < args_length) { var first_vararg = args [first_vararg_index]; if (first_vararg != null && first_vararg.GetType () == last_parameter_type) return; } var params_args = Array.CreateInstance (last_parameter_type.GetElementType (), param_args_count); for (int i = 0; i < param_args_count; i++) params_args.SetValue (args [first_vararg_index + i], i); var adjusted = new object [parameters_length]; Array.Copy (args, adjusted, parameters_length - 1); adjusted [adjusted.Length - 1] = params_args; args = adjusted; }