internal void CompareMethodAgainstTypeMethods (MethodDefinition current, TypeReference targetType) { if (CheckedTypes.Contains (targetType.Name)) return; foreach (MethodDefinition target in targetType.GetMethods ()) { if (target.IsGeneratedCode ()) continue; Pattern duplicated = GetDuplicatedCode (current, target); if (duplicated != null && duplicated.Count > 0) rule.Runner.Report (current, duplicated[0], Severity.High, Confidence.Normal, String.Format ("Duplicated code with {0}", target)); } }
private static bool DoesTypeStealthilyImplementInterface (TypeDefinition type, TypeReference iface) { //ignore already uninteresting types below (self, enum, struct, static class) if (type == iface || type.IsEnum || type.IsValueType || type.IsStatic ()) return false; //if type has less methods than the interface no need to check further if (!type.HasMethods) return false; IList<MethodDefinition> mdc = iface.GetMethods ().ToList (); if (type.Methods.Count < mdc.Count) return false; //type already publicly says it implements the interface if (type.Implements (iface.FullName)) return false; foreach (MethodDefinition m in mdc) { //if any candidate fails we can return right away //since the interface will never be fully implemented MethodDefinition candidate = type.GetMethod (MethodAttributes.Public, m.Name); if (null == candidate || !candidate.IsPublic || candidate.IsStatic) return false; //ok interesting candidate! let's check if it matches the signature if (!AreSameElementTypes (m.ReturnType, candidate.ReturnType)) return false; if (!CompareParameters (m, candidate)) return false; } return true; }
public static CacheType Resolve(Type type) #endif { if (type == null) { throw new ArgumentNullException(nameof(type)); } var exceptions = new List <Exception>(); var methods = new List <CacheMethod>(); foreach (var method in type.GetMethods()) { var canBeOverride = method.IsVirtual && !method.IsFinal; #if BuildTask if (!canBeOverride || method.DeclaringType == method.Module.TypeSystem.Object) { continue; } #else if (!canBeOverride || method.DeclaringType == typeof(object)) { continue; } #endif var operation = GetOperation(method); if (operation == CacheOperation.Ignore) { if (method.IsAbstract) { exceptions.Add(new InvalidOperationException($"不支持的抽象方法{method.Name}")); } continue; } CacheMethod?cm = null; switch (operation) { case CacheOperation.Get: cm = ResolveGet(method); if (cm == null) { exceptions.Add(ParameterException(type, method)); } break; case CacheOperation.Set: cm = ResolveSet(method); if (cm == null) { exceptions.Add(ParameterException(type, method)); } break; case CacheOperation.Remove: cm = ResolveRemove(method); if (cm == null) { exceptions.Add(ParameterException(type, method)); } break; default: exceptions.Add(new InvalidOperationException($"{method.Name}不支持的操作{operation}")); break; } if (cm != null) { methods.Add(cm); } } if (exceptions.Count > 0) { throw new AggregateException(exceptions); } return(new CacheType(GetCacheName(type, out var defaultTtl), type, methods) { DefaultTtl = defaultTtl });
private static bool OnlyContainsExternalMethods (TypeReference type) { bool has_methods = false; foreach (MethodDefinition method in type.GetMethods ()) { has_methods = true; if (!method.IsPInvokeImpl) return false; } // all methods are p/invoke return has_methods; }
//TODO: Perhaps we can perform this action with linq instead of //loop + hashtable private static IEnumerable<MethodDefinition> GetSmallestOverloaded (TypeReference type) { IDictionary<string, MethodDefinition> possibleOverloaded = new Dictionary<string, MethodDefinition> (); foreach (MethodDefinition method in type.GetMethods ()) { if (method.IsPInvokeImpl) continue; string name = method.Name; if (!possibleOverloaded.ContainsKey (name)) possibleOverloaded.Add (name, method); else { MethodDefinition candidate = possibleOverloaded [name]; int ccount = candidate.HasParameters ? candidate.Parameters.Count : 0; int mcount = method.HasParameters ? method.Parameters.Count : 0; if (ccount > mcount) possibleOverloaded [name] = method; } } return possibleOverloaded.Values; }