From 4527e0a7a9f8aaf8fa8457e437aa6e121adcebbc Mon Sep 17 00:00:00 2001 From: danielpalme Date: Thu, 2 Feb 2023 18:56:30 +0100 Subject: [PATCH] #536: Improved support for C code in Visual Studio coverage input format (*.coveragexml) --- src/Readme.txt | 1 + .../DynamicCodeCoverageReportPreprocessor.cs | 37 +++++++++++++++++++ .../Builders/Rendering/HtmlRenderer.cs | 3 +- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/Readme.txt b/src/Readme.txt index 81e7a019..a32236c9 100644 --- a/src/Readme.txt +++ b/src/Readme.txt @@ -68,6 +68,7 @@ CHANGELOG 5.1.16.0 + * Fix: #536: Improved support for C code in Visual Studio coverage input format (*.coveragexml) * Fix: #585: Improved merging of results in SonarQube output format 5.1.15.0 diff --git a/src/ReportGenerator.Core/Parser/Preprocessing/DynamicCodeCoverageReportPreprocessor.cs b/src/ReportGenerator.Core/Parser/Preprocessing/DynamicCodeCoverageReportPreprocessor.cs index e6aa9ef0..b407cfcb 100644 --- a/src/ReportGenerator.Core/Parser/Preprocessing/DynamicCodeCoverageReportPreprocessor.cs +++ b/src/ReportGenerator.Core/Parser/Preprocessing/DynamicCodeCoverageReportPreprocessor.cs @@ -18,6 +18,7 @@ internal void Execute(XContainer report) foreach (var module in report.Descendants("module").ToArray()) { ApplyClassNameToStartupCodeElements(module); + AddMissingTypeNames(module); } } @@ -116,5 +117,41 @@ private static void ApplyClassNameToStartupCodeElements(XElement module) } } } + + /// + /// Applies type names to funtions with empty 'type_name' attribute. + /// + /// The module. + private static void AddMissingTypeNames(XElement module) + { + var functionsWithoutTypeNameInModule = module + .Elements("functions") + .Elements("function") + .Where(c => c.Attribute("type_name").Value == string.Empty) + .ToArray(); + + if (functionsWithoutTypeNameInModule.LongLength > 0) + { + var classNamesBySoureFileId = module + .Elements("source_files") + .Elements("source_file") + .ToDictionary(e => e.Attribute("id").Value, e => + { + string path = e.Attribute("path").Value.Replace("/", "\\"); + + return path.Substring(path.LastIndexOf('\\') + 1); + }); + + foreach (var function in functionsWithoutTypeNameInModule) + { + string firstSourceId = function.Elements("ranges").Elements("range").FirstOrDefault()?.Attribute("source_id").Value; + + if (firstSourceId != null && classNamesBySoureFileId.TryGetValue(firstSourceId, out string className)) + { + function.Attribute("type_name").Value = className; + } + } + } + } } } diff --git a/src/ReportGenerator.Core/Reporting/Builders/Rendering/HtmlRenderer.cs b/src/ReportGenerator.Core/Reporting/Builders/Rendering/HtmlRenderer.cs index 42fe9584..0d2b8d4d 100644 --- a/src/ReportGenerator.Core/Reporting/Builders/Rendering/HtmlRenderer.cs +++ b/src/ReportGenerator.Core/Reporting/Builders/Rendering/HtmlRenderer.cs @@ -762,7 +762,8 @@ public void MetricsTable(Class @class) .SelectMany(f => f.MethodMetrics) .SelectMany(m => m.Metrics) .Distinct() - .OrderBy(m => m.Name); + .OrderBy(m => m.Name) + .ToArray(); this.reportTextWriter.WriteLine("
"); this.reportTextWriter.WriteLine("");