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); }