Skip to content

Commit ff5c432

Browse files
authored
Merge pull request DotNetAnalyzers#3861 from MattFromRVA/SA1642_Fix
SA1642: Allow <para> Tags in Constructor Documentation
2 parents 51c772e + df78311 commit ff5c432

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1642UnitTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,36 @@ public ClassName()
10611061
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
10621062
}
10631063

1064+
[Fact]
1065+
[WorkItem(3575, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3575")]
1066+
public async Task TestConstructorSummaryWithParaTagsAsync()
1067+
{
1068+
var testCode = @"
1069+
using System;
1070+
/// <summary>
1071+
/// Does a thing.
1072+
/// </summary>
1073+
public class B
1074+
{
1075+
/// <summary>
1076+
/// <para>
1077+
/// Initializes a new instance of the <see cref=""B""/> class.
1078+
/// </para>
1079+
/// <para>
1080+
/// Some more info about B.
1081+
/// </para>
1082+
/// </summary>
1083+
public B()
1084+
{
1085+
}
1086+
}
1087+
";
1088+
1089+
var expectedDiagnostics = DiagnosticResult.EmptyDiagnosticResults;
1090+
1091+
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, testCode, CancellationToken.None).ConfigureAwait(false);
1092+
}
1093+
10641094
private static async Task TestEmptyConstructorAsync(string typeKind, string modifiers)
10651095
{
10661096
var testCode = @"namespace FooNamespace

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/StandardTextDiagnosticBase.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,26 @@ protected static MatchResult HandleDeclaration(SyntaxNodeAnalysisContext context
122122
diagnosticLocation = summaryElement.GetLocation();
123123
diagnosticProperties = ImmutableDictionary.Create<string, string>();
124124

125+
// Handle empty or whitespace-only summary content
126+
var firstElementWithContent = XmlCommentHelper.TryGetFirstTextElementWithContent(summaryElement);
127+
if (firstElementWithContent == null)
128+
{
129+
// Report the diagnostic for empty or whitespace-only summaries
130+
if (diagnosticDescriptor != null)
131+
{
132+
context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, diagnosticLocation, diagnosticProperties));
133+
}
134+
135+
return MatchResult.None;
136+
}
137+
138+
// Check if the summary content starts with a <para> tag
139+
if (firstElementWithContent != null && firstElementWithContent.Parent is XmlElementSyntax firstElement && firstElement.StartTag.Name.ToString() == "para")
140+
{
141+
// We found a correct standard text
142+
return MatchResult.FoundMatch;
143+
}
144+
125145
// Check if the summary content could be a correct standard text
126146
if (summaryElement.Content.Count >= 3)
127147
{

documentation/SA1642.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,23 @@ private Customer()
9696
}
9797
```
9898

99+
The `<para>` tag can be used within the `<summary>` tag to structure the text.
100+
For example:
101+
102+
```csharp
103+
/// <summary>
104+
/// <para>
105+
/// Initializes a new instance of the <see cref="Customer"/> class.
106+
/// </para>
107+
/// <para>
108+
/// Additional information can be included in subsequent paragraphs.
109+
/// </para>
110+
/// </summary>
111+
public Customer()
112+
{
113+
}
114+
```
115+
99116
## How to fix violations
100117

101118
To fix a violation of this rule, edit the summary text for the constructor as described above.

0 commit comments

Comments
 (0)