diff --git a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs
index 8b0dc9a91d517..ab440347d3059 100644
--- a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs
+++ b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs
@@ -398,6 +398,25 @@ await TestAsync(markup,
Documentation("summary for interface IGoo"));
}
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60725")]
+ public async Task TestMergedRemarks()
+ {
+ var markup =
+ """
+ /// hello1
+ public partial class C {
+ }
+
+ /// hello2
+ public partial class $$C {
+ }
+ """;
+
+ await TestAsync(markup,
+ MainDescription("class C"),
+ Remarks("hello1 hello2"));
+ }
+
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991466")]
public async Task TestDocumentationInUsingDirectiveWithAlias3()
{
@@ -516,7 +535,9 @@ void M()
// SingleLine doc comment with '\r' line separators
await TestAsync("""
- ///Hello!
///
class C { void M() { $$C obj; } }
+ ///Hello!
+ ///
+ class C { void M() { $$C obj; } }
""",
MainDescription("class C"),
Documentation("Hello!"));
@@ -632,7 +653,12 @@ void M()
// Multiline doc comment with '\r' line separators
await TestAsync("""
- /**
*
* Hello!
*
*/
class C { void M() { $$C obj; } }
+ /**
+ *
+ * Hello!
+ *
+ */
+ class C { void M() { $$C obj; } }
""",
MainDescription("class C"),
Documentation("Hello!"));
diff --git a/src/EditorFeatures/Test2/Workspaces/SymbolDescriptionServiceTests.vb b/src/EditorFeatures/Test2/Workspaces/SymbolDescriptionServiceTests.vb
index d3a06bef056a3..8e99c1e4e54a4 100644
--- a/src/EditorFeatures/Test2/Workspaces/SymbolDescriptionServiceTests.vb
+++ b/src/EditorFeatures/Test2/Workspaces/SymbolDescriptionServiceTests.vb
@@ -10,10 +10,8 @@ Imports Microsoft.CodeAnalysis.Host
Imports Microsoft.CodeAnalysis.LanguageService
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
-
<[UseExportProvider]>
Public Class SymbolDescriptionServiceTests
-
Private Shared Async Function TestAsync(languageServiceProvider As HostLanguageServices, workspace As EditorTestWorkspace, expectedDescription As String) As Task
Dim solution = workspace.CurrentSolution
diff --git a/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs b/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs
index 4ee4086912483..4f51468a72599 100644
--- a/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs
+++ b/src/Features/CSharp/Portable/DocumentationComments/CSharpDocumentationCommentFormattingService.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#nullable disable
-
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.DocumentationComments;
@@ -12,11 +10,6 @@
namespace Microsoft.CodeAnalysis.CSharp.DocumentationComments;
[ExportLanguageService(typeof(IDocumentationCommentFormattingService), LanguageNames.CSharp), Shared]
-internal class CSharpDocumentationCommentFormattingService : AbstractDocumentationCommentFormattingService
-{
- [ImportingConstructor]
- [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
- public CSharpDocumentationCommentFormattingService()
- {
- }
-}
+[method: ImportingConstructor]
+[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
+internal sealed class CSharpDocumentationCommentFormattingService() : AbstractDocumentationCommentFormattingService;
diff --git a/src/Workspaces/Core/Portable/Shared/Utilities/DocumentationComment.cs b/src/Workspaces/Core/Portable/Shared/Utilities/DocumentationComment.cs
index 695466d6a1358..168cd9319471b 100644
--- a/src/Workspaces/Core/Portable/Shared/Utilities/DocumentationComment.cs
+++ b/src/Workspaces/Core/Portable/Shared/Utilities/DocumentationComment.cs
@@ -7,8 +7,8 @@
using System.Collections.Immutable;
using System.Xml;
using Microsoft.CodeAnalysis.PooledObjects;
-using XmlNames = Roslyn.Utilities.DocumentationCommentXmlNames;
using Microsoft.CodeAnalysis.Shared.Extensions;
+using XmlNames = Roslyn.Utilities.DocumentationCommentXmlNames;
namespace Microsoft.CodeAnalysis.Shared.Utilities;
@@ -227,89 +227,98 @@ private static string TrimEachLine(string text)
private void ParseCallback(XmlReader reader)
{
- if (reader.NodeType == XmlNodeType.Element)
+ if (reader.NodeType != XmlNodeType.Element)
{
- var localName = reader.LocalName;
- if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName) && _comment.ExampleText == null)
- {
- _comment.ExampleText = TrimEachLine(reader.ReadInnerXml());
- }
- else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName) && _comment.SummaryText == null)
- {
- _comment.SummaryText = TrimEachLine(reader.ReadInnerXml());
- }
- else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName) && _comment.ReturnsText == null)
- {
- _comment.ReturnsText = TrimEachLine(reader.ReadInnerXml());
- }
- else if (XmlNames.ElementEquals(localName, XmlNames.ValueElementName) && _comment.ValueText == null)
- {
- _comment.ValueText = TrimEachLine(reader.ReadInnerXml());
- }
- else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName) && _comment.RemarksText == null)
+ // We came across something that isn't a start element, like a block of text. Skip it.
+ reader.Read();
+ return;
+ }
+
+ var localName = reader.LocalName;
+ if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName))
+ {
+ _comment.ExampleText = InitializeValue(_comment.ExampleText, TrimEachLine(reader.ReadInnerXml()));
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName))
+ {
+ _comment.SummaryText = InitializeValue(_comment.SummaryText, TrimEachLine(reader.ReadInnerXml()));
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName))
+ {
+ _comment.ReturnsText = InitializeValue(_comment.ReturnsText, TrimEachLine(reader.ReadInnerXml()));
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.ValueElementName))
+ {
+ _comment.ValueText = InitializeValue(_comment.ValueText, TrimEachLine(reader.ReadInnerXml()));
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName))
+ {
+ _comment.RemarksText = InitializeValue(_comment.RemarksText, TrimEachLine(reader.ReadInnerXml()));
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName))
+ {
+ var name = reader.GetAttribute(XmlNames.NameAttributeName);
+ var paramText = reader.ReadInnerXml();
+
+ if (!string.IsNullOrWhiteSpace(name) && !_comment._parameterTexts.ContainsKey(name))
{
- _comment.RemarksText = TrimEachLine(reader.ReadInnerXml());
+ (_parameterNamesBuilder ??= ImmutableArray.CreateBuilder()).Add(name);
+ _comment._parameterTexts.Add(name, TrimEachLine(paramText));
}
- else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName))
- {
- var name = reader.GetAttribute(XmlNames.NameAttributeName);
- var paramText = reader.ReadInnerXml();
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName))
+ {
+ var name = reader.GetAttribute(XmlNames.NameAttributeName);
+ var typeParamText = reader.ReadInnerXml();
- if (!string.IsNullOrWhiteSpace(name) && !_comment._parameterTexts.ContainsKey(name))
- {
- (_parameterNamesBuilder ??= ImmutableArray.CreateBuilder()).Add(name);
- _comment._parameterTexts.Add(name, TrimEachLine(paramText));
- }
- }
- else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName))
+ if (!string.IsNullOrWhiteSpace(name) && !_comment._typeParameterTexts.ContainsKey(name))
{
- var name = reader.GetAttribute(XmlNames.NameAttributeName);
- var typeParamText = reader.ReadInnerXml();
-
- if (!string.IsNullOrWhiteSpace(name) && !_comment._typeParameterTexts.ContainsKey(name))
- {
- (_typeParameterNamesBuilder ??= ImmutableArray.CreateBuilder()).Add(name);
- _comment._typeParameterTexts.Add(name, TrimEachLine(typeParamText));
- }
+ (_typeParameterNamesBuilder ??= ImmutableArray.CreateBuilder()).Add(name);
+ _comment._typeParameterTexts.Add(name, TrimEachLine(typeParamText));
}
- else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName))
- {
- var type = reader.GetAttribute(XmlNames.CrefAttributeName);
- var exceptionText = reader.ReadInnerXml();
-
- if (!string.IsNullOrWhiteSpace(type))
- {
- if (_exceptionTextBuilders == null || !_exceptionTextBuilders.ContainsKey(type))
- {
- (_exceptionTypesBuilder ??= ImmutableArray.CreateBuilder()).Add(type);
- (_exceptionTextBuilders ??= []).Add(type, ImmutableArray.CreateBuilder());
- }
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName))
+ {
+ var type = reader.GetAttribute(XmlNames.CrefAttributeName);
+ var exceptionText = reader.ReadInnerXml();
- _exceptionTextBuilders[type].Add(exceptionText);
- }
- }
- else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName))
+ if (!string.IsNullOrWhiteSpace(type))
{
- var cref = reader.GetAttribute(XmlNames.CrefAttributeName);
- if (!string.IsNullOrWhiteSpace(cref))
+ if (_exceptionTextBuilders == null || !_exceptionTextBuilders.ContainsKey(type))
{
- _comment.CompletionListCref = cref;
+ (_exceptionTypesBuilder ??= ImmutableArray.CreateBuilder()).Add(type);
+ (_exceptionTextBuilders ??= []).Add(type, ImmutableArray.CreateBuilder());
}
- reader.ReadInnerXml();
+ _exceptionTextBuilders[type].Add(exceptionText);
}
- else
+ }
+ else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName))
+ {
+ var cref = reader.GetAttribute(XmlNames.CrefAttributeName);
+ if (!string.IsNullOrWhiteSpace(cref))
{
- // This is an element we don't handle. Skip it.
- reader.Read();
+ _comment.CompletionListCref = cref;
}
+
+ reader.ReadInnerXml();
}
else
{
- // We came across something that isn't a start element, like a block of text.
- // Skip it.
+ // This is an element we don't handle. Skip it.
reader.Read();
}
+
+ return;
+
+ static string InitializeValue(string? existingValue, string newValue)
+ {
+ // The use of Environment.NewLine matches the behavior of StringBuilder.AppendLine used in multiple
+ // places in this file.
+ return existingValue is null or ""
+ ? newValue
+ : $"{existingValue}{Environment.NewLine}{newValue}";
+ }
}
}
diff --git a/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentTests.cs b/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentTests.cs
index 2664563f9815e..7868727b2feda 100644
--- a/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentTests.cs
+++ b/src/Workspaces/CoreTest/UtilityTest/DocumentationCommentTests.cs
@@ -2,351 +2,389 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#nullable disable
-
using Microsoft.CodeAnalysis.Shared.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
-namespace Microsoft.CodeAnalysis.UnitTests
+namespace Microsoft.CodeAnalysis.UnitTests;
+
+public class DocumentationCommentTests
{
- public class DocumentationCommentTests
+ [Fact]
+ public void ParseEmptyXmlFragment()
+ {
+ var document = DocumentationComment.FromXmlFragment("");
+
+ Assert.Null(document.ExampleText);
+ Assert.Null(document.ReturnsText);
+ Assert.Null(document.ValueText);
+ Assert.Null(document.SummaryText);
+ }
+
+ [Fact]
+ public void ParseFullTag()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ Hello, world!
+ 42.
+ 43.
+ goo.Bar();
+ A goo.
+ A type.
+ An exception
+ A remark
+ """);
+
+ Assert.Equal("Hello, world!", comment.SummaryText);
+ Assert.Equal("42.", comment.ReturnsText);
+ Assert.Equal("43.", comment.ValueText);
+ Assert.Equal("goo.Bar();", comment.ExampleText);
+ Assert.Equal("goo", comment.ParameterNames[0]);
+ Assert.Equal("A goo.", comment.GetParameterText("goo"));
+ Assert.Equal("T", comment.TypeParameterNames[0]);
+ Assert.Equal("A type.", comment.GetTypeParameterText("T"));
+ Assert.Equal("System.Exception", comment.ExceptionTypes[0]);
+ Assert.Equal("An exception", comment.GetExceptionTexts("System.Exception")[0]);
+ Assert.Equal("A remark", comment.RemarksText);
+ }
+
+ [Fact]
+ public void ParseFullTagEmptyValues()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+
+
+
+
+
+
+
+
+ """);
+
+ Assert.Equal(string.Empty, comment.SummaryText);
+ Assert.Equal(string.Empty, comment.ReturnsText);
+ Assert.Equal(string.Empty, comment.ValueText);
+ Assert.Equal(string.Empty, comment.ExampleText);
+ Assert.Equal("goo", comment.ParameterNames[0]);
+ Assert.Equal(string.Empty, comment.GetParameterText("goo"));
+ Assert.Equal("T", comment.TypeParameterNames[0]);
+ Assert.Equal(string.Empty, comment.GetTypeParameterText("T"));
+ Assert.Equal("System.Exception", comment.ExceptionTypes[0]);
+ Assert.Equal(string.Empty, comment.GetExceptionTexts("System.Exception")[0]);
+ Assert.Equal(string.Empty, comment.RemarksText);
+ }
+
+ [Fact]
+ public void ParseTagWithMultipleSummaries()
+ {
+ var comment = DocumentationComment.FromXmlFragment("Summary 1Summary 2");
+
+ Assert.Equal("""
+ Summary 1
+ Summary 2
+ """, comment.SummaryText);
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/522741")]
+ public void ParseTagWithMultiLineComments()
+ {
+ var comment = DocumentationComment.FromXmlFragment("""
+
+ Summary 1
+ Summary 2
+
+ """);
+
+ Assert.Equal("""
+ Summary 1
+ Summary 2
+ """, comment.SummaryText);
+ }
+
+ [Fact]
+ public void ParseInvalidXML()
+ {
+ var comment = DocumentationComment.FromXmlFragment("goo");
+
+ Assert.True(comment.HadXmlParseError);
+ Assert.Null(comment.SummaryText);
+ }
+
+ [Fact]
+ public void PreserveParameterNameOrdering()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ Z
+ A
+ B
+ """);
+
+ Assert.Equal("z", comment.ParameterNames[0]);
+ Assert.Equal("a", comment.ParameterNames[1]);
+ Assert.Equal("b", comment.ParameterNames[2]);
+ }
+
+ [Fact]
+ public void PreserveTypeParameterNameOrdering()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ Z
+ A
+ B
+ """);
+
+ Assert.Equal("z", comment.TypeParameterNames[0]);
+ Assert.Equal("a", comment.TypeParameterNames[1]);
+ Assert.Equal("b", comment.TypeParameterNames[2]);
+ }
+
+ [Fact]
+ public void PreserveExceptionTypeOrdering()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ Z
+ A
+ B
+ """);
+
+ Assert.Equal("z", comment.ExceptionTypes[0]);
+ Assert.Equal("a", comment.ExceptionTypes[1]);
+ Assert.Equal("b", comment.ExceptionTypes[2]);
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546732")]
+ public void UnknownTag()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ This is a summary.
+ This is another summary.
+ The param named 'a'
+ """);
+
+ Assert.Equal("This is a summary.", comment.SummaryText);
+ Assert.Equal("a", comment.ParameterNames[0]);
+ Assert.Equal("The param named 'a'", comment.GetParameterText("a"));
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546732")]
+ public void TextOutsideTag()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ This is a summary.
+ This is random top-level text.
+ The param named 'a'
+ """);
+
+ Assert.Equal("This is a summary.", comment.SummaryText);
+ Assert.Equal("a", comment.ParameterNames[0]);
+ Assert.Equal("The param named 'a'", comment.GetParameterText("a"));
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546732")]
+ public void SingleTopLevelTag()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+
+ This is a summary.
+ This is random top-level text.
+ The param named 'a'
+
+ """);
+
+ Assert.Equal("This is a summary.", comment.SummaryText);
+ Assert.Equal("a", comment.ParameterNames[0]);
+ Assert.Equal("The param named 'a'", comment.GetParameterText("a"));
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
+ public void MultipleParamsWithSameName()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ This comment should be retained.
+ This comment should not be retained.
+ """);
+
+ Assert.Equal(1, comment.ParameterNames.Length);
+ Assert.Equal("a", comment.ParameterNames[0]);
+ Assert.Equal("This comment should be retained.", comment.GetParameterText("a"));
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
+ public void MultipleTypeParamsWithSameName()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ This comment should be retained.
+ This comment should not be retained.
+ """);
+
+ Assert.Equal(1, comment.TypeParameterNames.Length);
+ Assert.Equal("a", comment.TypeParameterNames[0]);
+ Assert.Equal("This comment should be retained.", comment.GetTypeParameterText("a"));
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
+ public void MultipleExceptionsWithSameName()
+ {
+ var comment = DocumentationComment.FromXmlFragment(
+ """
+ First A description
+ First B description
+ Second A description
+ Second B description
+ """);
+
+ Assert.Equal(2, comment.ExceptionTypes.Length);
+ Assert.Equal("A", comment.ExceptionTypes[0]);
+ Assert.Equal("B", comment.ExceptionTypes[1]);
+ Assert.Equal(2, comment.GetExceptionTexts("A").Length);
+ Assert.Equal("First A description", comment.GetExceptionTexts("A")[0]);
+ Assert.Equal("Second A description", comment.GetExceptionTexts("A")[1]);
+ Assert.Equal(2, comment.GetExceptionTexts("B").Length);
+ Assert.Equal("First B description", comment.GetExceptionTexts("B")[0]);
+ Assert.Equal("Second B description", comment.GetExceptionTexts("B")[1]);
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
+ public void NoExceptionWithGivenName()
+ {
+ var comment = DocumentationComment.FromXmlFragment(@"This is a summary");
+
+ Assert.Equal(0, comment.GetExceptionTexts("A").Length);
+ }
+
+ [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531189")]
+ public void NoNameAttribute()
{
- [Fact]
- public void ParseEmptyXmlFragment()
- {
- var document = DocumentationComment.FromXmlFragment("");
-
- Assert.Null(document.ExampleText);
- Assert.Null(document.ReturnsText);
- Assert.Null(document.ValueText);
- Assert.Null(document.SummaryText);
- }
-
- [Fact]
- public void ParseFullTag()
- {
- var comment = DocumentationComment.FromXmlFragment(
- @"Hello, world!
- 42.
- 43.
- goo.Bar();
- A goo.
- A type.
- An exception
- A remark");
-
- Assert.Equal("Hello, world!", comment.SummaryText);
- Assert.Equal("42.", comment.ReturnsText);
- Assert.Equal("43.", comment.ValueText);
- Assert.Equal("goo.Bar();", comment.ExampleText);
- Assert.Equal("goo", comment.ParameterNames[0]);
- Assert.Equal("A goo.", comment.GetParameterText("goo"));
- Assert.Equal("T", comment.TypeParameterNames[0]);
- Assert.Equal("A type.", comment.GetTypeParameterText("T"));
- Assert.Equal("System.Exception", comment.ExceptionTypes[0]);
- Assert.Equal("An exception", comment.GetExceptionTexts("System.Exception")[0]);
- Assert.Equal("A remark", comment.RemarksText);
- }
-
- [Fact]
- public void ParseFullTagEmptyValues()
- {
- var comment = DocumentationComment.FromXmlFragment(
- @"
-
-
-
-
-
-
- ");
-
- Assert.Equal(string.Empty, comment.SummaryText);
- Assert.Equal(string.Empty, comment.ReturnsText);
- Assert.Equal(string.Empty, comment.ValueText);
- Assert.Equal(string.Empty, comment.ExampleText);
- Assert.Equal("goo", comment.ParameterNames[0]);
- Assert.Equal(string.Empty, comment.GetParameterText("goo"));
- Assert.Equal("T", comment.TypeParameterNames[0]);
- Assert.Equal(string.Empty, comment.GetTypeParameterText("T"));
- Assert.Equal("System.Exception", comment.ExceptionTypes[0]);
- Assert.Equal(string.Empty, comment.GetExceptionTexts("System.Exception")[0]);
- Assert.Equal(string.Empty, comment.RemarksText);
- }
-
- [Fact]
- public void ParseTagWithMultipleSummaries()
- {
- var comment = DocumentationComment.FromXmlFragment("Summary 1Summary 2");
-
- Assert.Equal("Summary 1", comment.SummaryText);
- }
-
- [Fact(Skip = "Bug 522741")]
- [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/522741")]
- public void ParseTagWithMultiLineComments()
- {
- var comment = DocumentationComment.FromXmlFragment(@"
-Summary 1
-Summary 2
-");
-
- Assert.Equal("Summary 1 Summary 2", comment.SummaryText);
- }
-
- [Fact]
- public void ParseInvalidXML()
- {
- var comment = DocumentationComment.FromXmlFragment("goo");
-
- Assert.True(comment.HadXmlParseError);
- Assert.Null(comment.SummaryText);
- }
-
- [Fact]
- public void PreserveParameterNameOrdering()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"Z
-A
-B");
-
- Assert.Equal("z", comment.ParameterNames[0]);
- Assert.Equal("a", comment.ParameterNames[1]);
- Assert.Equal("b", comment.ParameterNames[2]);
- }
-
- [Fact]
- public void PreserveTypeParameterNameOrdering()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"Z
-A
-B");
-
- Assert.Equal("z", comment.TypeParameterNames[0]);
- Assert.Equal("a", comment.TypeParameterNames[1]);
- Assert.Equal("b", comment.TypeParameterNames[2]);
- }
-
- [Fact]
- public void PreserveExceptionTypeOrdering()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"Z
-A
-B");
-
- Assert.Equal("z", comment.ExceptionTypes[0]);
- Assert.Equal("a", comment.ExceptionTypes[1]);
- Assert.Equal("b", comment.ExceptionTypes[2]);
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546732")]
- public void UnknownTag()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"This is a summary.
-This is another summary.
-The param named 'a'");
-
- Assert.Equal("This is a summary.", comment.SummaryText);
- Assert.Equal("a", comment.ParameterNames[0]);
- Assert.Equal("The param named 'a'", comment.GetParameterText("a"));
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546732")]
- public void TextOutsideTag()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"This is a summary.
-This is random top-level text.
-The param named 'a'");
-
- Assert.Equal("This is a summary.", comment.SummaryText);
- Assert.Equal("a", comment.ParameterNames[0]);
- Assert.Equal("The param named 'a'", comment.GetParameterText("a"));
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546732")]
- public void SingleTopLevelTag()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"
-This is a summary.
-This is random top-level text.
-The param named 'a'
-");
-
- Assert.Equal("This is a summary.", comment.SummaryText);
- Assert.Equal("a", comment.ParameterNames[0]);
- Assert.Equal("The param named 'a'", comment.GetParameterText("a"));
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
- public void MultipleParamsWithSameName()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"This comment should be retained.
-This comment should not be retained.");
-
- Assert.Equal(1, comment.ParameterNames.Length);
- Assert.Equal("a", comment.ParameterNames[0]);
- Assert.Equal("This comment should be retained.", comment.GetParameterText("a"));
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
- public void MultipleTypeParamsWithSameName()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"This comment should be retained.
-This comment should not be retained.");
-
- Assert.Equal(1, comment.TypeParameterNames.Length);
- Assert.Equal("a", comment.TypeParameterNames[0]);
- Assert.Equal("This comment should be retained.", comment.GetTypeParameterText("a"));
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
- public void MultipleExceptionsWithSameName()
- {
- var comment = DocumentationComment.FromXmlFragment(
-@"First A description
-First B description
-Second A description
-Second B description");
-
- Assert.Equal(2, comment.ExceptionTypes.Length);
- Assert.Equal("A", comment.ExceptionTypes[0]);
- Assert.Equal("B", comment.ExceptionTypes[1]);
- Assert.Equal(2, comment.GetExceptionTexts("A").Length);
- Assert.Equal("First A description", comment.GetExceptionTexts("A")[0]);
- Assert.Equal("Second A description", comment.GetExceptionTexts("A")[1]);
- Assert.Equal(2, comment.GetExceptionTexts("B").Length);
- Assert.Equal("First B description", comment.GetExceptionTexts("B")[0]);
- Assert.Equal("Second B description", comment.GetExceptionTexts("B")[1]);
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530760")]
- public void NoExceptionWithGivenName()
- {
- var comment = DocumentationComment.FromXmlFragment(@"This is a summary");
-
- Assert.Equal(0, comment.GetExceptionTexts("A").Length);
- }
-
- [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531189")]
- public void NoNameAttribute()
- {
- var comment = DocumentationComment.FromXmlFragment(@"");
-
- Assert.Equal(0, comment.ParameterNames.Length);
- Assert.Equal(0, comment.TypeParameterNames.Length);
- Assert.Equal(0, comment.ExceptionTypes.Length);
- }
-
- [Fact, WorkItem(612456, "DevDiv2/DevDiv")]
- public void ReservedXmlNamespaceInName()
- {
- var fragment = @"";
-
- var comments = DocumentationComment.FromXmlFragment(fragment);
-
- Assert.Equal(fragment, comments.FullXmlFragment);
- Assert.True(comments.HadXmlParseError);
- }
-
- [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/18901")]
- public void TrimEachLine()
- {
- var multiLineText = @"
-
-
-
-Hello
- World .
-+
-.......
-
-
-
-
-123
-
- 1";
-
- var fullXml = $@"{multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}";
-
- var expected = @"Hello
- World .
-+
-.......
-123
- 1";
+ var comment = DocumentationComment.FromXmlFragment(@"");
+
+ Assert.Equal(0, comment.ParameterNames.Length);
+ Assert.Equal(0, comment.TypeParameterNames.Length);
+ Assert.Equal(0, comment.ExceptionTypes.Length);
+ }
+
+ [Fact, WorkItem(612456, "DevDiv2/DevDiv")]
+ public void ReservedXmlNamespaceInName()
+ {
+ var fragment = @"";
+
+ var comments = DocumentationComment.FromXmlFragment(fragment);
- var comment = DocumentationComment.FromXmlFragment(fullXml);
-
- Assert.Equal(expected, comment.SummaryText);
- Assert.Equal(expected, comment.ReturnsText);
- Assert.Equal(expected, comment.ValueText);
- Assert.Equal(expected, comment.ExampleText);
- Assert.Equal(expected, comment.GetParameterText("goo"));
- Assert.Equal(expected, comment.GetTypeParameterText("T"));
- Assert.Equal(expected, comment.RemarksText);
- }
+ Assert.Equal(fragment, comments.FullXmlFragment);
+ Assert.True(comments.HadXmlParseError);
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/18901")]
+ public void TrimEachLine()
+ {
+ var multiLineText = """
+
+
+
+
+ Hello
+ World .
+ +
+ .......
+
+
+
+
+ 123
+
+ 1
+ """;
+
+ var fullXml = $"""
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ """;
+
+ var expected = """
+ Hello
+ World .
+ +
+ .......
+ 123
+ 1
+ """;
+
+ var comment = DocumentationComment.FromXmlFragment(fullXml);
+
+ Assert.Equal(expected, comment.SummaryText);
+ Assert.Equal(expected, comment.ReturnsText);
+ Assert.Equal(expected, comment.ValueText);
+ Assert.Equal(expected, comment.ExampleText);
+ Assert.Equal(expected, comment.GetParameterText("goo"));
+ Assert.Equal(expected, comment.GetTypeParameterText("T"));
+ Assert.Equal(expected, comment.RemarksText);
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/18901")]
+ public void TrimEachLineCommonOffset()
+ {
+ var multiLineText = """
- [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/18901")]
- public void TrimEachLineCommonOffset()
- {
- var multiLineText = @"
- Hello
- World .
- +
- .......
-
+ Hello
+ World .
+ +
+ .......
+
- 123
+ 123
- 1";
+ 1
+ """;
- var fullXml = $@"{multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}
- {multiLineText}";
+ var fullXml = $"""
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ {multiLineText}
+ """;
- var expected = @"Hello
- World .
-+
-.......
+ var expected = """
+ Hello
+ World .
+ +
+ .......
- 123
- 1";
+ 123
+ 1
+ """;
- var comment = DocumentationComment.FromXmlFragment(fullXml);
+ var comment = DocumentationComment.FromXmlFragment(fullXml);
- Assert.Equal(expected, comment.SummaryText);
- Assert.Equal(expected, comment.ReturnsText);
- Assert.Equal(expected, comment.ValueText);
- Assert.Equal(expected, comment.ExampleText);
- Assert.Equal(expected, comment.GetParameterText("goo"));
- Assert.Equal(expected, comment.GetTypeParameterText("T"));
- Assert.Equal(expected, comment.RemarksText);
- }
+ Assert.Equal(expected, comment.SummaryText);
+ Assert.Equal(expected, comment.ReturnsText);
+ Assert.Equal(expected, comment.ValueText);
+ Assert.Equal(expected, comment.ExampleText);
+ Assert.Equal(expected, comment.GetParameterText("goo"));
+ Assert.Equal(expected, comment.GetTypeParameterText("T"));
+ Assert.Equal(expected, comment.RemarksText);
}
}