< Summary

Information
Class: NexusLabs.Needlr.Generators.DocumentationCommentHelper
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/DocumentationCommentHelper.cs
Line coverage
94%
Covered lines: 37
Uncovered lines: 2
Coverable lines: 39
Total lines: 97
Line coverage: 94.8%
Branch coverage
90%
Covered branches: 20
Total branches: 22
Branch coverage: 90.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetParameterDocumentation(...)83.33%66100%
GetSummaryDocumentation(...)100%44100%
TryParseDocumentation(...)100%2271.42%
GetNormalizedElementContent(...)75%44100%
NormalizeWhitespace(...)100%66100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/DocumentationCommentHelper.cs

#LineLine coverage
 1using System.Linq;
 2using System.Text;
 3using System.Xml;
 4using System.Xml.Linq;
 5
 6using Microsoft.CodeAnalysis;
 7
 8namespace NexusLabs.Needlr.Generators;
 9
 10/// <summary>
 11/// Extracts normalized semantic content from Roslyn XML documentation comments.
 12/// </summary>
 13internal static class DocumentationCommentHelper
 14{
 15    /// <summary>
 16    /// Gets the semantic content of a named <c>param</c> element.
 17    /// </summary>
 18    internal static string? GetParameterDocumentation(
 19        ISymbol symbol,
 20        string parameterName)
 21    {
 8122        var document = TryParseDocumentation(symbol);
 8123        var parameter = document?
 8124            .Descendants("param")
 8125            .FirstOrDefault(element =>
 9426                element.Attribute("name")?.Value == parameterName);
 8127        return parameter is null
 8128            ? null
 8129            : GetNormalizedElementContent(parameter);
 30    }
 31
 32    /// <summary>
 33    /// Gets the semantic content of a symbol's <c>summary</c> element.
 34    /// </summary>
 35    internal static string? GetSummaryDocumentation(ISymbol symbol)
 36    {
 7737        var summary = TryParseDocumentation(symbol)?
 7738            .Descendants("summary")
 7739            .FirstOrDefault();
 7740        return summary is null
 7741            ? null
 7742            : GetNormalizedElementContent(summary);
 43    }
 44
 45    private static XDocument? TryParseDocumentation(ISymbol symbol)
 46    {
 15847        var xml = symbol.GetDocumentationCommentXml();
 15848        if (string.IsNullOrWhiteSpace(xml))
 15049            return null;
 50
 51        try
 52        {
 853            return XDocument.Parse(xml);
 54        }
 055        catch (XmlException)
 56        {
 057            return null;
 58        }
 859    }
 60
 61    private static string? GetNormalizedElementContent(XElement element)
 62    {
 1263        foreach (var text in element.DescendantNodesAndSelf().OfType<XText>())
 64        {
 365            text.Value = NormalizeWhitespace(text.Value);
 66        }
 67
 368        var content = string.Concat(
 369                element.Nodes()
 370                    .Select(node => node.ToString(SaveOptions.DisableFormatting)))
 371            .Trim();
 372        return content.Length == 0 ? null : content;
 73    }
 74
 75    private static string NormalizeWhitespace(string value)
 76    {
 377        var builder = new StringBuilder(value.Length);
 378        var previousWasWhitespace = false;
 79
 13880        foreach (var character in value)
 81        {
 6682            if (char.IsWhiteSpace(character))
 83            {
 784                if (!previousWasWhitespace)
 785                    builder.Append(' ');
 86
 787                previousWasWhitespace = true;
 788                continue;
 89            }
 90
 5991            builder.Append(character);
 5992            previousWasWhitespace = false;
 93        }
 94
 395        return builder.ToString();
 96    }
 97}