public static MethodInfo[] GetMethods(Type grainType, bool bAllMethods = true) { var methodInfos = new List <MethodInfo>(); GetMethodsImpl(grainType, grainType, methodInfos); var flags = BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance; if (!bAllMethods) { flags |= BindingFlags.DeclaredOnly; } MethodInfo[] infos = grainType.GetMethods(flags); IEqualityComparer <MethodInfo> methodComparer = new MethodInfoComparer(); foreach (var methodInfo in infos) { if (!methodInfos.Contains(methodInfo, methodComparer)) { methodInfos.Add(methodInfo); } } return(methodInfos.ToArray()); }
/// <summary> /// Recurses through interface graph accumulating methods /// </summary> /// <param name="grainType">Grain type</param> /// <param name="serviceType">Service interface type</param> /// <param name="methodInfos">Accumulated </param> private static void GetMethodsImpl(Type grainType, Type serviceType, List <MethodInfo> methodInfos) { Type[] iTypes = GetRemoteInterfaces(serviceType, false).Values.ToArray(); IEqualityComparer <MethodInfo> methodComparer = new MethodInfoComparer(); var typeInfo = grainType.GetTypeInfo(); foreach (Type iType in iTypes) { var mapping = new InterfaceMapping(); if (typeInfo.IsClass) { mapping = typeInfo.GetRuntimeInterfaceMap(iType); } if (typeInfo.IsInterface || mapping.TargetType == grainType) { foreach (var methodInfo in iType.GetMethods()) { if (typeInfo.IsClass) { var mi = methodInfo; var match = mapping.TargetMethods.Any(info => methodComparer.Equals(mi, info) && info.DeclaringType == grainType); if (match) { if (!methodInfos.Contains(mi, methodComparer)) { methodInfos.Add(mi); } } } else if (!methodInfos.Contains(methodInfo, methodComparer)) { methodInfos.Add(methodInfo); } } } } }
// Compare base and diff file lists and produce a sorted list of method // deltas by file. Delta is computed diffBytes - baseBytes so positive // numbers are regressions. (lower is better) // // Todo: handle metrics where "higher is better" public static IEnumerable <FileDelta> Comparator(IEnumerable <FileInfo> baseInfo, IEnumerable <FileInfo> diffInfo, Config config) { MethodInfoComparer methodInfoComparer = new MethodInfoComparer(); return(baseInfo.Join(diffInfo, b => b.path, d => d.path, (b, d) => { var jointList = b.methodList.Join(d.methodList, x => x.name, y => y.name, (x, y) => new MethodDelta { name = x.name, baseMetrics = new MetricCollection(x.Metrics), diffMetrics = new MetricCollection(y.Metrics), baseOffsets = x.functionOffsets, diffOffsets = y.functionOffsets }) .OrderByDescending(r => r.deltaMetrics.GetMetric(config.Metric).Value); FileDelta f = new FileDelta { basePath = b.path, diffPath = d.path, baseMetrics = jointList.Sum(x => x.baseMetrics), diffMetrics = jointList.Sum(x => x.diffMetrics), deltaMetrics = jointList.Sum(x => x.deltaMetrics), methodsInBoth = jointList.Count(), methodsOnlyInBase = b.methodList.Except(d.methodList, methodInfoComparer), methodsOnlyInDiff = d.methodList.Except(b.methodList, methodInfoComparer), methodDeltaList = jointList.Where(x => x.deltaMetrics.GetMetric(config.Metric).Value != 0) }; if (config.Reconcile) { f.Reconcile(); } return f; }).ToList()); }
// Compare base and diff file lists and produce a sorted list of method // deltas by file. Delta is computed diffBytes - baseBytes so positive // numbers are regressions. (lower is better) public static IEnumerable <FileDelta> Comparator(IEnumerable <FileInfo> baseInfo, IEnumerable <FileInfo> diffInfo, Config config) { MethodInfoComparer methodInfoComparer = new MethodInfoComparer(); return(baseInfo.Join(diffInfo, b => b.path, d => d.path, (b, d) => { var jointList = b.methodList.Join(d.methodList, x => x.name, y => y.name, (x, y) => new MethodDelta { name = x.name, baseBytes = x.totalBytes, diffBytes = y.totalBytes, baseOffsets = x.functionOffsets, diffOffsets = y.functionOffsets }) .OrderByDescending(r => r.deltaBytes); FileDelta f = new FileDelta { path = b.path, baseBytes = jointList.Sum(x => x.baseBytes), diffBytes = jointList.Sum(x => x.diffBytes), deltaBytes = jointList.Sum(x => x.deltaBytes), methodsOnlyInBase = b.methodList.Except(d.methodList, methodInfoComparer), methodsOnlyInDiff = d.methodList.Except(b.methodList, methodInfoComparer), methodDeltaList = jointList.Where(x => x.deltaBytes != 0) }; if (config.Reconcile) { f.Reconcile(); } return f; })); }