提交 1e1a7d25 编写于 作者: R Ravi Chande

Include the non-special type names for special types in cref completion

上级 c337a61f
...@@ -443,5 +443,22 @@ class C ...@@ -443,5 +443,22 @@ class C
Assert.True(called); Assert.True(called);
} }
} }
[WorkItem(16060, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/16060")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task SpecialTypeNames()
{
var text = @"
using System;
/// <see cref=""$$""/>
class C
{
public void foo(int x) { }
}
";
await VerifyItemExistsAsync(text, "uint");
await VerifyItemExistsAsync(text, "UInt32");
}
} }
} }
\ No newline at end of file
...@@ -42,6 +42,16 @@ internal sealed class CrefCompletionProvider : AbstractCrefCompletionProvider ...@@ -42,6 +42,16 @@ internal sealed class CrefCompletionProvider : AbstractCrefCompletionProvider
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes); SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
public static readonly SymbolDisplayFormat SpecialTypeCrefFormat =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
propertyStyle: SymbolDisplayPropertyStyle.NameOnly,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
parameterOptions: SymbolDisplayParameterOptions.None,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers);
private readonly Action<SyntaxNode> _testSpeculativeNodeCallbackOpt; private readonly Action<SyntaxNode> _testSpeculativeNodeCallbackOpt;
public CrefCompletionProvider(Action<SyntaxNode> testSpeculativeNodeCallbackOpt = null) public CrefCompletionProvider(Action<SyntaxNode> testSpeculativeNodeCallbackOpt = null)
...@@ -251,8 +261,11 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position) ...@@ -251,8 +261,11 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
{ {
foreach (var symbol in symbols) foreach (var symbol in symbols)
{ {
builder.Clear();
yield return CreateItem(workspace, semanticModel, symbol, token, position, builder, options); yield return CreateItem(workspace, semanticModel, symbol, token, position, builder, options);
if (TryCreateSpecialTypeItem(workspace, semanticModel, symbol, token, position, builder, options, out var item))
{
yield return item;
}
} }
} }
finally finally
...@@ -261,20 +274,42 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position) ...@@ -261,20 +274,42 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
} }
} }
private bool TryCreateSpecialTypeItem(
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, int position, StringBuilder builder,
ImmutableDictionary<string, string> options, out CompletionItem item)
{
var typeSymbol = symbol as ITypeSymbol;
if (typeSymbol.IsSpecialType())
{
item = CreateItem(workspace, semanticModel, symbol, token, position, builder, options, SpecialTypeCrefFormat);
return true;
}
item = null;
return false;
}
private CompletionItem CreateItem( private CompletionItem CreateItem(
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, int position, StringBuilder builder, ImmutableDictionary<string, string> options) Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, int position, StringBuilder builder, ImmutableDictionary<string, string> options)
{ {
return CreateItem(workspace, semanticModel, symbol, token, position, builder, options, CrefFormat);
}
private CompletionItem CreateItem(
Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, int position, StringBuilder builder, ImmutableDictionary<string, string> options,
SymbolDisplayFormat unqualifiedCrefFormat)
{
builder.Clear();
if (symbol is INamespaceOrTypeSymbol && token.IsKind(SyntaxKind.DotToken)) if (symbol is INamespaceOrTypeSymbol && token.IsKind(SyntaxKind.DotToken))
{ {
// Handle qualified namespace and type names. // Handle qualified namespace and type names.
builder.Append(symbol.ToDisplayString(QualifiedCrefFormat)); builder.Append(symbol.ToDisplayString(QualifiedCrefFormat));
} }
else else
{ {
// Handle unqualified namespace and type names, or member names. // Handle unqualified namespace and type names, or member names.
builder.Append(symbol.ToMinimalDisplayString(semanticModel, token.SpanStart, CrefFormat)); builder.Append(symbol.ToMinimalDisplayString(semanticModel, token.SpanStart, unqualifiedCrefFormat));
var parameters = symbol.GetParameters(); var parameters = symbol.GetParameters();
if (!parameters.IsDefaultOrEmpty) if (!parameters.IsDefaultOrEmpty)
...@@ -308,6 +343,11 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position) ...@@ -308,6 +343,11 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position)
} }
} }
return CreateItemFromBuilder(symbol, position, builder, options);
}
private CompletionItem CreateItemFromBuilder(ISymbol symbol, int position, StringBuilder builder, ImmutableDictionary<string, string> options)
{
var symbolText = builder.ToString(); var symbolText = builder.ToString();
var insertionText = builder var insertionText = builder
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册