From 06903c048329d988c237382a397bc5c732180f93 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 18 Jul 2021 19:47:33 -0400 Subject: [PATCH 1/3] Add tests showing discrepancy for element from and --- .../DocumentationRules/SA1629UnitTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs index 7eab515e4..ea0ef77a6 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs @@ -544,6 +544,23 @@ public interface ITest await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, default).ConfigureAwait(false); } + [Theory] + [InlineData("a")] + [InlineData("see")] + [InlineData("seealso")] + public async Task TestFullSentenceLinkAsync(string tag) + { + var testCode = $@" +/// +/// <{tag} href=""someurl"">Periods aren't required to glow white at the end of a full-sentence link. +/// +public interface ITest +{{ +}} +"; + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, default).ConfigureAwait(false); + } + [Theory] [InlineData(",")] [InlineData(";")] From 4da16ee17e263fe8f7c7622b1038bee0f3db318b Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 18 Jul 2021 21:09:29 -0400 Subject: [PATCH 2/3] Fix inconsistency that forced full-sentence links to have a glowing white period --- ...1629DocumentationTextMustEndWithAPeriod.cs | 26 +++++++++++----- .../Helpers/XmlCommentHelper.cs | 31 +++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1629DocumentationTextMustEndWithAPeriod.cs b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1629DocumentationTextMustEndWithAPeriod.cs index 7ba6658e0..6230974cd 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1629DocumentationTextMustEndWithAPeriod.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1629DocumentationTextMustEndWithAPeriod.cs @@ -125,10 +125,7 @@ private static void HandleSectionOrBlockXmlElement(SyntaxNodeAnalysisContext con if (!string.IsNullOrEmpty(textWithoutTrailingWhitespace)) { - if (!textWithoutTrailingWhitespace.EndsWith(".", StringComparison.Ordinal) - && !textWithoutTrailingWhitespace.EndsWith(".)", StringComparison.Ordinal) - && (startingWithFinalParagraph || !textWithoutTrailingWhitespace.EndsWith(":", StringComparison.Ordinal)) - && !textWithoutTrailingWhitespace.EndsWith("-or-", StringComparison.Ordinal)) + if (IsMissingRequiredPeriod(textWithoutTrailingWhitespace, startingWithFinalParagraph)) { int spanStart = textToken.SpanStart + textWithoutTrailingWhitespace.Length; ImmutableDictionary properties = null; @@ -162,10 +159,15 @@ void SetReplaceChar() } else if (xmlElement.Content[i].IsInlineElement() && !currentParagraphDone) { - // Treat empty XML elements as a "word not ending with a period" - var location = Location.Create(xmlElement.SyntaxTree, new TextSpan(xmlElement.Content[i].Span.End, 1)); - context.ReportDiagnostic(Diagnostic.Create(Descriptor, location)); - currentParagraphDone = true; + var lastTextElement = XmlCommentHelper.TryGetLastTextElementWithContent(xmlElement.Content[i]); + + if (lastTextElement is null // Treat empty XML elements as a "word not ending with a period" + || IsMissingRequiredPeriod(lastTextElement.TextTokens.Last().Text.TrimEnd(' ', '\r', '\n'), startingWithFinalParagraph)) + { + var location = Location.Create(xmlElement.SyntaxTree, new TextSpan(xmlElement.Content[i].Span.End, 1)); + context.ReportDiagnostic(Diagnostic.Create(Descriptor, location)); + currentParagraphDone = true; + } } else if (xmlElement.Content[i] is XmlElementSyntax childXmlElement) { @@ -198,5 +200,13 @@ void SetReplaceChar() } } } + + private static bool IsMissingRequiredPeriod(string textWithoutTrailingWhitespace, bool startingWithFinalParagraph) + { + return !textWithoutTrailingWhitespace.EndsWith(".", StringComparison.Ordinal) + && !textWithoutTrailingWhitespace.EndsWith(".)", StringComparison.Ordinal) + && (startingWithFinalParagraph || !textWithoutTrailingWhitespace.EndsWith(":", StringComparison.Ordinal)) + && !textWithoutTrailingWhitespace.EndsWith("-or-", StringComparison.Ordinal); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/XmlCommentHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/XmlCommentHelper.cs index 9d2aefb9f..fd9c815ee 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/XmlCommentHelper.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/XmlCommentHelper.cs @@ -191,6 +191,37 @@ internal static XmlTextSyntax TryGetFirstTextElementWithContent(XmlNodeSyntax no return null; } + /// + /// Returns the last which is not simply empty or whitespace. + /// + /// The XML content to search. + /// The last which is not simply empty or whitespace, or + /// if no such element exists. + internal static XmlTextSyntax TryGetLastTextElementWithContent(XmlNodeSyntax node) + { + if (node is XmlEmptyElementSyntax) + { + return null; + } + else if (node is XmlTextSyntax xmlText) + { + return !IsConsideredEmpty(node) ? xmlText : null; + } + else if (node is XmlElementSyntax xmlElement) + { + for (var i = xmlElement.Content.Count - 1; i >= 0; i--) + { + var nestedContent = TryGetFirstTextElementWithContent(xmlElement.Content[i]); + if (nestedContent != null) + { + return nestedContent; + } + } + } + + return null; + } + /// /// Checks if a contains a and returns /// if it is considered empty. From 0896aa64b88bf56809872bc9593ad028740f8d62 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 31 Mar 2022 11:12:16 -0400 Subject: [PATCH 3/3] does not belong inside --- .../DocumentationRules/SA1629UnitTests.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs index ea0ef77a6..03f66e37e 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1629UnitTests.cs @@ -545,15 +545,15 @@ public interface ITest } [Theory] - [InlineData("a")] - [InlineData("see")] - [InlineData("seealso")] - public async Task TestFullSentenceLinkAsync(string tag) + [InlineData("a", true)] + [InlineData("see", true)] + [InlineData("seealso", false)] + public async Task TestFullSentenceLinkAsync(string tag, bool insideSummary) { + var surrounding = insideSummary ? (Start: "", End: "") : (Start: string.Empty, End: string.Empty); + var testCode = $@" -/// -/// <{tag} href=""someurl"">Periods aren't required to glow white at the end of a full-sentence link. -/// +/// {surrounding.Start}<{tag} href=""someurl"">Periods aren't required to glow white at the end of a full-sentence link.{surrounding.End} public interface ITest {{ }}