From 8278973bdbe73dbdb9f59b00f4ac23afde0c4d5e Mon Sep 17 00:00:00 2001 From: danielpalme Date: Sun, 15 Oct 2023 16:27:07 +0200 Subject: [PATCH] #629 Visual Studio Coverage: Added support for partial line coverage --- .../Parser/Analysis/FlagsLineVisitStatus.cs | 31 ++++++++++++++++ .../Parser/VisualStudioParser.cs | 35 +++++++++++++------ 2 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 src/ReportGenerator.Core/Parser/Analysis/FlagsLineVisitStatus.cs diff --git a/src/ReportGenerator.Core/Parser/Analysis/FlagsLineVisitStatus.cs b/src/ReportGenerator.Core/Parser/Analysis/FlagsLineVisitStatus.cs new file mode 100644 index 00000000..e284b8f1 --- /dev/null +++ b/src/ReportGenerator.Core/Parser/Analysis/FlagsLineVisitStatus.cs @@ -0,0 +1,31 @@ +using System; + +namespace Palmmedia.ReportGenerator.Core.Parser.Analysis +{ + /// + /// Indicates the coverage status of a line in a source file. + /// + [Flags] + internal enum FlagsLineVisitStatus + { + /// + /// Line can not be covered. + /// + NotCoverable = 0, + + /// + /// Line was not covered. + /// + NotCovered = 1, + + /// + /// Line was partially covered. + /// + PartiallyCovered = 2, + + /// + /// Line was covered. + /// + Covered = 4 + } +} diff --git a/src/ReportGenerator.Core/Parser/VisualStudioParser.cs b/src/ReportGenerator.Core/Parser/VisualStudioParser.cs index 231017ec..a7999065 100644 --- a/src/ReportGenerator.Core/Parser/VisualStudioParser.cs +++ b/src/ReportGenerator.Core/Parser/VisualStudioParser.cs @@ -16,7 +16,7 @@ namespace Palmmedia.ReportGenerator.Core.Parser /// /// Parser for XML reports generated by Visual Studio. /// - internal class VisualStudioParser : ParserBase + internal partial class VisualStudioParser : ParserBase { /// /// The Logger. @@ -203,11 +203,13 @@ private static CodeFile ProcessFile(XElement[] modules, string fileId, Class @cl int[] coverage = new int[] { }; LineVisitStatus[] lineVisitStatus = new LineVisitStatus[] { }; + FlagsLineVisitStatus[] flagsLineVisitStatus = new FlagsLineVisitStatus[] { }; if (linesOfFile.Length > 0) { coverage = new int[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1]; lineVisitStatus = new LineVisitStatus[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1]; + flagsLineVisitStatus = new FlagsLineVisitStatus[linesOfFile[linesOfFile.LongLength - 1].LineNumberEnd + 1]; for (int i = 0; i < coverage.Length; i++) { @@ -223,25 +225,36 @@ private static CodeFile ProcessFile(XElement[] modules, string fileId, Class @cl if (seqpnt.Coverage == 2) { - if (lineVisitStatus[lineNumber] == LineVisitStatus.NotCoverable) - { - lineVisitStatus[lineNumber] = LineVisitStatus.NotCovered; - } + flagsLineVisitStatus[lineNumber] |= FlagsLineVisitStatus.NotCovered; } else if (seqpnt.Coverage == 1) { - if (lineVisitStatus[lineNumber] == LineVisitStatus.NotCoverable - || lineVisitStatus[lineNumber] == LineVisitStatus.NotCovered) - { - lineVisitStatus[lineNumber] = LineVisitStatus.PartiallyCovered; - } + flagsLineVisitStatus[lineNumber] |= FlagsLineVisitStatus.PartiallyCovered; } else if (seqpnt.Coverage == 0) { - lineVisitStatus[lineNumber] = LineVisitStatus.Covered; + flagsLineVisitStatus[lineNumber] |= FlagsLineVisitStatus.Covered; } } } + + for (int i = 0; i < coverage.Length; i++) + { + if ((int)flagsLineVisitStatus[i] == (int)FlagsLineVisitStatus.Covered) + { + lineVisitStatus[i] = LineVisitStatus.Covered; + } + else if ((int)flagsLineVisitStatus[i] == (int)FlagsLineVisitStatus.NotCovered) + { + lineVisitStatus[i] = LineVisitStatus.NotCovered; + } + else if (flagsLineVisitStatus[i].HasFlag(FlagsLineVisitStatus.PartiallyCovered) + || (flagsLineVisitStatus[i].HasFlag(FlagsLineVisitStatus.Covered) + && flagsLineVisitStatus[i].HasFlag(FlagsLineVisitStatus.NotCovered))) + { + lineVisitStatus[i] = LineVisitStatus.PartiallyCovered; + } + } } var codeFile = new CodeFile(filePath, coverage, lineVisitStatus);