提交 17b81562 编写于 作者: C CyrusNajmabadi

Offer enum completion inside an enum member's initializer

上级 6a463b29
......@@ -16,9 +16,7 @@ public EnumAndCompletionListTagCompletionProviderTests(CSharpTestWorkspaceFixtur
}
internal override CompletionProvider CreateCompletionProvider()
{
return new EnumAndCompletionListTagCompletionProvider();
}
=> new EnumAndCompletionListTagCompletionProvider();
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NullableEnum()
......@@ -518,5 +516,85 @@ enum E
";
await VerifyNoItemsExistAsync(markup);
}
[WorkItem(5419, "https://github.com/dotnet/roslyn/issues/5419")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TestInEnumInitializer1()
{
var markup =
@"using System;
[Flags]
internal enum ProjectTreeWriterOptions
{
None,
Tags,
FilePath,
Capabilities,
Visibility,
AllProperties = FilePath | Visibility | $$
}";
await VerifyItemExistsAsync(markup, "ProjectTreeWriterOptions");
}
[WorkItem(5419, "https://github.com/dotnet/roslyn/issues/5419")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TestInEnumInitializer2()
{
var markup =
@"using System;
[Flags]
internal enum ProjectTreeWriterOptions
{
None,
Tags,
FilePath,
Capabilities,
Visibility,
AllProperties = FilePath | $$ Visibility
}";
await VerifyItemExistsAsync(markup, "ProjectTreeWriterOptions");
}
[WorkItem(5419, "https://github.com/dotnet/roslyn/issues/5419")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TestInEnumInitializer3()
{
var markup =
@"using System;
[Flags]
internal enum ProjectTreeWriterOptions
{
None,
Tags,
FilePath,
Capabilities,
Visibility,
AllProperties = FilePath ^ $$
}";
await VerifyItemExistsAsync(markup, "ProjectTreeWriterOptions");
}
[WorkItem(5419, "https://github.com/dotnet/roslyn/issues/5419")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TestInEnumInitializer4()
{
var markup =
@"using System;
[Flags]
internal enum ProjectTreeWriterOptions
{
None,
Tags,
FilePath,
Capabilities,
Visibility,
AllProperties = FilePath & $$
}";
await VerifyItemExistsAsync(markup, "ProjectTreeWriterOptions");
}
}
}
}
\ No newline at end of file
......@@ -91,20 +91,30 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
if (type.TypeKind != TypeKind.Enum)
{
type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
var enumType = TryGetEnumTypeInEnumInitializer(semanticModel, token, type, cancellationToken);
if (enumType != null)
{
type = enumType;
}
if (type == null)
{
return;
type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
}
}
if (type == null)
{
return;
}
if (!type.IsEditorBrowsable(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation))
{
return;
}
// Does type have any aliases?
ISymbol alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);
var alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);
var displayService = document.GetLanguageService<ISymbolDisplayService>();
var displayText = alias != null
......@@ -128,6 +138,49 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
}
}
private ITypeSymbol TryGetEnumTypeInEnumInitializer(
SemanticModel semanticModel, SyntaxToken token,
ITypeSymbol type, CancellationToken cancellationToken)
{
// https://github.com/dotnet/roslyn/issues/5419
//
// 14.3: "Within an enum member initializer, values of other enum members are always
// treated as having the type of their underlying type"
if (token.Kind() != SyntaxKind.BarToken &&
token.Kind() != SyntaxKind.AmpersandToken &&
token.Kind() != SyntaxKind.CaretToken)
{
return null;
}
var containingType = semanticModel.GetEnclosingNamedType(token.SpanStart, cancellationToken);
if (containingType?.TypeKind != TypeKind.Enum)
{
return null;
}
if (!type.Equals(containingType.EnumUnderlyingType))
{
return null;
}
var previousToken = token.GetPreviousToken();
var symbol = semanticModel.GetSymbolInfo(previousToken.Parent, cancellationToken).Symbol;
if (symbol?.Kind != SymbolKind.Field)
{
return null;
}
if (!containingType.Equals(symbol.ContainingType))
{
return null;
}
return containingType;
}
protected override Task<CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
=> SymbolCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册