diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1608UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1608UnitTests.cs
index 6bff418db..e869133ab 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1608UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1608UnitTests.cs
@@ -185,6 +185,18 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task TestClassWithIncludedMissingDocumentationAsync()
+ {
+ var testCode = @"
+///
+public class ClassName
+{
+}";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
public async Task TestClassWithIncludedSummaryDocumentationAsync()
{
@@ -210,6 +222,35 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task TestFieldWithIncludedSummaryDocumentationAsync()
+ {
+ var testCode = @"
+public class ClassName
+{
+ ///
+ public int FieldName;
+}";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task TestFieldWithIncludedDefaultSummaryDocumentationAsync()
+ {
+ var testCode = @"
+public class ClassName
+{
+ ///
+ public {|#0:int FieldName|};
+}";
+
+ DiagnosticResult expected = Diagnostic().WithLocation(0);
+
+ await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
+ }
+
private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, new[] { expected }, cancellationToken);
@@ -232,6 +273,20 @@ private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[
Summary description for the ClassName class.
+";
+ string fieldContentWithSummary = @"
+
+
+ Foo
+
+
+";
+ string fieldContentWithDefaultSummary = @"
+
+
+ Summary description for the ClassName class.
+
+
";
var test = new StyleCopDiagnosticVerifier.CSharpTest
@@ -242,6 +297,8 @@ private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[
{ "ClassWithoutSummary.xml", contentWithoutSummary },
{ "ClassWithSummary.xml", contentWithSummary },
{ "ClassWithDefaultSummary.xml", contentWithDefaultSummary },
+ { "FieldWithSummary.xml", fieldContentWithSummary },
+ { "FieldWithDefaultSummary.xml", fieldContentWithDefaultSummary },
},
};
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1611UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1611UnitTests.cs
index 31f7f74e4..1544c2e75 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1611UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1611UnitTests.cs
@@ -312,6 +312,36 @@ public void TestMethod(string param1, string param2, string param3)
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
}
+ ///
+ /// Verifies that included documentation with missing documentation file produces no diagnostics.
+ ///
+ /// A representing the asynchronous unit test.
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task VerifyIncludedMissingDocumentationAsync()
+ {
+ var testCode = @"
+///
+/// Foo
+///
+public class ClassName
+{
+ ///
+ public void TestMethod(string {|#0:param1|}, string {|#1:param2|}, string {|#2:param3|})
+ {
+ }
+}";
+
+ DiagnosticResult[] expected =
+ {
+ Diagnostic().WithLocation(0).WithArguments("param1"),
+ Diagnostic().WithLocation(1).WithArguments("param2"),
+ Diagnostic().WithLocation(2).WithArguments("param3"),
+ };
+
+ await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
+ }
+
///
/// Verifies that included documentation with missing elements documented produces the expected diagnostics.
///
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1612UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1612UnitTests.cs
index b5690dbe0..f17d5f9f8 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1612UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1612UnitTests.cs
@@ -285,6 +285,22 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task VerifyIncludedMissingFileIsNotReportedAsync()
+ {
+ var testCode = @"
+///
+/// Foo
+///
+public class ClassName
+{
+ ///
+ public ClassName Method() { return null; }
+}";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
public async Task VerifyIncludedMemberWithValidParamsIsNotReportedAsync()
{
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1613UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1613UnitTests.cs
index 9249f6031..56c72c605 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1613UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1613UnitTests.cs
@@ -154,6 +154,22 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task VerifyIncludedMissingFileAsync()
+ {
+ var testCode = @"
+///
+/// Foo
+///
+public class ClassName
+{
+ ///
+ public ClassName Method(string foo, string bar) { return null; }
+}";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
public async Task VerifyMemberWithValidParamsAndIncludedDocumentationAsync()
{
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1614UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1614UnitTests.cs
index b2d96f45d..e3e2fe0c3 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1614UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1614UnitTests.cs
@@ -154,6 +154,22 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task VerifyIncludedMissingFileAsync()
+ {
+ var testCode = @"
+///
+/// Foo
+///
+public class ClassName
+{
+ ///
+ public ClassName Method(string foo, string bar) { return null; }
+}";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
public async Task VerifyMemberIncludedDocumentationWithoutParamsAsync()
{
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1616UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1616UnitTests.cs
index 5aaac6432..4cc26502a 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1616UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1616UnitTests.cs
@@ -443,6 +443,22 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task VerifyMemberIncludedMissingFileAsync()
+ {
+ var testCode = @"
+///
+/// Foo
+///
+public class ClassName
+{
+ ///
+ public ClassName Method(string foo, string bar) { return null; }
+}";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
public async Task VerifyMemberIncludedDocumentationWithoutReturnsAsync()
{
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1625UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1625UnitTests.cs
index 1b14516cc..590ad2893 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1625UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1625UnitTests.cs
@@ -321,6 +321,21 @@ public class TestClass2 {{ }}
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task VerifyThatMissingIncludedDocumentationDoesNotReportADiagnosticAsync()
+ {
+ var testCode = $@"
+public class TestClass
+{{
+ ///
+ public void Test() {{ }}
+}}
+public class TestClass2 {{ }}
+";
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
public async Task VerifyThatTheAnalyzerDoesNotCrashOnIncludedInheritDocAsync()
{
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs
index 9c4bfe4c4..7eab515e4 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs
@@ -315,6 +315,20 @@ public class TestClass
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ [Fact]
+ [WorkItem(3150, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3150")]
+ public async Task TestIncludedMissingFileAsync()
+ {
+ var testCode = @"
+///
+public class TestClass
+{
+}
+";
+
+ await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
[Fact]
[WorkItem(2680, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2680")]
public async Task TestReportingAfterEmptyElementAsync()
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj b/StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj
index 385ad7dfc..28420c7b2 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/ElementDocumentationBase.cs b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/ElementDocumentationBase.cs
index 8484579b5..6a1981fe4 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/ElementDocumentationBase.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/ElementDocumentationBase.cs
@@ -234,29 +234,37 @@ private void HandleDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettin
if (hasIncludedDocumentation)
{
- var declaration = context.SemanticModel.GetDeclaredSymbol(node, context.CancellationToken);
- var rawDocumentation = declaration?.GetDocumentationCommentXml(expandIncludes: true, cancellationToken: context.CancellationToken);
- var completeDocumentation = XElement.Parse(rawDocumentation, LoadOptions.None);
+ var declaration = node switch
+ {
+ BaseFieldDeclarationSyntax baseFieldDeclaration => baseFieldDeclaration.Declaration.Variables.FirstOrDefault() ?? node,
+ _ => node,
+ };
- if (this.inheritDocSuppressesWarnings &&
- completeDocumentation.Nodes().OfType().Any(element => element.Name == XmlCommentHelper.InheritdocXmlTag))
+ var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(declaration, context.CancellationToken);
+ if (declaredSymbol is not null)
{
- // Ignore nodes with an tag in the included XML.
+ var rawDocumentation = declaredSymbol?.GetDocumentationCommentXml(expandIncludes: true, cancellationToken: context.CancellationToken);
+ var completeDocumentation = XElement.Parse(rawDocumentation ?? "", LoadOptions.None);
+
+ if (this.inheritDocSuppressesWarnings &&
+ completeDocumentation.Nodes().OfType().Any(element => element.Name == XmlCommentHelper.InheritdocXmlTag))
+ {
+ // Ignore nodes with an tag in the included XML.
+ return;
+ }
+
+ this.HandleCompleteDocumentation(context, needsComment, completeDocumentation, locations);
return;
}
-
- this.HandleCompleteDocumentation(context, needsComment, completeDocumentation, locations);
}
- else
- {
- IEnumerable matchingXmlElements = string.IsNullOrEmpty(this.matchElementName)
- ? documentation.Content
- .Where(x => x is XmlElementSyntax || x is XmlEmptyElementSyntax)
- .Where(x => !string.Equals(x.GetName()?.ToString(), XmlCommentHelper.IncludeXmlTag, StringComparison.Ordinal))
- : documentation.Content.GetXmlElements(this.matchElementName);
- this.HandleXmlElement(context, settings, needsComment, matchingXmlElements, locations);
- }
+ IEnumerable matchingXmlElements = string.IsNullOrEmpty(this.matchElementName)
+ ? documentation.Content
+ .Where(x => x is XmlElementSyntax || x is XmlEmptyElementSyntax)
+ .Where(x => !string.Equals(x.GetName()?.ToString(), XmlCommentHelper.IncludeXmlTag, StringComparison.Ordinal))
+ : documentation.Content.GetXmlElements(this.matchElementName);
+
+ this.HandleXmlElement(context, settings, needsComment, matchingXmlElements, locations);
}
}
}