diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs index 96315d2dc2127ace4388b28731001a6629c9351a..75575c0f28387fc8a39b04e042ff86c9b6c6c691 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs @@ -967,7 +967,7 @@ public static XmlEmptyElementSyntax XmlNullKeywordElement() private static XmlEmptyElementSyntax XmlKeywordElement(string keyword) { return XmlEmptyElement(DocumentationCommentXmlNames.SeeElementName).AddAttributes( - XmlTextAttribute(DocumentationCommentXmlNames.KeywordElementName, keyword)); + XmlTextAttribute(DocumentationCommentXmlNames.LangwordAttributeName, keyword)); } /// diff --git a/src/Compilers/Core/Portable/InternalUtilities/DocumentationCommentXmlNames.cs b/src/Compilers/Core/Portable/InternalUtilities/DocumentationCommentXmlNames.cs index e4cf00896016c5b6db5e96d590062af5f69d586d..15a2e232900d6003ba7e2810344c208fac0a395f 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/DocumentationCommentXmlNames.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/DocumentationCommentXmlNames.cs @@ -12,34 +12,38 @@ internal static class DocumentationCommentXmlNames public const string CElementName = "c"; public const string CodeElementName = "code"; public const string CompletionListElementName = "completionlist"; + public const string DescriptionElementName = "description"; public const string ExampleElementName = "example"; public const string ExceptionElementName = "exception"; public const string IncludeElementName = "include"; + public const string ItemElementName = "item"; public const string ListElementName = "list"; + public const string ListHeaderElementName = "listheader"; public const string ParaElementName = "para"; public const string ParameterElementName = "param"; public const string ParameterReferenceElementName = "paramref"; public const string PermissionElementName = "permission"; + public const string PlaceholderElementName = "placeholder"; + public const string PreliminaryElementName = "preliminary"; public const string RemarksElementName = "remarks"; public const string ReturnsElementName = "returns"; public const string SeeElementName = "see"; public const string SeeAlsoElementName = "seealso"; public const string SummaryElementName = "summary"; + public const string TermElementName = "term"; + public const string ThreadSafetyElementName = "threadsafety"; public const string TypeParameterElementName = "typeparam"; public const string TypeParameterReferenceElementName = "typeparamref"; public const string ValueElementName = "value"; - public const string ThreadSafetyElementName = "threadsafety"; - public const string PreliminaryElementName = "preliminary"; - public const string KeywordElementName = "langword"; - public const string PlaceholderElementName = "placeholder"; public const string CrefAttributeName = "cref"; - public const string NameAttributeName = "name"; public const string FileAttributeName = "file"; + public const string InstanceAttributeName = "instance"; + public const string LangwordAttributeName = "langword"; + public const string NameAttributeName = "name"; public const string PathAttributeName = "path"; - public const string TypeAttributeName = "type"; public const string StaticAttributeName = "static"; - public const string InstanceAttributeName = "instance"; + public const string TypeAttributeName = "type"; public static bool ElementEquals(string name1, string name2, bool fromVb = false) { diff --git a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFactory.vb b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFactory.vb index 6873f1f724d40c55e2a69445dccbe06371d3ac8d..2a18e9003e0e3551cbdcf4edf2f537ac484d1d20 100644 --- a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFactory.vb +++ b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFactory.vb @@ -748,7 +748,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic XmlAttribute( XmlName( Nothing, - XmlTextLiteralToken(DocumentationCommentXmlNames.KeywordElementName, DocumentationCommentXmlNames.KeywordElementName)), + XmlTextLiteralToken(DocumentationCommentXmlNames.LangwordAttributeName, DocumentationCommentXmlNames.LangwordAttributeName)), XmlString( Token(SyntaxKind.DoubleQuoteToken), SyntaxTokenList.Create(XmlTextLiteralToken(keyword, keyword)), diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs index 44766bf97af168d0f937887c48d28e4b8b1bb22e..1a775c77792c44880c5e015428d25403c574e1ab 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs @@ -16,6 +16,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers { + using static DocumentationCommentXmlNames; + internal partial class XmlDocCommentCompletionProvider : AbstractDocCommentCompletionProvider { internal override bool IsInsertionTrigger(SourceText text, int characterPosition, OptionSet options) @@ -88,10 +90,10 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement || token.Parent.Parent.IsParentKind(SyntaxKind.XmlElement)) { - items.AddRange(GetNestedTags(declaredSymbol)); + items.AddRange(GetNestedItems(declaredSymbol)); } - if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListTagName) + if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListElementName) { items.AddRange(GetListItems()); } @@ -99,13 +101,13 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition if (token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement) && token.Parent.Parent.IsParentKind(SyntaxKind.XmlElement)) { var element = (XmlElementSyntax)token.Parent.Parent.Parent; - if (element.StartTag.Name.LocalName.ValueText == ListTagName) + if (element.StartTag.Name.LocalName.ValueText == ListElementName) { items.AddRange(GetListItems()); } } - if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListHeaderTagName) + if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListHeaderElementName) { items.AddRange(GetListHeaderItems()); } @@ -123,12 +125,12 @@ internal override bool IsInsertionTrigger(SourceText text, int characterPosition { var startTag = (XmlElementStartTagSyntax)token.Parent; - if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListTagName) + if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListElementName) { items.AddRange(GetListItems()); } - if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListHeaderTagName) + if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListHeaderElementName) { items.AddRange(GetListHeaderItems()); } @@ -144,16 +146,16 @@ private bool IsAttributeNameContext(SyntaxToken token, int position, out string if (token.IsKind(SyntaxKind.XmlTextLiteralToken) && string.IsNullOrWhiteSpace(token.Text)) { - // Unlike VB, the C# lexer has a preference for leading trivia so, in the following text... + // Unlike VB, the C# lexer has a preference for leading trivia. In the following example... // - // attributes = default(SyntaxList); @@ -179,9 +181,7 @@ private bool IsAttributeNameContext(SyntaxToken token, int position, out string } } - attributeNames = attributes.Select(attribute => GetAttributeName(attribute)) - .ToSet(); - + attributeNames = attributes.Select(GetAttributeName).ToSet(); return elementName != null; } @@ -192,26 +192,20 @@ private string GetElementNameAndAttributes(SyntaxNode node, out SyntaxList GetKeywordNames() { - return SyntaxFacts.GetKeywordKinds().Select(keyword => SyntaxFacts.GetText(keyword)); + return SyntaxFacts.GetKeywordKinds().Select(SyntaxFacts.GetText); } protected override IEnumerable GetExistingTopLevelElementNames(DocumentationCommentTriviaSyntax syntax) diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs index 9addb7279a26ee22a0aa206ffb348f4d1e9edec7..f251422753ca44ebd297a481d0b402ac64935d41 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractDocCommentCompletionProvider.cs @@ -1,86 +1,62 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; -using System.Collections.Immutable; -using System; namespace Microsoft.CodeAnalysis.Completion.Providers { + using static DocumentationCommentXmlNames; + internal abstract class AbstractDocCommentCompletionProvider : CommonCompletionProvider where TSyntax : SyntaxNode { // Tag names - protected const string CTagName = "c"; - protected const string CodeTagName = "code"; - protected const string CompletionListTagName = "completionlist"; - protected const string DescriptionTagName = "description"; - protected const string ExampleTagName = "example"; - protected const string ExceptionTagName = "exception"; - protected const string IncludeTagName = "include"; - protected const string ItemTagName = "item"; - protected const string ListTagName = "list"; - protected const string ListHeaderTagName = "listheader"; - protected const string ParaTagName = "para"; - protected const string ParamTagName = "param"; - protected const string ParamRefTagName = "paramref"; - protected const string PermissionTagName = "permission"; - protected const string RemarksTagName = "remarks"; - protected const string ReturnsTagName = "returns"; - protected const string SeeTagName = "see"; - protected const string SeeAlsoTagName = "seealso"; - protected const string SummaryTagName = "summary"; - protected const string TermTagName = "term"; - protected const string TypeParamTagName = "typeparam"; - protected const string TypeParamRefTagName = "typeparamref"; - protected const string ValueTagName = "value"; - - // Attribute names - protected const string CrefAttributeName = "cref"; - protected const string FileAttributeName = "file"; - protected const string LangwordAttributeName = "langword"; - protected const string NameAttributeName = "name"; - protected const string PathAttributeName = "path"; - protected const string TypeAttributeName = "type"; - - private readonly Dictionary _tagMap = + private static readonly ImmutableArray s_alwaysVisibleTagNames = ImmutableArray.Create(SeeElementName, SeeAlsoElementName); + private static readonly ImmutableArray s_listTagNames = ImmutableArray.Create(ListHeaderElementName, TermElementName, ItemElementName, DescriptionElementName); + private static readonly ImmutableArray s_listHeaderTagNames = ImmutableArray.Create(TermElementName, DescriptionElementName); + private static readonly ImmutableArray s_nestedTagNames = ImmutableArray.Create(CElementName, CodeElementName, ParaElementName, ListElementName); + private static readonly ImmutableArray s_topLevelRepeatableTagNames = ImmutableArray.Create(ExceptionElementName, IncludeElementName, PermissionElementName); + private static readonly ImmutableArray s_topLevelSingleUseTagNames = ImmutableArray.Create(SummaryElementName, RemarksElementName, ExampleElementName, CompletionListElementName); + + private static readonly Dictionary s_tagMap = new Dictionary { - // Open Before caret $$ After caret Close - { ExceptionTagName, new[] { $"<{ExceptionTagName}", $" {CrefAttributeName}=\"", "\"", null } }, - { IncludeTagName, new[] { $"<{IncludeTagName}", $" {FileAttributeName}=\'", $"\' {PathAttributeName}=\'[@name=\"\"]\'", "/>" } }, - { PermissionTagName, new[] { $"<{PermissionTagName}", $" {CrefAttributeName}=\"", "\"", null } }, - { SeeTagName, new[] { $"<{SeeTagName}", $" {CrefAttributeName}=\"", "\"", "/>" } }, - { SeeAlsoTagName, new[] { $"<{SeeAlsoTagName}", $" {CrefAttributeName}=\"", "\"", "/>" } }, - { ListTagName, new[] { $"<{ListTagName}", $" {TypeAttributeName}=\"", "\"", null } }, - { ParamRefTagName, new[] { $"<{ParamRefTagName}", $" {NameAttributeName}=\"", "\"", "/>" } }, - { TypeParamRefTagName, new[] { $"<{TypeParamRefTagName}", $" {NameAttributeName}=\"", "\"", "/>" } }, - { CompletionListTagName, new[] { $"<{CompletionListTagName}", $" {CrefAttributeName}=\"", "\"", "/>" } }, + // Open Before caret $$ After caret Close + { ExceptionElementName, new[] { $"<{ExceptionElementName}", $" {CrefAttributeName}=\"", "\"", null } }, + { IncludeElementName, new[] { $"<{IncludeElementName}", $" {FileAttributeName}=\'", $"\' {PathAttributeName}=\'[@name=\"\"]\'", "/>" } }, + { PermissionElementName, new[] { $"<{PermissionElementName}", $" {CrefAttributeName}=\"", "\"", null } }, + { SeeElementName, new[] { $"<{SeeElementName}", $" {CrefAttributeName}=\"", "\"", "/>" } }, + { SeeAlsoElementName, new[] { $"<{SeeAlsoElementName}", $" {CrefAttributeName}=\"", "\"", "/>" } }, + { ListElementName, new[] { $"<{ListElementName}", $" {TypeAttributeName}=\"", "\"", null } }, + { ParameterReferenceElementName, new[] { $"<{ParameterReferenceElementName}", $" {NameAttributeName}=\"", "\"", "/>" } }, + { TypeParameterReferenceElementName, new[] { $"<{TypeParameterReferenceElementName}", $" {NameAttributeName}=\"", "\"", "/>" } }, + { CompletionListElementName, new[] { $"<{CompletionListElementName}", $" {CrefAttributeName}=\"", "\"", "/>" } }, }; - private readonly string[][] _attributeMap = + private static readonly string[][] s_attributeMap = new[] { - new[] { ExceptionTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, - new[] { PermissionTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, - new[] { SeeTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, - new[] { SeeTagName, LangwordAttributeName, $"{LangwordAttributeName}=\"", "\"" }, - new[] { SeeAlsoTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, - new[] { ListTagName, TypeAttributeName, $"{TypeAttributeName}=\"", "\"" }, - new[] { ParamTagName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, - new[] { ParamRefTagName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, - new[] { TypeParamTagName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, - new[] { TypeParamRefTagName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, - new[] { IncludeTagName, FileAttributeName, $"{FileAttributeName}=\"", "\"" }, - new[] { IncludeTagName, PathAttributeName, $"{PathAttributeName}=\"", "\"" } + new[] { ExceptionElementName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, + new[] { PermissionElementName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, + new[] { SeeElementName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, + new[] { SeeElementName, LangwordAttributeName, $"{LangwordAttributeName}=\"", "\"" }, + new[] { SeeAlsoElementName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" }, + new[] { ListElementName, TypeAttributeName, $"{TypeAttributeName}=\"", "\"" }, + new[] { ParameterElementName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, + new[] { ParameterReferenceElementName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, + new[] { TypeParameterElementName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, + new[] { TypeParameterReferenceElementName, NameAttributeName, $"{NameAttributeName}=\"", "\"" }, + new[] { IncludeElementName, FileAttributeName, $"{FileAttributeName}=\"", "\"" }, + new[] { IncludeElementName, PathAttributeName, $"{PathAttributeName}=\"", "\"" } }; - private readonly ImmutableArray _listTypeValues = ImmutableArray.Create("bullet", "number", "table"); + private static readonly ImmutableArray s_listTypeValues = ImmutableArray.Create("bullet", "number", "table"); public override async Task ProvideCompletionsAsync(CompletionContext context) { @@ -104,14 +80,14 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) protected abstract IEnumerable GetExistingTopLevelAttributeValues(TSyntax syntax, string tagName, string attributeName); - private Boolean HasExistingTopLevelElement(TSyntax syntax, string name) + private bool HasExistingTopLevelElement(TSyntax syntax, string name) { return GetExistingTopLevelElementNames(syntax).Contains(name); } private CompletionItem GetItem(string name) { - if (_tagMap.TryGetValue(name, out var values)) + if (s_tagMap.TryGetValue(name, out var values)) { return CreateCompletionItem(name, beforeCaretText: values[0] + values[1], @@ -125,130 +101,111 @@ private CompletionItem GetItem(string name) protected IEnumerable GetAttributeItems(string tagName, ISet existingAttributes) { - return _attributeMap.Where(x => x[0] == tagName && !existingAttributes.Contains(x[1])) - .Select(x => CreateCompletionItem(x[1], x[2], x[3])); + return s_attributeMap.Where(x => x[0] == tagName && !existingAttributes.Contains(x[1])) + .Select(x => CreateCompletionItem(x[1], x[2], x[3])); } protected IEnumerable GetAlwaysVisibleItems() { - const string CommentPrefix = "!--"; - const string CommentSuffix = "-->"; - const string CDataPrefix = "![CDATA["; - const string CDataSuffix = "]]>"; - - return new[] { - GetItem(SeeTagName), - GetItem(SeeAlsoTagName), - CreateCompletionItem(CommentPrefix, "<" + CommentPrefix, CommentSuffix), - CreateCompletionItem(CDataPrefix, "<" + CDataPrefix, CDataSuffix), - }; + return new[] { GetCDataItem(), GetCommentItem(), GetItem(SeeElementName), GetItem(SeeAlsoElementName) }; } - protected IEnumerable NestedTagNames + private CompletionItem GetCommentItem() { - get { return new[] { CTagName, CodeTagName, ParaTagName, ListTagName }; } + const string prefix = "!--"; + const string suffix = "-->"; + return CreateCompletionItem(prefix, "<" + prefix, suffix); } - protected IEnumerable GetNestedTags(ISymbol declaredSymbol) + private CompletionItem GetCDataItem() { - return NestedTagNames.Select(GetItem) - .Concat(GetParamRefItems(declaredSymbol)) - .Concat(GetTypeParamRefItems(declaredSymbol)); + const string prefix = "![CDATA["; + const string suffix = "]]>"; + return CreateCompletionItem(prefix, "<" + prefix, suffix); } - private IEnumerable GetParamRefItems(ISymbol declaredSymbol) + protected IEnumerable GetNestedItems(ISymbol symbol) { - var parameters = declaredSymbol?.GetParameters().Select(p => p.Name).ToSet(); + var items = s_nestedTagNames.Select(GetItem); - if (parameters == null) + if (symbol != null) { - return SpecializedCollections.EmptyEnumerable(); + items = items.Concat(GetParamRefItems(symbol)) + .Concat(GetTypeParamRefItems(symbol)); } - return parameters.Select(p => CreateCompletionItem( - displayText: FormatParameter(ParamRefTagName, p), - beforeCaretText: FormatParameterRefTag(ParamRefTagName, p), - afterCaretText: string.Empty)); + return items; } - private IEnumerable GetTypeParamRefItems(ISymbol declaredSymbol) + private IEnumerable GetParamRefItems(ISymbol symbol) { - var typeParameters = declaredSymbol?.GetTypeParameters().Select(t => t.Name).ToSet(); + var names = symbol.GetParameters().Select(p => p.Name); - if (typeParameters == null) - { - return SpecializedCollections.EmptyEnumerable(); - } + return names.Select(p => CreateCompletionItem( + displayText: FormatParameter(ParameterReferenceElementName, p), + beforeCaretText: FormatParameterRefTag(ParameterReferenceElementName, p), + afterCaretText: string.Empty)); + } - return typeParameters.Select(t => CreateCompletionItem( - displayText: FormatParameter(TypeParamRefTagName, t), - beforeCaretText: FormatParameterRefTag(TypeParamRefTagName, t), + private IEnumerable GetTypeParamRefItems(ISymbol symbol) + { + var names = symbol.GetTypeParameters().Select(t => t.Name); + + return names.Select(t => CreateCompletionItem( + displayText: FormatParameter(TypeParameterReferenceElementName, t), + beforeCaretText: FormatParameterRefTag(TypeParameterReferenceElementName, t), afterCaretText: string.Empty)); } protected IEnumerable GetAttributeValueItems(ISymbol symbol, string tagName, string attributeName) { - if (attributeName == NameAttributeName) + if (attributeName == NameAttributeName && symbol != null) { - if (tagName == ParamTagName || tagName == ParamRefTagName) + if (tagName == ParameterElementName || tagName == ParameterReferenceElementName) { - return GetParamNameItems(symbol); + return symbol.GetParameters() + .Select(parameter => CreateCompletionItem(parameter.Name)); } - else if (tagName == TypeParamTagName || tagName == TypeParamRefTagName) + else if (tagName == TypeParameterElementName || tagName == TypeParameterReferenceElementName) { - return GetTypeParamNameItems(symbol); + return symbol.GetTypeParameters() + .Select(typeParameter => CreateCompletionItem(typeParameter.Name)); } } - else if (attributeName == LangwordAttributeName && tagName == SeeTagName) + else if (attributeName == LangwordAttributeName && tagName == SeeElementName) { - return GetKeywordNames().Select(keyword => CreateCompletionItem(keyword)); + return GetKeywordNames().Select(CreateCompletionItem); } - else if (attributeName == TypeAttributeName && tagName == ListTagName) + else if (attributeName == TypeAttributeName && tagName == ListElementName) { - return _listTypeValues.Select(value => CreateCompletionItem(value)); + return s_listTypeValues.Select(CreateCompletionItem); } return null; } - protected IEnumerable GetParamNameItems(ISymbol declaredSymbol) - { - var items = declaredSymbol?.GetParameters() - .Select(parameter => CreateCompletionItem(parameter.Name)); - - return items ?? SpecializedCollections.EmptyEnumerable(); - } - - protected IEnumerable GetTypeParamNameItems(ISymbol declaredSymbol) - { - var items = declaredSymbol?.GetTypeParameters() - .Select(typeParameter => CreateCompletionItem(typeParameter.Name)); - - return items ?? SpecializedCollections.EmptyEnumerable(); - } - protected abstract IEnumerable GetKeywordNames(); protected IEnumerable GetTopLevelRepeatableItems() { - return new[] { ExceptionTagName, IncludeTagName, PermissionTagName }.Select(GetItem); + return s_topLevelRepeatableTagNames.Select(GetItem); } protected IEnumerable GetTopLevelSingleUseItems(TSyntax syntax) { - var tagNames = new HashSet(new[] { SummaryTagName, RemarksTagName, ExampleTagName, CompletionListTagName }); + var tagNames = new HashSet(s_topLevelSingleUseTagNames); tagNames.RemoveAll(GetExistingTopLevelElementNames(syntax).WhereNotNull()); return tagNames.Select(GetItem); } protected IEnumerable GetListItems() { - return new[] { ListHeaderTagName, TermTagName, ItemTagName, DescriptionTagName }.Select(GetItem); + return s_listTagNames.Select(GetItem); } protected IEnumerable GetListHeaderItems() { - return new[] { TermTagName, DescriptionTagName }.Select(GetItem); + return s_listHeaderTagNames.Select(GetItem); } protected IEnumerable GetItemsForSymbol(ISymbol symbol, TSyntax syntax) @@ -257,20 +214,20 @@ protected IEnumerable GetItemsForSymbol(ISymbol symbol, TSyntax if (symbol != null) { - items.AddRange(GetParameterItems(symbol.GetParameters(), syntax, ParamTagName)); - items.AddRange(GetParameterItems(symbol.GetTypeParameters(), syntax, TypeParamTagName)); + items.AddRange(GetParameterItems(symbol.GetParameters(), syntax, ParameterElementName)); + items.AddRange(GetParameterItems(symbol.GetTypeParameters(), syntax, TypeParameterElementName)); var property = symbol as IPropertySymbol; - if (property != null && !HasExistingTopLevelElement(syntax, ValueTagName)) + if (property != null && !HasExistingTopLevelElement(syntax, ValueElementName)) { - items.Add(GetItem(ValueTagName)); + items.Add(GetItem(ValueElementName)); } var method = symbol as IMethodSymbol; var returns = method != null && !method.ReturnsVoid; - if (returns && !HasExistingTopLevelElement(syntax, ReturnsTagName)) + if (returns && !HasExistingTopLevelElement(syntax, ReturnsElementName)) { - items.Add(GetItem(ReturnsTagName)); + items.Add(GetItem(ReturnsElementName)); } } diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.vb index 3c9fd15db473d74b54ac639a61a87b573c0ce334..b2c7dc8bf9fab427cb95f4b4fc1a6cbb8a0c481e 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.vb @@ -6,6 +6,7 @@ Imports Microsoft.CodeAnalysis.Completion.Providers Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Roslyn.Utilities.DocumentationCommentXmlNames Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Partial Friend Class XmlDocCommentCompletionProvider @@ -101,23 +102,23 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Dim grandParent = parentElement.Parent If grandParent.IsKind(SyntaxKind.XmlElement) Then - items.AddRange(GetNestedTags(symbol)) + items.AddRange(GetNestedItems(symbol)) - If GetStartTagName(grandParent) = ListTagName Then + If GetStartTagName(grandParent) = ListElementName Then items.AddRange(GetListItems()) End If - If GetStartTagName(grandParent) = ListHeaderTagName Then + If GetStartTagName(grandParent) = ListHeaderElementName Then items.AddRange(GetListHeaderItems()) End If ElseIf token.Parent.IsKind(SyntaxKind.XmlText) AndAlso token.Parent.Parent.IsKind(SyntaxKind.XmlElement) Then - items.AddRange(GetNestedTags(symbol)) + items.AddRange(GetNestedItems(symbol)) - If GetStartTagName(token.Parent.Parent) = ListTagName Then + If GetStartTagName(token.Parent.Parent) = ListElementName Then items.AddRange(GetListItems()) End If - If GetStartTagName(token.Parent.Parent) = ListHeaderTagName Then + If GetStartTagName(token.Parent.Parent) = ListHeaderElementName Then items.AddRange(GetListHeaderItems()) End If ElseIf grandParent.IsKind(SyntaxKind.DocumentationCommentTrivia) Then @@ -128,11 +129,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers If token.Parent.IsKind(SyntaxKind.XmlElementStartTag, SyntaxKind.XmlName) Then If parentElement.IsParentKind(SyntaxKind.XmlElement) Then - If GetStartTagName(parentElement.Parent) = ListTagName Then + If GetStartTagName(parentElement.Parent) = ListElementName Then items.AddRange(GetListItems()) End If - If GetStartTagName(parentElement.Parent) = ListHeaderTagName Then + If GetStartTagName(parentElement.Parent) = ListHeaderElementName Then items.AddRange(GetListHeaderItems()) End If End If @@ -229,7 +230,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers End Sub Protected Overrides Function GetKeywordNames() As IEnumerable(Of String) - Return SyntaxFacts.GetKeywordKinds().Select(Function(keyword) SyntaxFacts.GetText(keyword)) + Return SyntaxFacts.GetKeywordKinds().Select(AddressOf SyntaxFacts.GetText) End Function Protected Overrides Function GetExistingTopLevelElementNames(parentTrivia As DocumentationCommentTriviaSyntax) As IEnumerable(Of String)