private static TypeReference DoGetDeclaringInterface(TypeReference declared, MethodMatcher matcher, AssemblyCache cache) { Log.DebugLine(true, " finding {0}", declared.FullName); TypeDefinition type = cache.FindType(declared); if (type != null) { Log.DebugLine(true, " found {0}, {1} interfaces", type.FullName, type.Interfaces.Count); foreach (TypeReference inRef in type.Interfaces) { Log.DebugLine(true, " references {0}", inRef.FullName); TypeDefinition inType = cache.FindType(inRef); if (inType != null) { Log.DebugLine(true, " checking {0}", inType); if (DoDeclares(inType, matcher)) { return(inType); } } } } return(null); }
private static bool DoDeclares(TypeDefinition type, MethodMatcher matcher) { foreach (MethodDefinition method in type.Methods) { if (matcher == method) { return(true); } } return(false); }
/// <summary>Returns the first base class (not including Object) method which declares the specified method. /// Note that this may return an abstract method, or the original method, or null if a base /// type could not be found.</summary> public static MethodDefinition GetBasestMethod(this MethodDefinition method, AssemblyCache cache) { DBC.Pre(method != null, "method is null"); DBC.Pre(cache != null, "cache is null"); MethodDefinition result = method; if (method.IsVirtual) { TypeDefinition type = cache.FindType(method.DeclaringType); if (type != null) { type = cache.FindType(type.BaseType); } while (type != null && type.FullName != "System.Object") { MethodMatcher matcher = new MethodMatcher(method); MethodDefinition[] candidates = type.Methods.GetMethod(method.Name); foreach (MethodDefinition candidate in candidates) { if (candidate.IsVirtual && !candidate.IsFinal && matcher == candidate) { result = candidate; } } type = cache.FindType(type.BaseType); } if (type == null) { result = null; } } return(result); }