Skip to content

Commit 2a98d64

Browse files
authored
Odd IntelliSense Behavior with Overloaded Methods (#36293)
1 parent 0d44ad1 commit 2a98d64

File tree

2 files changed

+74
-35
lines changed

2 files changed

+74
-35
lines changed

src/EditorFeatures/Test2/IntelliSense/CSharpCompletionCommandHandlerTests.vb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5254,6 +5254,35 @@ class C
52545254
End Using
52555255
End Function
52565256

5257+
<WorkItem(36187, "https://github.com/dotnet/roslyn/issues/36187")>
5258+
<MemberData(NameOf(AllCompletionImplementations))>
5259+
<WpfTheory, Trait(Traits.Feature, Traits.Features.Completion), Trait(Traits.Feature, Traits.Features.CodeActionsUseRangeOperator)>
5260+
Public Async Function CompletionWithTwoOverloadsOneOfThemIsEmpty(completionImplementation As CompletionImplementation) As Task
5261+
Using state = TestStateFactory.CreateCSharpTestState(completionImplementation,
5262+
<Document><![CDATA[
5263+
class C
5264+
{
5265+
private enum A
5266+
{
5267+
A,
5268+
B,
5269+
}
5270+
5271+
private void Get(string a) { }
5272+
private void Get(A a) { }
5273+
5274+
private void Test()
5275+
{
5276+
Get$$
5277+
}
5278+
}
5279+
]]></Document>)
5280+
5281+
state.SendTypeChars("(")
5282+
Await state.AssertSelectedCompletionItem(displayText:="A", isHardSelected:=True)
5283+
End Using
5284+
End Function
5285+
52575286
Private Class MultipleChangeCompletionProvider
52585287
Inherits CompletionProvider
52595288

src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Linq;
55
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis;
67
using Microsoft.CodeAnalysis.Completion;
78
using Microsoft.CodeAnalysis.Completion.Providers;
89
using Microsoft.CodeAnalysis.CSharp.Extensions;
@@ -74,56 +75,65 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
7475

7576
var span = new TextSpan(position, 0);
7677
var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);
77-
var type = typeInferenceService.InferType(semanticModel, position,
78-
objectAsDefault: true,
78+
var types = typeInferenceService.InferTypes(semanticModel, position,
7979
cancellationToken: cancellationToken);
8080

81-
// If we have a Nullable<T>, unwrap it.
82-
if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
81+
if (types.Length == 0)
8382
{
84-
type = type.GetTypeArguments().FirstOrDefault();
85-
86-
if (type == null)
87-
{
88-
return;
89-
}
83+
types = ImmutableArray.Create<ITypeSymbol>(semanticModel.Compilation.ObjectType);
9084
}
9185

92-
if (type.TypeKind != TypeKind.Enum)
86+
foreach (var typeIterator in types)
9387
{
94-
type = TryGetEnumTypeInEnumInitializer(semanticModel, token, type, cancellationToken) ??
95-
TryGetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
88+
var type = typeIterator;
9689

97-
if (type == null)
90+
// If we have a Nullable<T>, unwrap it.
91+
if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
9892
{
99-
return;
93+
type = type.GetTypeArguments().FirstOrDefault();
94+
95+
if (type == null)
96+
{
97+
continue;
98+
}
10099
}
101-
}
102100

103-
if (!type.IsEditorBrowsable(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation))
104-
{
105-
return;
106-
}
101+
if (type.TypeKind != TypeKind.Enum)
102+
{
103+
type = TryGetEnumTypeInEnumInitializer(semanticModel, token, type, cancellationToken) ??
104+
TryGetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
107105

108-
// Does type have any aliases?
109-
var alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);
106+
if (type == null)
107+
{
108+
continue;
109+
}
110+
}
110111

111-
var displayService = document.GetLanguageService<ISymbolDisplayService>();
112-
var displayText = alias != null
113-
? alias.Name
114-
: displayService.ToMinimalDisplayString(semanticModel, position, type);
112+
if (!type.IsEditorBrowsable(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation))
113+
{
114+
continue;
115+
}
115116

116-
var workspace = document.Project.Solution.Workspace;
117-
var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
117+
// Does type have any aliases?
118+
var alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);
118119

119-
var item = SymbolCompletionItem.CreateWithSymbolId(
120-
displayText: displayText,
121-
displayTextSuffix: "",
122-
symbols: ImmutableArray.Create(alias ?? type),
123-
rules: s_rules.WithMatchPriority(MatchPriority.Preselect),
124-
contextPosition: position);
120+
var displayService = document.GetLanguageService<ISymbolDisplayService>();
121+
var displayText = alias != null
122+
? alias.Name
123+
: displayService.ToMinimalDisplayString(semanticModel, position, type);
125124

126-
context.AddItem(item);
125+
var workspace = document.Project.Solution.Workspace;
126+
var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
127+
128+
var item = SymbolCompletionItem.CreateWithSymbolId(
129+
displayText: displayText,
130+
displayTextSuffix: "",
131+
symbols: ImmutableArray.Create(alias ?? type),
132+
rules: s_rules.WithMatchPriority(MatchPriority.Preselect),
133+
contextPosition: position);
134+
135+
context.AddItem(item);
136+
}
127137
}
128138
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
129139
{

0 commit comments

Comments
 (0)