/// <summary> /// Add the <see cref="Module"/> to the current session /// </summary> /// <param name="module"></param> public void PersistModule(Module module) { if (module == null) return; module.Classes = module.Classes ?? new Class[0]; if (CommandLine.MergeByHash) { lock (Protection) { var modules = CoverageSession.Modules ?? new Module[0]; lock (Protection) { var existingModule = modules.FirstOrDefault(x => x.ModuleHash == module.ModuleHash); if (existingModule != null) { if ( !existingModule.Aliases.Any( x => x.Equals(module.ModulePath, StringComparison.InvariantCultureIgnoreCase))) { existingModule.Aliases.Add(module.ModulePath); } return; } } } } _moduleMethodMap[module] = new Dictionary<int, KeyValuePair<Class, Method>>(); BuildMethodMapForModule(module); var list = new List<Module>(CoverageSession.Modules ?? new Module[0]) { module }; CoverageSession.Modules = list.ToArray(); }
private Module CreateModule(bool full) { var hash = string.Empty; var timeStamp = DateTime.MinValue; if (System.IO.File.Exists(_symbolManager.ModulePath)) { try { timeStamp = System.IO.File.GetLastWriteTimeUtc(_symbolManager.ModulePath); } catch (Exception e) { e.InformUser(); } hash = HashFile(_symbolManager.ModulePath); } var module = new Module { ModuleName = _symbolManager.ModuleName, ModulePath = _symbolManager.ModulePath, ModuleHash = hash, ModuleTime = timeStamp }; module.Aliases.Add(_symbolManager.ModulePath); if (full) { module.Files = _symbolManager.GetFiles(); module.Classes = _symbolManager.GetInstrumentableTypes(); foreach (var @class in module.Classes) { BuildClassModel(@class, module.Files); } } return module; }
private void ProcessGenericMethods(CoverageSession coverageSession) { CoveredMethodStats[] coveredMethodStats = Coverage.GetStatsForAllCoveredMethods(); foreach (CoveredMethodStats coveredMethodStat in coveredMethodStats) { MethodBase method = coveredMethodStat.method; ResultsLogger.LogSessionItem($"Processing generic method: {method.Name}", LogVerbosityLevel.Verbose); Type declaringType = method.DeclaringType; string assemblyName = declaringType.Assembly.GetName().Name.ToLower(); if (!m_ReporterFilter.ShouldProcessAssembly(assemblyName)) { ResultsLogger.LogSessionItem($"Excluded assembly from generic (Assembly Filtering): {assemblyName}", LogVerbosityLevel.Verbose); continue; } if (!(declaringType.IsGenericType || method.IsGenericMethod)) { continue; } Module module = Array.Find(coverageSession.Modules, element => element.ModuleName.ToLower() == assemblyName); if (module != null) { string className = string.Empty; if (declaringType.IsGenericType) { Type genericTypeDefinition = declaringType.GetGenericTypeDefinition(); className = GenerateTypeName(genericTypeDefinition); } else if (method.IsGenericMethod) { className = GenerateTypeName(declaringType); } Class klass = Array.Find(module.Classes, element => element.FullName == className); if (klass != null) { Method targetMethod = Array.Find(klass.Methods, element => element.MetadataToken == method.MetadataToken); if (targetMethod != null) { ResultsLogger.LogSessionItem($"Processing included generic method: {method.Name}", LogVerbosityLevel.Verbose); CoveredSequencePoint[] coveredSequencePoints = Coverage.GetSequencePointsFor(method); foreach (CoveredSequencePoint coveredSequencePoint in coveredSequencePoints) { SequencePoint targetSequencePoint = Array.Find(targetMethod.SequencePoints, element => (element.StartLine == coveredSequencePoint.line && element.Offset == coveredSequencePoint.ilOffset)); if (targetSequencePoint != null) { targetSequencePoint.VisitCount += (int)coveredSequencePoint.hitCount; } } } } } } }
public NamespaceNode(Module module, string @namespace) { _module = module; _namespace = @namespace; LazyLoading = true; var coveredClasses = _module.CoveredClasses; foreach (var @class in coveredClasses .Where(cc => cc.Namespace == _namespace)) { _visitedSequencePoints += @class.Summary.VisitedSequencePoints; _numSequencePoints += @class.Summary.NumSequencePoints; } }
public Module BuildModuleModel() { if (!_filter.UseAssembly(_symbolManager.ModuleName)) return null; var hash = string.Empty; if (System.IO.File.Exists(_symbolManager.ModulePath)) { hash = HashFile(_symbolManager.ModulePath); } var module = new Module { ModuleName = _symbolManager.ModuleName, FullName = _symbolManager.ModulePath, Files = _symbolManager.GetFiles(), ModuleHash = hash }; module.Aliases.Add(_symbolManager.ModulePath); module.Classes = _symbolManager.GetInstrumentableTypes(); foreach (var @class in module.Classes) { BuildClassModel(@class, module.Files); } return module; }
internal CoverageSession GenerateOpenCoverSession() { ResultsLogger.LogSessionItem("Started OpenCover Session", LogVerbosityLevel.Info); CoverageSession coverageSession = null; UInt32 fileUID = 0; List <Module> moduleList = new List <Module>(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); float progressInterval = 0.9f / assemblies.Length; float currentProgress = 0.0f; bool shouldGenerateAdditionalMetrics = m_ReporterFilter.ShouldGenerateAdditionalMetrics(); foreach (Assembly assembly in assemblies) { string assemblyName = assembly.GetName().Name.ToLower(); ResultsLogger.LogSessionItem($"Processing assembly: {assemblyName}", LogVerbosityLevel.Verbose); try { if (assembly.GetCustomAttribute <ExcludeFromCoverageAttribute>() != null || assembly.GetCustomAttribute <ExcludeFromCodeCoverageAttribute>() != null) { ResultsLogger.LogSessionItem($"Excluded assembly (ExcludeFromCoverage): {assemblyName}", LogVerbosityLevel.Verbose); continue; } } catch { ResultsLogger.Log(ResultID.Warning_ExcludeAttributeAssembly, assemblyName); } if (!CommandLineManager.instance.batchmode) { EditorUtility.DisplayProgressBar(Styles.ProgressTitle.text, Styles.ProgressGatheringResults.text, currentProgress); } currentProgress += progressInterval; if (!m_ReporterFilter.ShouldProcessAssembly(assemblyName)) { ResultsLogger.LogSessionItem($"Excluded assembly (Assembly Filtering): {assemblyName}", LogVerbosityLevel.Verbose); continue; } List <Class> coveredClasses = new List <Class>(); List <string> filesNotFound = new List <string>(); Dictionary <string, UInt32> fileList = new Dictionary <string, UInt32>(); Type[] assemblyTypes = null; m_ExcludedMethods = null; m_ExcludedTypes = null; try { assemblyTypes = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { // This exception can be thrown if some of the types from this assembly can't be loaded. If this // happens, the Types property array contains a Type for all loaded types and null for each // type that couldn't be loaded. assemblyTypes = ex.Types; m_ReporterFilter.ShouldProcessAssembly(assemblyName); } // Debug.Assert(assemblyTypes != null) ResultsLogger.Log(ResultID.Assert_NullAssemblyTypes, assemblyTypes == null ? "0" : "1"); ResultsLogger.LogSessionItem($"Processing included assembly: {assemblyName}", LogVerbosityLevel.Info); foreach (Type type in assemblyTypes) { // The type can be null if the ReflectionTypeLoadException has been thrown previously. if (type == null) { continue; } string className = type.FullName; ResultsLogger.LogSessionItem($"Processing class: {className}", LogVerbosityLevel.Verbose); try { if (type.GetCustomAttribute <ExcludeFromCoverageAttribute>() != null || type.GetCustomAttribute <ExcludeFromCodeCoverageAttribute>() != null || CheckIfParentMemberIsExcluded(type)) { ResultsLogger.LogSessionItem($"Excluded class (ExcludeFromCoverage): {className}", LogVerbosityLevel.Verbose); if (m_ExcludedTypes == null) { m_ExcludedTypes = new List <string>(); } m_ExcludedTypes.Add(type.FullName); continue; } } catch { ResultsLogger.Log(ResultID.Warning_ExcludeAttributeClass, className, assemblyName); } ResultsLogger.LogSessionItem($"Processing included class: {className}", LogVerbosityLevel.Info); CoveredMethodStats[] classMethodStatsArray = Coverage.GetStatsFor(type); if (classMethodStatsArray.Length > 0) { List <Method> coveredMethods = new List <Method>(); foreach (CoveredMethodStats classMethodStats in classMethodStatsArray) { MethodBase method = classMethodStats.method; if (method == null) { continue; } string methodName = method.Name; ResultsLogger.LogSessionItem($"Processing method: {methodName}", LogVerbosityLevel.Verbose); try { if (method.GetCustomAttribute <ExcludeFromCoverageAttribute>() != null || method.GetCustomAttribute <ExcludeFromCodeCoverageAttribute>() != null || CheckIfParentMemberIsExcluded(method)) { ResultsLogger.LogSessionItem($"Excluded method (ExcludeFromCoverage): {methodName}", LogVerbosityLevel.Verbose); if (m_ExcludedMethods == null) { m_ExcludedMethods = new List <MethodBase>(); } m_ExcludedMethods.Add(method); continue; } } catch { ResultsLogger.Log(ResultID.Warning_ExcludeAttributeMethod, methodName, className, assemblyName); } if (IsGetterSetterPropertyExcluded(method, type)) { ResultsLogger.LogSessionItem($"Excluded method (ExcludeFromCoverage): {methodName}", LogVerbosityLevel.Verbose); continue; } if (classMethodStats.totalSequencePoints > 0) { List <SequencePoint> coveredSequencePoints = new List <SequencePoint>(); uint fileId = 0; CoveredSequencePoint[] classMethodSequencePointsArray = Coverage.GetSequencePointsFor(method); foreach (CoveredSequencePoint classMethodSequencePoint in classMethodSequencePointsArray) { string filename = classMethodSequencePoint.filename; if (filesNotFound.Contains(filename) || !m_ReporterFilter.ShouldProcessFile(filename)) { ResultsLogger.LogSessionItem($"Excluded method (Path Filtering): {methodName}", LogVerbosityLevel.Verbose); continue; } if (!fileList.TryGetValue(filename, out fileId)) { if (!File.Exists(filename)) { filesNotFound.Add(filename); continue; } else { fileId = ++fileUID; fileList.Add(filename, fileId); } } SequencePoint coveredSequencePoint = new SequencePoint(); coveredSequencePoint.FileId = fileId; coveredSequencePoint.StartLine = (int)classMethodSequencePoint.line; coveredSequencePoint.StartColumn = (int)classMethodSequencePoint.column; coveredSequencePoint.EndLine = (int)classMethodSequencePoint.line; coveredSequencePoint.EndColumn = (int)classMethodSequencePoint.column; coveredSequencePoint.VisitCount = (int)classMethodSequencePoint.hitCount; coveredSequencePoint.Offset = (int)classMethodSequencePoint.ilOffset; coveredSequencePoints.Add(coveredSequencePoint); } if (coveredSequencePoints.Count > 0) { Method coveredMethod = new Method(); coveredMethod.MetadataToken = method.MetadataToken; coveredMethod.FullName = GenerateMethodName(method); coveredMethod.FileRef = new FileRef() { UniqueId = fileId }; coveredMethod.IsConstructor = IsConstructor(method) || IsStaticConstructor(method); coveredMethod.IsStatic = method.IsStatic; coveredMethod.IsSetter = IsPropertySetter(method); coveredMethod.IsGetter = IsPropertyGetter(method); coveredMethod.SequencePoints = coveredSequencePoints.ToArray(); if (shouldGenerateAdditionalMetrics) { coveredMethod.CyclomaticComplexity = method.CalculateCyclomaticComplexity(); } ResultsLogger.LogSessionItem($"Processing included method: {coveredMethod.FullName}", LogVerbosityLevel.Verbose); coveredMethods.Add(coveredMethod); } } } if (coveredMethods.Count > 0) { Class coveredClass = new Class(); coveredClass.FullName = GenerateTypeName(type); coveredClass.Methods = coveredMethods.ToArray(); coveredClasses.Add(coveredClass); } } } if (coveredClasses.Count != 0) { Module module = new Module(); module.ModuleName = assembly.GetName().Name; List <ModelFile> coveredFileList = new List <ModelFile>(); foreach (KeyValuePair <string, UInt32> fileEntry in fileList) { ModelFile coveredFile = new ModelFile(); coveredFile.FullPath = CoverageUtils.NormaliseFolderSeparators(fileEntry.Key); if (CommandLineManager.instance.pathStrippingSpecified) { coveredFile.FullPath = CommandLineManager.instance.pathStripping.StripPath(coveredFile.FullPath); } coveredFile.UniqueId = fileEntry.Value; coveredFileList.Add(coveredFile); } module.Files = coveredFileList.ToArray(); module.Classes = coveredClasses.ToArray(); moduleList.Add(module); } } if (moduleList.Count > 0) { coverageSession = new CoverageSession(); coverageSession.Modules = moduleList.ToArray(); ProcessGenericMethods(coverageSession); foreach (Module coveredModule in moduleList) { foreach (Class coveredClass in coveredModule.Classes) { foreach (Method coveredMethod in coveredClass.Methods) { UpdateMethodSummary(coveredMethod); } UpdateClassSummary(coveredClass); } UpdateModuleSummary(coveredModule); } UpdateSessionSummary(coverageSession); } ResultsLogger.LogSessionItem("Finished OpenCover Session", LogVerbosityLevel.Info); return(coverageSession); }
public void PersistModule(Module module) { if (module == null) return; module.Classes = module.Classes ?? new Class[0]; if (CommandLine.MergeByHash) { var modules = CoverageSession.Modules ?? new Module[0]; var existingModule = modules.FirstOrDefault(x => x.ModuleHash == module.ModuleHash); if (existingModule!=null) { if (!existingModule.Aliases.Any(x=>x.Equals(module.FullName, StringComparison.InvariantCultureIgnoreCase))) { existingModule.Aliases.Add(module.FullName); } return; } } _moduleMethodMap[module] = new Dictionary<int, KeyValuePair<Class, Method>>(); foreach(var @class in module.Classes) { foreach (var method in @class.Methods) { _moduleMethodMap[module][method.MetadataToken] = new KeyValuePair<Class, Method>(@class, method); } } var list = new List<Module>(CoverageSession.Modules ?? new Module[0]) { module }; CoverageSession.Modules = list.ToArray(); }
private Module CreateModule(bool full) { var hash = string.Empty; if (System.IO.File.Exists(_symbolManager.ModulePath)) { hash = HashFile(_symbolManager.ModulePath); } var module = new Module { ModuleName = _symbolManager.ModuleName, FullName = _symbolManager.ModulePath, ModuleHash = hash }; module.Aliases.Add(_symbolManager.ModulePath); if (full) { module.Files = _symbolManager.GetFiles(); module.Classes = _symbolManager.GetInstrumentableTypes(); foreach (var @class in module.Classes) { BuildClassModel(@class, module.Files); } } return module; }
public Module BuildModuleTestModel(Module module, bool full) { module = module ?? CreateModule(full); module.TrackedMethods = _symbolManager.GetTrackedMethods(); return module; }
private void BuildMethodMapForModule(Module module) { _moduleMethodMap[module] = new Dictionary<int, KeyValuePair<Class, Method>>(); foreach (var @class in module.Classes) { foreach (var method in @class.Methods) { _moduleMethodMap[module][method.MetadataToken] = new KeyValuePair<Class, Method>(@class, method); } } }
/// <summary> /// initialise a coverage session /// </summary> public CoverageSession() { Modules = new Module[0]; Summary = new Summary(); }
/// <summary> /// initialise a coverage session /// </summary> public CoverageSession() { Modules = new Module[0]; Summary = new Summary(); _version = GetType().Assembly.GetName().Version.ToString(); }
public void PersistModule(Module module) { if (module == null) return; module.Classes = module.Classes ?? new Class[0]; if (_commandLine.MergeByHash) { var modules = CoverageSession.Modules ?? new Module[0]; var existingModule = modules.FirstOrDefault(x => x.ModuleHash == module.ModuleHash); if (existingModule!=null) { if (!existingModule.Aliases.Any(x=>x.Equals(module.FullName, StringComparison.InvariantCultureIgnoreCase))) { existingModule.Aliases.Add(module.FullName); } return; } } var list = new List<Module>(CoverageSession.Modules ?? new Module[0]) { module }; CoverageSession.Modules = list.ToArray(); }
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 void ProcessModuleData(Module module) { AddPoints(CoverageSession.Summary, module.Summary); CalculateCoverage(module.Summary); if (CoverageSession.Summary.MinCyclomaticComplexity == 0) CoverageSession.Summary.MinCyclomaticComplexity = module.Summary.MinCyclomaticComplexity; CoverageSession.Summary.MinCyclomaticComplexity = Math.Min(CoverageSession.Summary.MinCyclomaticComplexity, module.Summary.MinCyclomaticComplexity); CoverageSession.Summary.MaxCyclomaticComplexity = Math.Max(CoverageSession.Summary.MaxCyclomaticComplexity, module.Summary.MaxCyclomaticComplexity); }
private void UpdateModuleSummary(Module coveredModule) { UpdateSummary(coveredModule.Summary, coveredModule.Classes); }
public ModuleNode(Module module) { _module = module; LazyLoading = true; }
/// <summary> /// initialise a coverage session /// </summary> public CoverageSession() { Modules = new Module[0]; }