private void BuildClassModel(Class @class, File[] files) { var methods = _symbolManager.GetMethodsForType(@class, files); foreach (var method in methods) { method.SequencePoints = _symbolManager.GetSequencePointsForToken(method.MetadataToken); method.MethodPoint = (method.SequencePoints!=null) ? method.SequencePoints.FirstOrDefault(pt => pt.Offset == 0) : null; method.MethodPoint = method.MethodPoint ?? new InstrumentationPoint(); method.BranchPoints = _symbolManager.GetBranchPointsForToken(method.MetadataToken); method.CyclomaticComplexity = _symbolManager.GetCyclomaticComplexityForToken(method.MetadataToken); } @class.Methods = methods.Where(method => method.SequencePoints != null).ToArray(); }
private void BuildClassModel(Class @class, File[] files) { if (@class.ShouldSerializeSkippedDueTo()) return; var methods = _symbolManager.GetMethodsForType(@class, files); foreach (var method in methods) { if (!method.ShouldSerializeSkippedDueTo()) { method.SequencePoints = _symbolManager.GetSequencePointsForToken(method.MetadataToken); method.MethodPoint = (method.SequencePoints != null) ? method.SequencePoints.FirstOrDefault(pt => pt.Offset == 0) : null; method.MethodPoint = method.MethodPoint ?? new InstrumentationPoint(); method.BranchPoints = _symbolManager.GetBranchPointsForToken(method.MetadataToken); } method.CyclomaticComplexity = _symbolManager.GetCyclomaticComplexityForToken(method.MetadataToken); } @class.Methods = methods; }
private static void GetInstrumentableTypes(IEnumerable<TypeDefinition> typeDefinitions, List<Class> classes, IFilter filter, string moduleName) { foreach (var typeDefinition in typeDefinitions) { if (typeDefinition.IsEnum) continue; if (typeDefinition.IsInterface && typeDefinition.IsAbstract) continue; var @class = new Class() { FullName = typeDefinition.FullName }; if (!filter.InstrumentClass(moduleName, @class.FullName)) { @class.SkippedDueTo = SkippedMethod.Filter; } else if (filter.ExcludeByAttribute(typeDefinition)) { @class.SkippedDueTo = SkippedMethod.Attribute; } var list = new List<string>(); if ([email protected]()) { foreach (var methodDefinition in typeDefinition.Methods) { if (methodDefinition.Body != null && methodDefinition.Body.Instructions != null) { foreach (var instruction in methodDefinition.Body.Instructions) { if (instruction.SequencePoint != null) { list.Add(instruction.SequencePoint.Document.Url); break; } } } } } // only instrument types that are not structs and have instrumentable points if (!typeDefinition.IsValueType || list.Count > 0) { @class.Files = list.Distinct().Select(file => new File { FullPath = file }).ToArray(); classes.Add(@class); } if (typeDefinition.HasNestedTypes) GetInstrumentableTypes(typeDefinition.NestedTypes, classes, filter, moduleName); } }
public Method[] GetMethodsForType(Class type, File[] files) { var methods = new List<Method>(); IEnumerable<TypeDefinition> typeDefinitions = SourceAssembly.MainModule.Types; GetMethodsForType(typeDefinitions, type.FullName, methods, files, _filter); return methods.ToArray(); }
private static void GetMethodsForType(IEnumerable<TypeDefinition> typeDefinitions, Class type, List<Method> methods, File[] files) { foreach (var typeDefinition in typeDefinitions) { if (typeDefinition.FullName == type.FullName) { foreach (var methodDefinition in typeDefinition.Methods) { if (!methodDefinition.IsConstructor) { var method = new Method() { Name = methodDefinition.FullName, MetadataToken = methodDefinition.MetadataToken.ToInt32() }; var definition = methodDefinition; method.FileRef = files.Where(x => x.FullPath == GetFirstFile(definition)).Select(x => new FileRef() {UniqueId = x.UniqueId}).FirstOrDefault(); methods.Add(method); } } } if (typeDefinition.HasNestedTypes) GetMethodsForType(typeDefinition.NestedTypes, type, methods, files); } }
private static void GetInstrumentableTypes(IEnumerable<TypeDefinition> typeDefinitions, List<Class> classes) { foreach (var typeDefinition in typeDefinitions) { if (typeDefinition.IsEnum) continue; if (typeDefinition.IsValueType) continue; if (typeDefinition.IsInterface && typeDefinition.IsAbstract) continue; var @class = new Class() {FullName = typeDefinition.FullName}; var list = new List<string>(); foreach (var methodDefinition in typeDefinition.Methods) { if (methodDefinition.Body != null && methodDefinition.Body.Instructions != null) { foreach (var instruction in methodDefinition.Body.Instructions) { if (instruction.SequencePoint != null) { list.Add(instruction.SequencePoint.Document.Url); break; } } } } @class.Files = list.Distinct().Select(file => new File { FullPath = file }).ToArray(); classes.Add(@class); if (typeDefinition.HasNestedTypes) GetInstrumentableTypes(typeDefinition.NestedTypes, classes); } }
private Method GetMethod(string modulePath, int functionToken, out Class @class) { @class = null; //c = null; var module = CoverageSession.Modules.FirstOrDefault(x => x.Aliases.Any(path => path.Equals(modulePath, StringComparison.InvariantCultureIgnoreCase))); if (module == null) return null; if (!_moduleMethodMap[module].ContainsKey(functionToken)) return null; var pair = _moduleMethodMap[module][functionToken]; @class = pair.Key; return pair.Value; }
public ClassNode(Class @class) { Class = @class; LazyLoading = true; }
private Method GetMethod(string modulePath, int functionToken, out Class @class) { @class = null; //c = null; var module = CoverageSession.Modules.FirstOrDefault(x => x.Aliases.Any(path => path.Equals(modulePath, StringComparison.InvariantCultureIgnoreCase))); if (module == null) return null; foreach (var c in module.Classes) { @class = c; foreach (var method in c.Methods) { if (method.MetadataToken == functionToken) return method; } } @class = null; return null; }
private static void CalculateCyclomaticComplexity(Method method, Class @class) { method.Summary.MinCyclomaticComplexity = Math.Max(1, method.CyclomaticComplexity); method.Summary.MaxCyclomaticComplexity = method.Summary.MinCyclomaticComplexity; if (@class.Summary.MinCyclomaticComplexity == 0) @class.Summary.MinCyclomaticComplexity = method.Summary.MinCyclomaticComplexity; @class.Summary.MinCyclomaticComplexity = Math.Min(@class.Summary.MinCyclomaticComplexity, method.CyclomaticComplexity); @class.Summary.MaxCyclomaticComplexity = Math.Max(@class.Summary.MaxCyclomaticComplexity, method.CyclomaticComplexity); }
private static void ProcessMethodData(Method method, Class @class) { if (method.MethodPoint != null) { method.Visited = (method.MethodPoint.VisitCount > 0); } method.Summary.NumBranchPoints = method.BranchPoints.Length; method.Summary.VisitedBranchPoints = method.BranchPoints.Count(pt => pt.VisitCount != 0); method.Summary.NumSequencePoints = method.SequencePoints.Length; method.Summary.VisitedSequencePoints = method.SequencePoints.Count(pt => pt.VisitCount != 0); if (method.Summary.NumSequencePoints > 0) method.Summary.NumBranchPoints += 1; if (method.Summary.VisitedSequencePoints > 0) method.Summary.VisitedBranchPoints += 1; if (method.FileRef != null) { method.Summary.NumMethods = 1; method.Summary.VisitedMethods = (method.Visited) ? 1 : 0; } AddPoints(@class.Summary, method.Summary); CalculateCoverage(method.Summary); method.SequenceCoverage = method.Summary.SequenceCoverage; method.BranchCoverage = method.Summary.BranchCoverage; CalculateNPathComplexity(method); CalculateCyclomaticComplexity(method, @class); }
private static void ProcessClassData(Class @class, Module module) { @class.Summary.NumClasses = (@class.Summary.NumMethods > 0) ? 1 : 0; @class.Summary.VisitedClasses = (@class.Summary.VisitedMethods > 0) ? 1 : 0; AddPoints(module.Summary, @class.Summary); CalculateCoverage(@class.Summary); if (module.Summary.MinCyclomaticComplexity == 0) module.Summary.MinCyclomaticComplexity = @class.Summary.MinCyclomaticComplexity; module.Summary.MinCyclomaticComplexity = Math.Min(module.Summary.MinCyclomaticComplexity, @class.Summary.MinCyclomaticComplexity); module.Summary.MaxCyclomaticComplexity = Math.Max(module.Summary.MaxCyclomaticComplexity, @class.Summary.MaxCyclomaticComplexity); }
private static void CalculateCrapScore(Method method, Class @class) { method.CrapScore = Math.Round((decimal) Math.Pow(method.CyclomaticComplexity, 2) * (decimal) Math.Pow(1.0 - (double) (method.SequenceCoverage / (decimal) 100.0), 3.0) + method.CyclomaticComplexity, 2); // TODO: is 0 a possible crap score? method.Summary.MinCrapScore = Math.Max(0, method.CrapScore); method.Summary.MaxCrapScore = method.Summary.MinCrapScore; if (@class.Summary.MinCrapScore == 0) { @class.Summary.MinCrapScore = method.Summary.MinCrapScore; } @class.Summary.MinCrapScore = Math.Min(@class.Summary.MinCrapScore, method.CrapScore); @class.Summary.MaxCrapScore = Math.Max(@class.Summary.MaxCrapScore, method.CrapScore); }