提交 386dd3b5 编写于 作者: G Gen Lu

Fix completion of ext-method for receiver of type parameter type

上级 ca892c8d
......@@ -1491,6 +1491,52 @@ public void M(int{rank} x)
inlineDescription: "Foo");
}
[InlineData(ReferenceType.Project)]
[InlineData(ReferenceType.Metadata)]
[Theory, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TestGenericReceiverTypeWithConstraint(ReferenceType refType)
{
var refDoc = @"
using System;
namespace NS1
{
public class C1 {}
}
namespace NS2
{
public static class Extensions
{
public static bool ExtentionMethod(this NS1.C1 c) => false;
}
}";
var srcDoc = @"
namespace NS1
{
public class C2
{
public void M<T>(T x) where T : C1
{
x.$$
}
}
}";
var markup = refType switch
{
ReferenceType.Project => CreateMarkupForProjectWithProjectReference(srcDoc, refDoc, LanguageNames.CSharp, LanguageNames.CSharp),
ReferenceType.Metadata => CreateMarkupForProjectWithMetadataReference(srcDoc, refDoc, LanguageNames.CSharp, LanguageNames.CSharp),
_ => null,
};
await VerifyImportItemExistsAsync(
markup,
"ExtentionMethod",
glyph: (int)Glyph.ExtensionMethodPublic,
inlineDescription: "NS2");
}
private Task VerifyImportItemExistsAsync(string markup, string expectedItem, int glyph, string inlineDescription, string displayTextSuffix = null, string expectedDescriptionOrNull = null)
=> VerifyItemExistsAsync(markup, expectedItem, displayTextSuffix: displayTextSuffix, glyph: glyph, inlineDescription: inlineDescription, expectedDescriptionOrNull: expectedDescriptionOrNull);
......
......@@ -75,18 +75,31 @@ async Task<(ImmutableArray<SerializableImportCompletionItem>, StatisticCounter)>
private static ImmutableArray<string> GetReceiverTypeNames(ITypeSymbol receiverTypeSymbol)
{
using var _ = PooledHashSet<string>.GetInstance(out var allTypeNamesBuilder);
AddNamesForTypeWorker(receiverTypeSymbol, allTypeNamesBuilder);
return allTypeNamesBuilder.ToImmutableArray();
allTypeNamesBuilder.Add(GetReceiverTypeName(receiverTypeSymbol));
allTypeNamesBuilder.AddRange(receiverTypeSymbol.GetBaseTypes().Select(t => t.MetadataName));
allTypeNamesBuilder.AddRange(receiverTypeSymbol.GetAllInterfacesIncludingThis().Select(t => t.MetadataName));
// interface doesn't inherit from object, but is implicitly convertible to object type.
if (receiverTypeSymbol.IsInterfaceType())
static void AddNamesForTypeWorker(ITypeSymbol receiverTypeSymbol, PooledHashSet<string> builder)
{
allTypeNamesBuilder.Add(nameof(Object));
}
if (receiverTypeSymbol is ITypeParameterSymbol typeParameter)
{
foreach (var constraintType in typeParameter.ConstraintTypes)
{
AddNamesForTypeWorker(constraintType, builder);
}
}
else
{
builder.Add(GetReceiverTypeName(receiverTypeSymbol));
builder.AddRange(receiverTypeSymbol.GetBaseTypes().Select(t => t.MetadataName));
builder.AddRange(receiverTypeSymbol.GetAllInterfacesIncludingThis().Select(t => t.MetadataName));
return allTypeNamesBuilder.ToImmutableArray();
// interface doesn't inherit from object, but is implicitly convertible to object type.
if (receiverTypeSymbol.IsInterfaceType())
{
builder.Add(nameof(Object));
}
}
}
}
private static string GetReceiverTypeName(ITypeSymbol typeSymbol)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册