diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs index b122f7461928f214cbe38dcd6a1e0c815825b844..eb47c36d39559d98205b03b5ae4c386bca16e823 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis.Classification; using Microsoft.VisualStudio.Text.Adornments; using Roslyn.Utilities; @@ -10,18 +12,70 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense internal static class Helpers { internal static IEnumerable BuildClassifiedTextElements(ImmutableArray taggedTexts) + { + var index = 0; + return BuildClassifiedTextElements(taggedTexts, ref index); + } + + private static IReadOnlyCollection BuildClassifiedTextElements(ImmutableArray taggedTexts, ref int index) { // This method produces a sequence of zero or more paragraphs var paragraphs = new List(); // Each paragraph is constructed from one or more lines - var currentParagraph = new List(); + var currentParagraph = new List(); // Each line is constructed from one or more inline elements var currentRuns = new List(); - foreach (var part in taggedTexts) + for (; index < taggedTexts.Length; index++) { + var part = taggedTexts[index]; + if (part.Tag == TextTags.ContainerStart) + { + if (currentRuns.Count > 0) + { + // This line break means the end of a line within a paragraph. + currentParagraph.Add(new ClassifiedTextElement(currentRuns)); + currentRuns.Clear(); + } + + index++; + var nestedElements = BuildClassifiedTextElements(taggedTexts, ref index); + if (nestedElements.Count <= 1) + { + currentParagraph.Add(new ContainerElement( + ContainerElementStyle.Wrapped, + new ClassifiedTextElement(new ClassifiedTextRun(ClassificationTypeNames.Text, part.Text)), + new ContainerElement(ContainerElementStyle.Stacked, nestedElements))); + } + else + { + currentParagraph.Add(new ContainerElement( + ContainerElementStyle.Wrapped, + new ClassifiedTextElement(new ClassifiedTextRun(ClassificationTypeNames.Text, part.Text)), + new ContainerElement( + ContainerElementStyle.Stacked, + nestedElements.First(), + new ContainerElement( + ContainerElementStyle.Stacked | ContainerElementStyle.VerticalPadding, + nestedElements.Skip(1))))); + } + + continue; + } + else if (part.Tag == TextTags.ContainerEnd) + { + // Return the current result and let the caller continue + break; + } + + if (part.Tag == TextTags.ContainerStart + || part.Tag == TextTags.ContainerEnd) + { + continue; + } + if (part.Tag == TextTags.LineBreak) { if (currentRuns.Count > 0) @@ -72,7 +126,7 @@ internal static IEnumerable BuildClassifiedTextElements(ImmutableArray lines) + internal static object CreateParagraphFromLines(IReadOnlyList lines) { Contract.ThrowIfFalse(lines.Count > 0); diff --git a/src/EditorFeatures/Test/DocCommentFormatting/DocCommentFormattingTests.cs b/src/EditorFeatures/Test/DocCommentFormatting/DocCommentFormattingTests.cs index 2db2b66abc2fac33b65c107cbd005c79ff541599..d5c2e2e87dbc6e2bef8b08e2c8da0c87a5e99725 100644 --- a/src/EditorFeatures/Test/DocCommentFormatting/DocCommentFormattingTests.cs +++ b/src/EditorFeatures/Test/DocCommentFormatting/DocCommentFormattingTests.cs @@ -66,7 +66,7 @@ public void ListTag() "; - var expected = @"Here is an example of a bulleted list: Item 1. Item 2."; + var expected = "Here is an example of a bulleted list:\r\n\r\n• Item 1.\r\n• Item 2."; TestFormat(comment, expected); } diff --git a/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests_Lists.vb b/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests_Lists.vb new file mode 100644 index 0000000000000000000000000000000000000000..76fd519a02d4dc67a3784156f3f84e0507d42888 --- /dev/null +++ b/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests_Lists.vb @@ -0,0 +1,381 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Classification +Imports Microsoft.VisualStudio.Core.Imaging +Imports Microsoft.VisualStudio.Imaging +Imports Microsoft.VisualStudio.Text.Adornments + +Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense + Public Class IntellisenseQuickInfoBuilderTests_Lists + Inherits AbstractIntellisenseQuickInfoBuilderTests + + + + + Public Async Sub QuickInfoForBulletedList(itemTags As String()) + Dim openItemTag = String.Join("", itemTags.Select(Function(tag) $"<{tag}>")) + Dim closeItemTag = String.Join("", itemTags.Reverse().Select(Function(tag) $"")) + Dim workspace = + + + + using System.Threading; + class MyClass { + /// <summary> + /// <list type="bullet"> + /// <%= openItemTag %>Item 1<%= closeItemTag %> + /// <%= openItemTag %>Item 2<%= closeItemTag %> + /// </list> + /// </summary> + void MyMethod() { + MyM$$ethod(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "• ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 1"))))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "• ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 2"))))) + + AssertEqualAdornments(expected, intellisenseQuickInfo.Item) + End Sub + + + + + Public Async Sub QuickInfoForNumberedList(itemTags As String()) + Dim openItemTag = String.Join("", itemTags.Select(Function(tag) $"<{tag}>")) + Dim closeItemTag = String.Join("", itemTags.Reverse().Select(Function(tag) $"")) + Dim workspace = + + + + using System.Threading; + class MyClass { + /// <summary> + /// <list type="number"> + /// <%= openItemTag %>Item 1<%= closeItemTag %> + /// <%= openItemTag %>Item 2<%= closeItemTag %> + /// </list> + /// </summary> + void MyMethod() { + MyM$$ethod(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "1. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 1"))))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "2. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 2"))))) + + AssertEqualAdornments(expected, intellisenseQuickInfo.Item) + End Sub + + + Public Async Sub QuickInfoForBulletedTermList() + Dim workspace = + + + + using System.Threading; + class MyClass { + /// <summary> + /// <list type="bullet"> + /// <item><term>word1</term><description>Item 1</description></item> + /// <item><term>word2</term><description>Item 2</description></item> + /// </list> + /// </summary> + void MyMethod() { + MyM$$ethod(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "• ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "word1"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.Text, "–"), + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 1"))))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "• ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "word2"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.Text, "–"), + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 2"))))) + + AssertEqualAdornments(expected, intellisenseQuickInfo.Item) + End Sub + + + Public Async Sub QuickInfoForNumberedTermList() + Dim workspace = + + + + using System.Threading; + class MyClass { + /// <summary> + /// <list type="number"> + /// <item><term>word1</term><description>Item 1</description></item> + /// <item><term>word2</term><description>Item 2</description></item> + /// </list> + /// </summary> + void MyMethod() { + MyM$$ethod(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "1. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "word1"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.Text, "–"), + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 1"))))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "2. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "word2"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.Text, "–"), + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 2"))))) + + AssertEqualAdornments(expected, intellisenseQuickInfo.Item) + End Sub + + + + + Public Async Sub QuickInfoForNestedLists(itemTags As String()) + Dim openItemTag = String.Join("", itemTags.Select(Function(tag) $"<{tag}>")) + Dim closeItemTag = String.Join("", itemTags.Reverse().Select(Function(tag) $"")) + Dim workspace = + + + + using System.Threading; + class MyClass { + /// <summary> + /// <list type="number"> + /// <%= openItemTag %> + /// <list type="bullet"> + /// <%= openItemTag %><para>Line1</para><para>Line2</para><%= closeItemTag %> + /// <%= openItemTag %>Item 1.2<%= closeItemTag %> + /// </list> + /// <%= closeItemTag %> + /// <%= openItemTag %> + /// <list type="number"> + /// <%= openItemTag %>Item 2.1<%= closeItemTag %> + /// <%= openItemTag %><para>Line1</para><para>Line2</para><%= closeItemTag %> + /// </list> + /// <%= closeItemTag %> + /// </list> + /// </summary> + void MyMethod() { + MyM$$ethod(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "1. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "• ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Line1")), + New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Line2"))))), + New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "• ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 1.2")))))))), + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "2. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "1. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Item 2.1")))), + New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "2. ")), + New ContainerElement( + ContainerElementStyle.Stacked, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Line1")), + New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "Line2"))))))))) + + AssertEqualAdornments(expected, intellisenseQuickInfo.Item) + End Sub + End Class +End Namespace diff --git a/src/Features/Core/Portable/Common/TextTags.cs b/src/Features/Core/Portable/Common/TextTags.cs index beb5615a34fd541b08ae618d81cfa60b9525f76e..de61d3a9ff9242b75148f34cb7f006d382644957 100644 --- a/src/Features/Core/Portable/Common/TextTags.cs +++ b/src/Features/Core/Portable/Common/TextTags.cs @@ -39,5 +39,7 @@ public static class TextTags public const string EnumMember = nameof(EnumMember); public const string ExtensionMethod = nameof(ExtensionMethod); public const string Constant = nameof(Constant); + internal const string ContainerStart = nameof(ContainerStart); + internal const string ContainerEnd = nameof(ContainerEnd); } } diff --git a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs index 388b49573bd50abc499aa4cd221f1d837edfdad6..35bc2835ac5cd1d5035cb9c843e88ef39f98c712 100644 --- a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs @@ -11,6 +11,14 @@ namespace Microsoft.CodeAnalysis.DocumentationComments { internal abstract class AbstractDocumentationCommentFormattingService : IDocumentationCommentFormattingService { + private enum DocumentationCommentListType + { + None, + Bullet, + Number, + Table, + } + private class FormatterState { private bool _anyNonWhitespaceSinceLastPara; @@ -22,6 +30,7 @@ private class FormatterState private static TaggedText s_newlinePart = new TaggedText(TextTags.LineBreak, "\r\n"); internal readonly List Builder = new List(); + private readonly List<(DocumentationCommentListType type, int index, bool renderedItem)> _listStack = new List<(DocumentationCommentListType type, int index, bool renderedItem)>(); internal SemanticModel SemanticModel { get; set; } internal int Position { get; set; } @@ -59,6 +68,45 @@ public void AppendParts(IEnumerable parts) _anyNonWhitespaceSinceLastPara = true; } + public void PushList(DocumentationCommentListType listType) + { + _listStack.Add((listType, 0, false)); + MarkBeginOrEndPara(); + } + + public void NextListItem() + { + if (_listStack.Count == 0) + { + return; + } + + var (type, index, renderedItem) = _listStack[_listStack.Count - 1]; + if (renderedItem) + { + Builder.Add(new TaggedText(TextTags.ContainerEnd, string.Empty)); + } + + _listStack[_listStack.Count - 1] = (type, index + 1, false); + MarkLineBreak(); + } + + public void PopList() + { + if (_listStack.Count == 0) + { + return; + } + + if (_listStack[_listStack.Count - 1].renderedItem) + { + Builder.Add(new TaggedText(TextTags.ContainerEnd, string.Empty)); + } + + _listStack.RemoveAt(_listStack.Count - 1); + MarkBeginOrEndPara(); + } + public void MarkBeginOrEndPara() { // If this is a with nothing before it, then skip it. @@ -120,6 +168,33 @@ private void EmitPendingChars() _pendingParagraphBreak = false; _pendingLineBreak = false; _pendingSingleSpace = false; + + for (var i = 0; i < _listStack.Count; i++) + { + if (_listStack[i].renderedItem) + { + continue; + } + + switch (_listStack[i].type) + { + case DocumentationCommentListType.Bullet: + Builder.Add(new TaggedText(TextTags.ContainerStart, "• ")); + break; + + case DocumentationCommentListType.Number: + Builder.Add(new TaggedText(TextTags.ContainerStart, $"{_listStack[i].index}. ")); + break; + + case DocumentationCommentListType.Table: + case DocumentationCommentListType.None: + default: + Builder.Add(new TaggedText(TextTags.ContainerStart, string.Empty)); + break; + } + + _listStack[i] = (_listStack[i].type, _listStack[i].index, renderedItem: true); + } } } @@ -204,6 +279,36 @@ private static void AppendTextFromNode(FormatterState state, XNode node, Compila return; } + if (name == DocumentationCommentXmlNames.ListElementName) + { + var rawListType = element.Attribute(DocumentationCommentXmlNames.TypeAttributeName)?.Value; + DocumentationCommentListType listType; + switch (rawListType) + { + case "table": + listType = DocumentationCommentListType.Table; + break; + + case "number": + listType = DocumentationCommentListType.Number; + break; + + case "bullet": + listType = DocumentationCommentListType.Bullet; + break; + + default: + listType = DocumentationCommentListType.None; + break; + } + + state.PushList(listType); + } + else if (name == DocumentationCommentXmlNames.ItemElementName) + { + state.NextListItem(); + } + if (name == DocumentationCommentXmlNames.ParaElementName || name == DocumentationCommentXmlNames.CodeElementName) { @@ -224,6 +329,17 @@ private static void AppendTextFromNode(FormatterState state, XNode node, Compila { state.MarkBeginOrEndPara(); } + + if (name == DocumentationCommentXmlNames.ListElementName) + { + state.PopList(); + } + + if (name == DocumentationCommentXmlNames.TermElementName) + { + state.AppendSingleSpace(); + state.AppendString("–"); + } } private static void AppendTextFromAttribute(FormatterState state, XElement element, XAttribute attribute, string attributeNameToParse, SymbolDisplayPartKind kind)