提交 8c6fd872 编写于 作者: D Dustin Campbell

Unify constants for tag and attribute names across C# and VB XML doc comment completion providers

上级 9b9ad519
......@@ -78,7 +78,7 @@ protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(D
items.AddRange(GetNestedTags(span));
}
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "list")
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListTagName)
{
items.AddRange(GetListItems(span));
}
......@@ -86,13 +86,13 @@ protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(D
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 == "list")
if (element.StartTag.Name.LocalName.ValueText == ListTagName)
{
items.AddRange(GetListItems(span));
}
}
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "listheader")
if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == ListHeaderTagName)
{
items.AddRange(GetListHeaderItems(span));
}
......@@ -108,12 +108,12 @@ protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(D
{
var startTag = (XmlElementStartTagSyntax)token.Parent;
if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "list")
if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListTagName)
{
items.AddRange(GetListItems(span));
}
if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "listheader")
if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == ListHeaderTagName)
{
items.AddRange(GetListHeaderItems(span));
}
......@@ -125,7 +125,7 @@ protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(D
private IEnumerable<CompletionItem> GetTopLevelSingleUseNames(DocumentationCommentTriviaSyntax parentTrivia, TextSpan span)
{
var names = new HashSet<string>(new[] { "summary", "remarks", "example", "completionlist" });
var names = new HashSet<string>(new[] { SummaryTagName, RemarksTagName, ExampleTagName, CompletionListTagName });
RemoveExistingTags(parentTrivia, names, (x) => x.StartTag.Name.LocalName.ValueText);
......@@ -173,11 +173,11 @@ private IEnumerable<CompletionItem> GetTagsForType(INamedTypeSymbol symbol, Text
var typeParameters = symbol.TypeParameters.Select(p => p.Name).ToSet();
RemoveExistingTags(trivia, typeParameters, x => AttributeSelector(x, "typeparam"));
RemoveExistingTags(trivia, typeParameters, x => AttributeSelector(x, TypeParamTagName));
items.AddRange(typeParameters.Select(t => new XmlDocCommentCompletionItem(this,
filterSpan,
FormatParameter("typeparam", t), GetCompletionItemRules())));
FormatParameter(TypeParamTagName, t), GetCompletionItemRules())));
return items;
}
......@@ -186,7 +186,7 @@ private string AttributeSelector(XmlElementSyntax element, string attribute)
if (!element.StartTag.IsMissing && !element.EndTag.IsMissing)
{
var startTag = element.StartTag;
var nameAttribute = startTag.Attributes.OfType<XmlNameAttributeSyntax>().FirstOrDefault(a => a.Name.LocalName.ValueText == "name");
var nameAttribute = startTag.Attributes.OfType<XmlNameAttributeSyntax>().FirstOrDefault(a => a.Name.LocalName.ValueText == NameAttributeName);
if (nameAttribute != null)
{
if (startTag.Name.LocalName.ValueText == attribute)
......@@ -220,7 +220,7 @@ private IEnumerable<XmlDocCommentCompletionItem> GetTagsForProperty(IPropertySym
}
// We're writing the name of a paramref
if (parentElementName == "paramref")
if (parentElementName == ParamRefTagName)
{
items.AddRange(parameters.Select(p => new XmlDocCommentCompletionItem(this, filterSpan, p, GetCompletionItemRules())));
}
......@@ -228,12 +228,12 @@ private IEnumerable<XmlDocCommentCompletionItem> GetTagsForProperty(IPropertySym
return items;
}
RemoveExistingTags(trivia, parameters, x => AttributeSelector(x, "param"));
items.AddRange(parameters.Select(p => new XmlDocCommentCompletionItem(this, filterSpan, FormatParameter("param", p), GetCompletionItemRules())));
RemoveExistingTags(trivia, parameters, x => AttributeSelector(x, ParamTagName));
items.AddRange(parameters.Select(p => new XmlDocCommentCompletionItem(this, filterSpan, FormatParameter(ParamTagName, p), GetCompletionItemRules())));
}
var typeParameters = symbol.GetTypeArguments().Select(p => p.Name).ToSet();
items.AddRange(typeParameters.Select(t => new XmlDocCommentCompletionItem(this, filterSpan, "typeparam", "name", t, GetCompletionItemRules())));
items.AddRange(typeParameters.Select(t => new XmlDocCommentCompletionItem(this, filterSpan, TypeParamTagName, NameAttributeName, t, GetCompletionItemRules())));
items.Add(new XmlDocCommentCompletionItem(this, filterSpan, "value", GetCompletionItemRules()));
return items;
}
......@@ -258,11 +258,11 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
}
// We're writing the name of a paramref or typeparamref
if (parentElementName == "paramref")
if (parentElementName == ParamRefTagName)
{
items.AddRange(parameters.Select(p => new XmlDocCommentCompletionItem(this, filterSpan, p, GetCompletionItemRules())));
}
else if (parentElementName == "typeparamref")
else if (parentElementName == TypeParamRefTagName)
{
items.AddRange(typeParameters.Select(t => new XmlDocCommentCompletionItem(this, filterSpan, t, GetCompletionItemRules())));
}
......@@ -272,8 +272,8 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
var returns = true;
RemoveExistingTags(trivia, parameters, x => AttributeSelector(x, "param"));
RemoveExistingTags(trivia, typeParameters, x => AttributeSelector(x, "typeparam"));
RemoveExistingTags(trivia, parameters, x => AttributeSelector(x, ParamTagName));
RemoveExistingTags(trivia, typeParameters, x => AttributeSelector(x, TypeParamTagName));
foreach (var node in trivia.Content)
{
......@@ -282,7 +282,7 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
{
var startTag = element.StartTag;
if (startTag.Name.LocalName.ValueText == "returns")
if (startTag.Name.LocalName.ValueText == ReturnsTagName)
{
returns = false;
break;
......@@ -290,12 +290,12 @@ private IEnumerable<CompletionItem> GetTagsForMethod(IMethodSymbol symbol, TextS
}
}
items.AddRange(parameters.Select(p => new XmlDocCommentCompletionItem(this, filterSpan, FormatParameter("param", p), GetCompletionItemRules())));
items.AddRange(typeParameters.Select(t => new XmlDocCommentCompletionItem(this, filterSpan, FormatParameter("typeparam", t), GetCompletionItemRules())));
items.AddRange(parameters.Select(p => new XmlDocCommentCompletionItem(this, filterSpan, FormatParameter(ParamTagName, p), GetCompletionItemRules())));
items.AddRange(typeParameters.Select(t => new XmlDocCommentCompletionItem(this, filterSpan, FormatParameter(TypeParamTagName, t), GetCompletionItemRules())));
if (returns && !symbol.ReturnsVoid)
{
items.Add(new XmlDocCommentCompletionItem(this, filterSpan, "returns", GetCompletionItemRules()));
items.Add(new XmlDocCommentCompletionItem(this, filterSpan, ReturnsTagName, GetCompletionItemRules()));
}
return items;
......
......@@ -14,33 +14,67 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion.C
{
internal abstract class AbstractDocCommentCompletionProvider : CompletionListProvider, ICustomCommitCompletionProvider
{
// Tag names
protected const string CDataPrefixTagName = "![CDATA[";
protected const string CTagName = "c";
protected const string CodeTagName = "code";
protected const string CommentPrefixTagName = "!--";
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 NameAttributeName = "name";
protected const string PathAttributeName = "path";
protected const string TypeAttributeName = "type";
private readonly Dictionary<string, string[]> _tagMap =
new Dictionary<string, string[]>
{
{ "exception", new[] { "<exception cref=\"", "\"" } },
{ "!--", new[] { "<!--", "-->" } },
{ "![CDATA[", new[] { "<![CDATA[", "]]>" } },
{ "include", new[] { "<include file=\'", "\' path=\'[@name=\"\"]\'/>" } },
{ "permission", new[] { "<permission cref=\"", "\"" } },
{ "see", new[] { "<see cref=\"", "\"/>" } },
{ "seealso", new[] { "<seealso cref=\"", "\"/>" } },
{ "list", new[] { "<list type=\"", "\"" } },
{ "paramref", new[] { "<paramref name=\"", "\"/>" } },
{ "typeparamref", new[] { "<typeparamref name=\"", "\"/>" } },
{ "completionlist", new[] { "<completionlist cref=\"", "\"/>" } },
{ ExceptionTagName, new[] { $"<{ExceptionTagName} {CrefAttributeName}=\"", "\"" } },
{ CommentPrefixTagName, new[] { $"<{CommentPrefixTagName}", "-->" } },
{ CDataPrefixTagName, new[] { $"<{CDataPrefixTagName}", "]]>" } },
{ IncludeTagName, new[] { $"<{IncludeTagName} {FileAttributeName}=\'", $"\' {PathAttributeName}=\'[@name=\"\"]\'/>" } },
{ PermissionTagName, new[] { $"<{PermissionTagName} {CrefAttributeName}=\"", "\"" } },
{ SeeTagName, new[] { $"<{SeeTagName} {CrefAttributeName}=\"", "\"/>" } },
{ SeeAlsoTagName, new[] { $"<{SeeAlsoTagName} {CrefAttributeName}=\"", "\"/>" } },
{ ListTagName, new[] { $"<{ListTagName} {TypeAttributeName}=\"", "\"" } },
{ ParamRefTagName, new[] { $"<{ParamRefTagName} {NameAttributeName}=\"", "\"/>" } },
{ TypeParamRefTagName, new[] { $"<{TypeParamRefTagName} {NameAttributeName}=\"", "\"/>" } },
{ CompletionListTagName, new[] { $"<{CompletionListTagName} {CrefAttributeName}=\"", "\"/>" } },
};
private readonly string[][] _attributeMap =
new[]
{
new[] { "exception", "cref", "cref=\"", "\"" },
new[] { "permission", "cref", "cref=\"", "\"" },
new[] { "see", "cref", "cref=\"", "\"" },
new[] { "seealso", "cref", "cref=\"", "\"" },
new[] { "list", "type", "type=\"", "\"" },
new[] { "param", "name", "name=\"", "\"" },
new[] { "include", "file", "file=\"", "\"" },
new[] { "include", "path", "path=\"", "\"" }
new[] { ExceptionTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" },
new[] { PermissionTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" },
new[] { SeeTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" },
new[] { SeeAlsoTagName, CrefAttributeName, $"{CrefAttributeName}=\"", "\"" },
new[] { ListTagName, TypeAttributeName, $"{TypeAttributeName}=\"", "\"" },
new[] { ParamTagName, NameAttributeName, $"{NameAttributeName}=\"", "\"" },
new[] { IncludeTagName, FileAttributeName, $"{FileAttributeName}=\"", "\"" },
new[] { IncludeTagName, PathAttributeName, $"{PathAttributeName}=\"", "\"" }
};
public override async Task ProduceCompletionListAsync(CompletionListContext context)
......@@ -79,37 +113,37 @@ protected IEnumerable<CompletionItem> GetAttributeItem(string n, TextSpan span)
protected IEnumerable<CompletionItem> GetAlwaysVisibleItems(TextSpan filterSpan)
{
return new[] { "see", "seealso", "![CDATA[", "!--" }
return new[] { SeeTagName, SeeAlsoTagName, CDataPrefixTagName, CommentPrefixTagName }
.Select(t => GetItem(t, filterSpan));
}
protected IEnumerable<CompletionItem> GetNestedTags(TextSpan filterSpan)
{
return new[] { "c", "code", "para", "list", "paramref", "typeparamref" }
return new[] { CTagName, CodeTagName, ParaTagName, ListTagName, ParamRefTagName, TypeParamRefTagName }
.Select(t => GetItem(t, filterSpan));
}
protected IEnumerable<CompletionItem> GetTopLevelRepeatableItems(TextSpan filterSpan)
{
return new[] { "exception", "include", "permission" }
return new[] { ExceptionTagName, IncludeTagName, PermissionTagName }
.Select(t => GetItem(t, filterSpan));
}
protected IEnumerable<CompletionItem> GetListItems(TextSpan span)
{
return new[] { "listheader", "term", "item", "description" }
return new[] { ListHeaderTagName, TermTagName, ItemTagName, DescriptionTagName }
.Select(t => GetItem(t, span));
}
protected IEnumerable<CompletionItem> GetListHeaderItems(TextSpan span)
{
return new[] { "term", "description" }
return new[] { TermTagName, DescriptionTagName }
.Select(t => GetItem(t, span));
}
protected string FormatParameter(string kind, string name)
{
return string.Format("{0} name=\"{1}\"", kind, name);
return $"{kind} {NameAttributeName}=\"{name}\"";
}
public void Commit(CompletionItem completionItem, ITextView textView, ITextBuffer subjectBuffer, ITextSnapshot triggerSnapshot, char? commitChar)
......
......@@ -14,25 +14,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Completion.CompletionProvide
Partial Friend Class XmlDocCommentCompletionProvider
Inherits AbstractDocCommentCompletionProvider
' Tag names
Private Const CompletionListTagName = "completionlist"
Private Const ExampleTagName = "example"
Private Const ExceptionTagName = "exception"
Private Const IncludeTagName = "include"
Private Const ParamTagName = "param"
Private Const PermissionTagName = "permission"
Private Const RemarksTagName = "remarks"
Private Const ReturnsTagName = "returns"
Private Const SummaryTagName = "summary"
Private Const TypeParamTagName = "typeparam"
Private Const ValueTagName = "value"
' Attribute names
Private Const CrefAttributeName = "cref"
Private Const ListTagName = "list"
Private Const ListHeaderTagName = "listheader"
Private Const NameAttributeName = "name"
Public Overrides Function IsTriggerCharacter(text As SourceText, characterPosition As Integer, options As OptionSet) As Boolean
Return text(characterPosition) = "<"c OrElse (text(characterPosition) = "/"c AndAlso characterPosition > 0 AndAlso text(characterPosition - 1) = "<"c)
End Function
......@@ -174,7 +155,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Completion.CompletionProvide
Dim nameToken = name.LocalName
If Not nameToken.IsMissing AndAlso nameToken.ValueText.Length > 0 Then
Return SpecializedCollections.SingletonEnumerable(Of CompletionItem)(New XmlDocCommentCompletionItem(Me, span, nameToken.ValueText, nameToken.ValueText + ">", String.Empty, GetCompletionItemRules()))
Return SpecializedCollections.SingletonEnumerable(Of CompletionItem)(New XmlDocCommentCompletionItem(Me, span, nameToken.ValueText, nameToken.ValueText & ">", String.Empty, GetCompletionItemRules()))
End If
Return Nothing
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册