diff --git a/src/DotnetDocument.Tools/Handlers/ApplyDocumentHandler.cs b/src/DotnetDocument.Tools/Handlers/ApplyDocumentHandler.cs
index a4fd5b3..fc5dd0b 100644
--- a/src/DotnetDocument.Tools/Handlers/ApplyDocumentHandler.cs
+++ b/src/DotnetDocument.Tools/Handlers/ApplyDocumentHandler.cs
@@ -32,7 +32,7 @@ public class ApplyDocumentHandler : IApplyDocumentHandler
///
/// The service resolver
///
- private readonly IServiceResolver _serviceResolver;
+ private readonly IServiceResolver _strategyResolver;
///
/// The walker
@@ -49,7 +49,7 @@ public class ApplyDocumentHandler : IApplyDocumentHandler
public ApplyDocumentHandler(ILogger logger,
IServiceResolver serviceResolver,
DocumentationSyntaxWalker walker, IOptions appSettings) =>
- (_logger, _serviceResolver, _walker, _documentationSettings) =
+ (_logger, _strategyResolver, _walker, _documentationSettings) =
(logger, serviceResolver, walker, appSettings.Value);
///
@@ -73,11 +73,13 @@ public Result Apply(string? path, bool isDryRun)
var memberDocStatusList = GetFilesDocumentationStatus(files);
// Get the list of undocumented members
- var undocumentedMembers = memberDocStatusList.Where(m => m.IsDocumented is not true).ToList();
+ var undocumentedMembers = memberDocStatusList.Where(m => m.NeedsDocumentation).ToList();
foreach (var member in undocumentedMembers)
- _logger.LogInformation(" {File} (ln {Line}): {MemberType} '{MemberName}' has no document",
+ {
+ _logger.LogInformation(" {File} (ln {Line}): {MemberType} '{MemberName}' has no documentation",
member.FilePath, member.StartLine, member.Kind.ToString().Humanize(), member.Identifier);
+ }
// If is dry run
if (isDryRun)
@@ -87,7 +89,7 @@ public Result Apply(string? path, bool isDryRun)
// Don't go ahead with saving.
// If there are members without doc return `undocumented members`
- return memberDocStatusList.Any(m => m.IsDocumented is not true)
+ return memberDocStatusList.Any(m => m.NeedsDocumentation)
? Result.UndocumentedMembers
: Result.Success;
}
@@ -110,10 +112,19 @@ public Result Apply(string? path, bool isDryRun)
// Replace the
var changedSyntaxTree = root.ReplaceNodes(_walker.NodesWithoutXmlDoc,
- (node, syntaxNode) => _serviceResolver
- .Resolve(syntaxNode.Kind().ToString())
- ?
- .Apply(syntaxNode) ?? syntaxNode);
+ (originalNode, replacedNode) =>
+ {
+ var documentationAttempt = _strategyResolver
+ .Resolve(replacedNode.Kind().ToString())
+ ?.Apply(replacedNode);
+
+ if (documentationAttempt is null || documentationAttempt.Value.IsChanged is false)
+ {
+ return replacedNode;
+ }
+
+ return documentationAttempt.Value.NodeWithDocs;
+ });
// TODO: Don't write if no changes
@@ -158,19 +169,32 @@ private IEnumerable GetFileDocumentationStatus(string
_walker.Visit(root);
foreach (var node in _walker.NodesWithXmlDoc)
+ {
yield return new MemberDocumentationStatus(filePath, SyntaxUtils.FindMemberIdentifier(node),
- node.Kind(), true, null, node,
+ node.Kind(), needsDocumentation: false, nodeWithoutDocument: null, documentedNode: node,
node.GetLocation().GetLineSpan().StartLinePosition.ToString());
+ }
foreach (var node in _walker.NodesWithoutXmlDoc)
{
- var nodeWithDoc = _serviceResolver
- .Resolve(node.Kind().ToString())
- ?
- .Apply(node);
+ var documentationStrategy = _strategyResolver
+ .Resolve(node.Kind().ToString());
+
+ // If not documentation strategy found for this node type then skip it
+ if (documentationStrategy is null)
+ {
+ _logger.LogWarning("Documentation strategy is null");
+ yield break;
+ }
+
+ var (needsDocumentation, nodeWithDocs) = documentationStrategy.Apply(node);
+
+ var nodeWithoutXmlDocs = needsDocumentation ? node : null;
+ var nodeWithXmlDocs = needsDocumentation ? nodeWithDocs : node;
yield return new MemberDocumentationStatus(filePath, SyntaxUtils.FindMemberIdentifier(node),
- node.Kind(), false, node, nodeWithDoc,
+ node.Kind(), needsDocumentation: needsDocumentation, nodeWithoutDocument: nodeWithoutXmlDocs,
+ documentedNode: nodeWithXmlDocs,
node.GetLocation().GetLineSpan().StartLinePosition.ToString());
}
}
diff --git a/src/DotnetDocument.Tools/Handlers/MemberDocumentationStatus.cs b/src/DotnetDocument.Tools/Handlers/MemberDocumentationStatus.cs
index bcdbf0b..6e01015 100644
--- a/src/DotnetDocument.Tools/Handlers/MemberDocumentationStatus.cs
+++ b/src/DotnetDocument.Tools/Handlers/MemberDocumentationStatus.cs
@@ -14,17 +14,17 @@ public class MemberDocumentationStatus
/// The file path
/// The identifier
/// The kind
- /// The is documented
+ /// The is documented
/// The node without document
/// The documented node
/// The start line
- public MemberDocumentationStatus(string filePath, string identifier, SyntaxKind kind, bool isDocumented,
+ public MemberDocumentationStatus(string filePath, string identifier, SyntaxKind kind, bool needsDocumentation,
SyntaxNode? nodeWithoutDocument, SyntaxNode? documentedNode, string startLine)
{
FilePath = filePath;
Identifier = identifier;
Kind = kind;
- IsDocumented = isDocumented;
+ NeedsDocumentation = needsDocumentation;
NodeWithoutDocument = nodeWithoutDocument;
DocumentedNode = documentedNode;
StartLine = startLine;
@@ -48,7 +48,7 @@ public MemberDocumentationStatus(string filePath, string identifier, SyntaxKind
///
/// Gets or inits the value of the is documented
///
- public bool IsDocumented { get; init; }
+ public bool NeedsDocumentation { get; init; }
///
/// Gets the value of the node without document
diff --git a/src/DotnetDocument/Configuration/DocumentationOptions.cs b/src/DotnetDocument/Configuration/DocumentationOptions.cs
index 67a3f02..631117d 100644
--- a/src/DotnetDocument/Configuration/DocumentationOptions.cs
+++ b/src/DotnetDocument/Configuration/DocumentationOptions.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp;
@@ -18,6 +19,17 @@ public abstract class MemberDocumentationOptionsBase
///
public bool Required { get; init; } = true;
+ ///
+ /// Gets or sets the value of the apply on modifiers
+ ///
+ public List ApplyOnModifiers { get; set; } = new()
+ {
+ "public",
+ //"private",
+ //"internal",
+ //"protected"
+ };
+
///
/// Gets the syntax kind
///
@@ -484,28 +496,22 @@ public class DocumentationOptions
public Dictionary Verbs { get; init; } = new()
{
{
- "to",
- "returns"
+ "to", "returns"
},
{
- "from",
- "creates"
+ "from", "creates"
},
{
- "as",
- "converts"
+ "as", "converts"
},
{
- "with",
- "adds"
+ "with", "adds"
},
{
- "setup",
- "setup"
+ "setup", "setup"
},
{
- "main",
- "main"
+ "main", "main"
}
};
@@ -515,8 +521,7 @@ public class DocumentationOptions
public Dictionary Aliases { get; init; } = new()
{
{
- "sut",
- "system under test"
+ "sut", "system under test"
}
};
diff --git a/src/DotnetDocument/Strategies/Abstractions/AttributeServiceResolver.cs b/src/DotnetDocument/Strategies/Abstractions/AttributeServiceResolver.cs
index e9dfe8b..fab24d7 100644
--- a/src/DotnetDocument/Strategies/Abstractions/AttributeServiceResolver.cs
+++ b/src/DotnetDocument/Strategies/Abstractions/AttributeServiceResolver.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -9,6 +10,7 @@ namespace DotnetDocument.Strategies.Abstractions
/// The attribute service resolver class
///
///
+ [SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates")]
public class AttributeServiceResolver : IServiceResolver
{
///
@@ -45,11 +47,15 @@ public AttributeServiceResolver(IServiceProvider provider) =>
.Any(a => a.Key == key));
if (service is null)
+ {
logger.LogWarning("No {ServiceType} implementation resolved matching {KeyType} key: '{Key}'",
typeof(TService).Name, key.GetType().Name, key);
+ }
else
+ {
logger.LogTrace("Resolved implementation of {ServiceType} with key '{Key}': {ImplementationType}",
typeof(TService).Name, key, service.GetType().Name);
+ }
return service;
}
diff --git a/src/DotnetDocument/Strategies/Abstractions/DocumentationStrategyBase.cs b/src/DotnetDocument/Strategies/Abstractions/DocumentationStrategyBase.cs
index be37679..0979f4f 100644
--- a/src/DotnetDocument/Strategies/Abstractions/DocumentationStrategyBase.cs
+++ b/src/DotnetDocument/Strategies/Abstractions/DocumentationStrategyBase.cs
@@ -22,15 +22,16 @@ public abstract class DocumentationStrategyBase : IDocumentationStrategy wher
/// Applies the node
///
/// The node
- /// The syntax node
- public SyntaxNode Apply(SyntaxNode node) => Apply(node as T ?? throw new InvalidOperationException());
+ /// The bool is changed syntax node node with docs
+ public (bool IsChanged, SyntaxNode NodeWithDocs) Apply(SyntaxNode node) =>
+ Apply(node as T ?? throw new InvalidOperationException());
///
/// Applies the node
///
/// The node
- /// The
- public abstract T Apply(T node);
+ /// The bool is changed node with docs
+ public abstract (bool IsChanged, T NodeWithDocs) Apply(T node);
///
/// Gets the documentation builder
diff --git a/src/DotnetDocument/Strategies/Abstractions/IDocumentationStrategy.cs b/src/DotnetDocument/Strategies/Abstractions/IDocumentationStrategy.cs
index 64ca384..e18e0ed 100644
--- a/src/DotnetDocument/Strategies/Abstractions/IDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/Abstractions/IDocumentationStrategy.cs
@@ -15,11 +15,6 @@ public interface IDocumentationStrategy
/// An enumerable of syntax kind
IEnumerable GetSupportedKinds();
- ///
- /// Applies the node
- ///
- /// The node
- /// The syntax node
- SyntaxNode Apply(SyntaxNode node);
+ (bool IsChanged, SyntaxNode NodeWithDocs) Apply(SyntaxNode node);
}
}
diff --git a/src/DotnetDocument/Strategies/ClassDocumentationStrategy.cs b/src/DotnetDocument/Strategies/ClassDocumentationStrategy.cs
index 2a37d1a..841529d 100644
--- a/src/DotnetDocument/Strategies/ClassDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/ClassDocumentationStrategy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using DotnetDocument.Configuration;
@@ -55,9 +56,11 @@ public override IEnumerable GetSupportedKinds() => new[]
/// Applies the node
///
/// The node
- /// The class declaration syntax
- public override ClassDeclarationSyntax Apply(ClassDeclarationSyntax node)
+ /// The bool is changed class declaration syntax node with docs
+ public override (bool IsChanged, ClassDeclarationSyntax NodeWithDocs) Apply(ClassDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
// Retrieve class name
var className = node.Identifier.Text;
@@ -82,7 +85,7 @@ public override ClassDeclarationSyntax Apply(ClassDeclarationSyntax node)
builder.WithSeeAlso(baseTypes);
}
- return builder.Build();
+ return (true, builder.Build());
}
}
}
diff --git a/src/DotnetDocument/Strategies/ConstructorDocumentationStrategy.cs b/src/DotnetDocument/Strategies/ConstructorDocumentationStrategy.cs
index 0c763e6..f89ec84 100644
--- a/src/DotnetDocument/Strategies/ConstructorDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/ConstructorDocumentationStrategy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using DotnetDocument.Configuration;
@@ -55,16 +56,20 @@ public override IEnumerable GetSupportedKinds() => new[]
/// Applies the node
///
/// The node
- /// The constructor declaration syntax
- public override ConstructorDeclarationSyntax Apply(ConstructorDeclarationSyntax node)
+ /// The bool is changed constructor declaration syntax node with docs
+ public override (bool IsChanged, ConstructorDeclarationSyntax NodeWithDocs) Apply(
+ ConstructorDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
// Retrieve constructor name
var ctorName = SyntaxUtils.ExtractClassName(node);
// Declare the summary by using the template from configuration
var summary = new List
{
- _options.Summary.Template.Replace(TemplateKeys.Name, $"<<{ctorName}>>")
+ _options.Summary.Template.Replace(TemplateKeys.Name, $"<<{ctorName}>>",
+ StringComparison.InvariantCulture)
};
var exceptions = new List<(string, string)>();
@@ -97,12 +102,14 @@ public override ConstructorDeclarationSyntax Apply(ConstructorDeclarationSyntax
.Select(p => (p, _formatter
.FormatName(_options.Parameters.Template, (TemplateKeys.Name, p))));
- return GetDocumentationBuilder()
+ var nodeWithDocs = GetDocumentationBuilder()
.For(node)
.WithSummary(summary.ToArray())
.WithParams(@params)
.WithExceptions(exceptions.ToArray())
.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Strategies/DefaultDocumentationStrategy.cs b/src/DotnetDocument/Strategies/DefaultDocumentationStrategy.cs
index 0099176..eabfab6 100644
--- a/src/DotnetDocument/Strategies/DefaultDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/DefaultDocumentationStrategy.cs
@@ -1,4 +1,6 @@
+using System;
using System.Collections.Generic;
+using System.Linq;
using DotnetDocument.Configuration;
using DotnetDocument.Format;
using DotnetDocument.Strategies.Abstractions;
@@ -65,8 +67,18 @@ public override IEnumerable GetSupportedKinds() => new[]
///
/// The node
/// The member declaration syntax
- public override MemberDeclarationSyntax Apply(MemberDeclarationSyntax node)
+ public override (bool IsChanged, MemberDeclarationSyntax NodeWithDocs) Apply(MemberDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
+ var memberModifiers = node.Modifiers.Select(m => m.Text);
+ var allowedModifiers = _options.ApplyOnModifiers;
+
+ if (memberModifiers.Any(m => allowedModifiers.Contains(m)) is false)
+ {
+ return (false, node);
+ }
+
// Retrieve member name
var name = SyntaxUtils.FindMemberIdentifier(node);
@@ -77,10 +89,12 @@ public override MemberDeclarationSyntax Apply(MemberDeclarationSyntax node)
(TemplateKeys.Name, name))
};
- return GetDocumentationBuilder()
+ var nodeWithDocs = GetDocumentationBuilder()
.For(node)
.WithSummary(summary.ToArray())
.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Strategies/EnumDocumentationStrategy.cs b/src/DotnetDocument/Strategies/EnumDocumentationStrategy.cs
index 08cd3f3..e2fd34c 100644
--- a/src/DotnetDocument/Strategies/EnumDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/EnumDocumentationStrategy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using DotnetDocument.Configuration;
using DotnetDocument.Format;
@@ -54,8 +55,10 @@ public override IEnumerable GetSupportedKinds() => new[]
///
/// The node
/// The enum declaration syntax
- public override EnumDeclarationSyntax Apply(EnumDeclarationSyntax node)
+ public override (bool IsChanged, EnumDeclarationSyntax NodeWithDocs) Apply(EnumDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
// Retrieve class name
var enumName = node.Identifier.Text;
@@ -65,10 +68,12 @@ public override EnumDeclarationSyntax Apply(EnumDeclarationSyntax node)
_formatter.FormatName(_options.Summary.Template, (TemplateKeys.Name, enumName))
};
- return GetDocumentationBuilder()
+ var nodeWithDocs = GetDocumentationBuilder()
.For(node)
.WithSummary(summary.ToArray())
.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Strategies/EnumMemberDocumentationStrategy.cs b/src/DotnetDocument/Strategies/EnumMemberDocumentationStrategy.cs
index 1b41999..47dd700 100644
--- a/src/DotnetDocument/Strategies/EnumMemberDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/EnumMemberDocumentationStrategy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using DotnetDocument.Configuration;
using DotnetDocument.Format;
@@ -54,8 +55,11 @@ public override IEnumerable GetSupportedKinds() => new[]
///
/// The node
/// The enum member declaration syntax
- public override EnumMemberDeclarationSyntax Apply(EnumMemberDeclarationSyntax node)
+ public override (bool IsChanged, EnumMemberDeclarationSyntax NodeWithDocs) Apply(
+ EnumMemberDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
// Retrieve class name
var enumMemberName = node.Identifier.Text;
var enumName = string.Empty;
@@ -70,10 +74,12 @@ public override EnumMemberDeclarationSyntax Apply(EnumMemberDeclarationSyntax no
(TemplateKeys.EnumName, enumName))
};
- return GetDocumentationBuilder()
+ var nodeWithDocs = GetDocumentationBuilder()
.For(node)
.WithSummary(summary.ToArray())
.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Strategies/InterfaceDocumentationStrategy.cs b/src/DotnetDocument/Strategies/InterfaceDocumentationStrategy.cs
index 85bf8b2..543d415 100644
--- a/src/DotnetDocument/Strategies/InterfaceDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/InterfaceDocumentationStrategy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using DotnetDocument.Configuration;
@@ -56,8 +57,10 @@ public override IEnumerable GetSupportedKinds() => new[]
///
/// The node
/// The interface declaration syntax
- public override InterfaceDeclarationSyntax Apply(InterfaceDeclarationSyntax node)
+ public override (bool IsChanged, InterfaceDeclarationSyntax NodeWithDocs) Apply(InterfaceDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
// Retrieve class name
var interfaceName = node.Identifier.Text;
@@ -81,7 +84,9 @@ public override InterfaceDeclarationSyntax Apply(InterfaceDeclarationSyntax node
builder.WithSeeAlso(baseTypes);
}
- return builder.Build();
+ var nodeWithDocs = builder.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Strategies/MethodDocumentationStrategy.cs b/src/DotnetDocument/Strategies/MethodDocumentationStrategy.cs
index d57b7b7..4f4a13e 100644
--- a/src/DotnetDocument/Strategies/MethodDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/MethodDocumentationStrategy.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using DotnetDocument.Configuration;
@@ -57,8 +58,18 @@ public override IEnumerable GetSupportedKinds() => new[]
///
/// The node
/// The method declaration syntax
- public override MethodDeclarationSyntax Apply(MethodDeclarationSyntax node)
+ public override (bool IsChanged, MethodDeclarationSyntax NodeWithDocs) Apply(MethodDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
+ var memberModifiers = node.Modifiers.Select(m => m.Text);
+ var allowedModifiers = _options.ApplyOnModifiers;
+
+ if (memberModifiers.Any(m => allowedModifiers.Contains(m)) is false)
+ {
+ return (false, node);
+ }
+
// Get the doc builder for this node
var builder = GetDocumentationBuilder()
.For(node);
@@ -75,6 +86,7 @@ public override MethodDeclarationSyntax Apply(MethodDeclarationSyntax node)
var returns = string.Empty;
if (node.Body is not null)
+ {
// Extract the last return statement which returns a variable
// and humanize the name of the variable which will be used as
// returns descriptions. Empty otherwise.
@@ -83,6 +95,7 @@ public override MethodDeclarationSyntax Apply(MethodDeclarationSyntax node)
.Select(r => _formatter
.FormatName(_options.Returns.Template, (TemplateKeys.Name, r)))
.LastOrDefault();
+ }
// TODO: Handle case where node.ExpressionBody is not null
@@ -156,10 +169,12 @@ public override MethodDeclarationSyntax Apply(MethodDeclarationSyntax node)
}
}
- return builder
+ var nodeWithDocs = builder
.WithTypeParams(typeParams)
.WithParams(@params)
.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Strategies/PropertyDocumentationStrategy.cs b/src/DotnetDocument/Strategies/PropertyDocumentationStrategy.cs
index 7f7dd44..6b66b77 100644
--- a/src/DotnetDocument/Strategies/PropertyDocumentationStrategy.cs
+++ b/src/DotnetDocument/Strategies/PropertyDocumentationStrategy.cs
@@ -1,4 +1,6 @@
+using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using DotnetDocument.Configuration;
using DotnetDocument.Format;
@@ -15,6 +17,7 @@ namespace DotnetDocument.Strategies
///
///
[Strategy(nameof(SyntaxKind.PropertyDeclaration))]
+ [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase")]
public class PropertyDocumentationStrategy : DocumentationStrategyBase
{
///
@@ -56,13 +59,23 @@ public override IEnumerable GetSupportedKinds() => new[]
///
/// The node
/// The property declaration syntax
- public override PropertyDeclarationSyntax Apply(PropertyDeclarationSyntax node)
+ public override (bool IsChanged, PropertyDeclarationSyntax NodeWithDocs) Apply(PropertyDeclarationSyntax node)
{
+ ArgumentNullException.ThrowIfNull(node);
+
+ var memberModifiers = node.Modifiers.Select(m => m.Text);
+ var allowedModifiers = _options.ApplyOnModifiers;
+
+ if (memberModifiers.Any(m => allowedModifiers.Contains(m)) is false)
+ {
+ return (false, node);
+ }
+
// Retrieve constructor name
var propertyName = node.Identifier.Text;
// Humanize the constructor name
- var humanizedPropertyName = propertyName.Humanize().ToLower();
+ var humanizedPropertyName = propertyName.Humanize().ToLowerInvariant();
var accessorsDescription = "";
@@ -71,18 +84,22 @@ public override PropertyDeclarationSyntax Apply(PropertyDeclarationSyntax node)
.ToList();
if (accessors is not null && accessors.Any())
+ {
accessorsDescription = string.Join(" or ", accessors)
- .ToLower()
+ .ToLowerInvariant()
.Humanize();
+ }
else
+ {
accessorsDescription = _formatter.ConjugateThirdPersonSingular("Get");
+ }
var summary = new List
{
// Declare the summary by using the template from configuration
_options.Summary.Template
- .Replace(TemplateKeys.Accessors, accessorsDescription)
- .Replace(TemplateKeys.Name, humanizedPropertyName)
+ .Replace(TemplateKeys.Accessors, accessorsDescription, StringComparison.InvariantCulture)
+ .Replace(TemplateKeys.Name, humanizedPropertyName, StringComparison.InvariantCulture)
};
// Check if constructor has an expression body => {...}
@@ -90,10 +107,12 @@ public override PropertyDeclarationSyntax Apply(PropertyDeclarationSyntax node)
{
}
- return GetDocumentationBuilder()
+ var nodeWithDocs = GetDocumentationBuilder()
.For(node)
.WithSummary(summary.ToArray())
.Build();
+
+ return (true, nodeWithDocs);
}
}
}
diff --git a/src/DotnetDocument/Syntax/SyntaxUtils.cs b/src/DotnetDocument/Syntax/SyntaxUtils.cs
index f88da92..ad52153 100644
--- a/src/DotnetDocument/Syntax/SyntaxUtils.cs
+++ b/src/DotnetDocument/Syntax/SyntaxUtils.cs
@@ -104,8 +104,10 @@ public static string FindMemberIdentifier(SyntaxNode node)
public static IEnumerable ExtractBaseTypes(ClassDeclarationSyntax classDeclarationSyntax)
{
if (classDeclarationSyntax.BaseList is not null)
+ {
return classDeclarationSyntax.BaseList.Types
.Select(t => t.Type.ToString().Replace("<", "{").Replace(">", "}").Trim());
+ }
return new List();
}
@@ -137,8 +139,10 @@ public static string ExtractClassName(ConstructorDeclarationSyntax constructorDe
public static IEnumerable ExtractBaseTypes(InterfaceDeclarationSyntax interfaceDeclarationSyntax)
{
if (interfaceDeclarationSyntax.BaseList is not null)
+ {
return interfaceDeclarationSyntax.BaseList.Types
.Select(t => t.Type.ToString().Replace("<", "{").Replace(">", "}").Trim());
+ }
return new List();
}
@@ -276,8 +280,10 @@ public static IEnumerable ExtractReturnStatements(BlockSyntax body)
if (body is null) yield break;
foreach (var returnStatement in body.Statements.OfType())
+ {
if (returnStatement.Expression is IdentifierNameSyntax identifierName)
yield return identifierName.Identifier.Text;
+ }
}
///
diff --git a/src/DotnetDocument/Utils/EnglishUtils.cs b/src/DotnetDocument/Utils/EnglishUtils.cs
index 7139c7a..6c9525e 100644
--- a/src/DotnetDocument/Utils/EnglishUtils.cs
+++ b/src/DotnetDocument/Utils/EnglishUtils.cs
@@ -18,7 +18,9 @@ public static string ConjugateToThirdPersonSingular(string verb)
// Check if verb ends with one of the following chars
if (verb.EndsWith("ch") || verb.EndsWith("s") || verb.EndsWith("sh") ||
verb.EndsWith("x") || verb.EndsWith("z") || verb.EndsWith("o"))
+ {
return $"{verb}es";
+ }
// Check if verb is at least 3 chars long, ends with a consonant then y
if (verb.Length > 2 && verb.Last() == 'y' && verb[^2].IsConsonant()) return $"{verb.RemoveEnd("y")}ies";
diff --git a/test/DotnetDocument.Tests/Strategies/ClassDocumentationStrategyTests.cs b/test/DotnetDocument.Tests/Strategies/ClassDocumentationStrategyTests.cs
index 600d5af..a66432f 100644
--- a/test/DotnetDocument.Tests/Strategies/ClassDocumentationStrategyTests.cs
+++ b/test/DotnetDocument.Tests/Strategies/ClassDocumentationStrategyTests.cs
@@ -34,10 +34,11 @@ public void ShouldDocument(string uncommentedCode, string expectedCommentedCode)
new ClassDocumentationOptions());
// Act
- var documentedSyntax = strategy.Apply(classDeclarationSyntax);
+ var documentationAttempt = strategy.Apply(classDeclarationSyntax);
// Assert
- documentedSyntax.ToFullString().ShouldBe(expectedCommentedCode);
+ documentationAttempt.IsChanged.ShouldBe(true);
+ documentationAttempt.NodeWithDocs.ToFullString().ShouldBe(expectedCommentedCode);
}
}
}
diff --git a/test/DotnetDocument.Tests/Strategies/ConstructorStrategyTestsBase.cs b/test/DotnetDocument.Tests/Strategies/ConstructorStrategyTestsBase.cs
index d8f1cfd..169a9fa 100644
--- a/test/DotnetDocument.Tests/Strategies/ConstructorStrategyTestsBase.cs
+++ b/test/DotnetDocument.Tests/Strategies/ConstructorStrategyTestsBase.cs
@@ -52,10 +52,11 @@ public void ShouldDocument(string uncommentedCode, string expectedCommentedCode)
options);
// Act
- var documentedSyntax = strategy.Apply(ctorDeclarationSyntax);
+ var documentationAttempt = strategy.Apply(ctorDeclarationSyntax);
// Assert
- documentedSyntax.ToFullString().Trim().ShouldBe(expectedCommentedCode.Trim());
+ documentationAttempt.IsChanged.ShouldBe(true);
+ documentationAttempt.NodeWithDocs.ToFullString().Trim().ShouldBe(expectedCommentedCode.Trim());
}
}
}