未验证 提交 1e8d4d20 编写于 作者: I Ivan Basov 提交者: GitHub

supporting types from params in intellisense (#36040)

上级 699318cf
......@@ -10148,6 +10148,73 @@ public void Test()
await VerifyItemIsAbsentAsync(markup, "Target");
}
[WorkItem(36029, "https://github.com/dotnet/roslyn/issues/36029")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CompletionInsideMethodWithParamsBeforeParams()
{
var markup = @"
using System;
class C
{
void M()
{
Goo(builder =>
{
builder.$$
});
}
void Goo(Action<Builder> action, params Action<AnotherBuilder>[] otherActions)
{
}
}
class Builder
{
public int Something { get; set; }
};
class AnotherBuilder
{
public int AnotherSomething { get; set; }
}";
await VerifyItemIsAbsentAsync(markup, "AnotherSomething");
await VerifyItemIsAbsentAsync(markup, "FirstOrDefault");
await VerifyItemExistsAsync(markup, "Something");
}
[WorkItem(36029, "https://github.com/dotnet/roslyn/issues/36029")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CompletionInsideMethodWithParamsInParams()
{
var markup = @"
using System;
class C
{
void M()
{
Goo(b0 => { }, b1 => {}, b2 => { b2.$$ });
}
void Goo(Action<Builder> action, params Action<AnotherBuilder>[] otherActions)
{
}
}
class Builder
{
public int Something { get; set; }
};
class AnotherBuilder
{
public int AnotherSomething { get; set; }
}";
await VerifyItemIsAbsentAsync(markup, "Something");
await VerifyItemIsAbsentAsync(markup, "FirstOrDefault");
await VerifyItemExistsAsync(markup, "AnotherSomething");
}
[Fact, Trait(Traits.Feature, Traits.Features.TargetTypedCompletion)]
public async Task TestTargetTypeFilterWithExperimentEnabled()
{
......
......@@ -8169,6 +8169,64 @@ End Module
Await VerifyItemIsAbsentAsync(source, "Target")
End Function
<WorkItem(36029, "https://github.com/dotnet/roslyn/issues/36029")>
<Fact, Trait(Traits.Feature, Traits.Features.TargetTypedCompletion)>
Public Async Function CompletionInsideMethodWithParamsBeforeParams() As Task
Dim source =
<code><![CDATA[
Imports System
Class C
Sub M()
Goo(Sub(b) b.$$)
End Sub
Sub Goo(action As Action(Of Builder), ParamArray otherActions() As Action(Of AnotherBuilder))
End Sub
End Class
Class Builder
Public Something As Integer
End Class
Class AnotherBuilder
Public AnotherSomething As Integer
End Class
]]></code>.Value
Await VerifyItemIsAbsentAsync(source, "AnotherSomething")
Await VerifyItemIsAbsentAsync(source, "FirstOrDefault")
Await VerifyItemExistsAsync(source, "Something")
End Function
<WorkItem(36029, "https://github.com/dotnet/roslyn/issues/36029")>
<Fact, Trait(Traits.Feature, Traits.Features.TargetTypedCompletion)>
Public Async Function CompletionInsideMethodWithParamsInParams() As Task
Dim source =
<code><![CDATA[
Imports System
Class C
Sub M()
Goo(Nothing, Nothing, Sub(b) b.$$)
End Sub
Sub Goo(action As Action(Of Builder), ParamArray otherActions() As Action(Of AnotherBuilder))
End Sub
End Class
Class Builder
Public Something As Integer
End Class
Class AnotherBuilder
Public AnotherSomething As Integer
End Class
]]></code>.Value
Await VerifyItemIsAbsentAsync(source, "Something")
Await VerifyItemIsAbsentAsync(source, "FirstOrDefault")
Await VerifyItemExistsAsync(source, "AnotherSomething")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.TargetTypedCompletion)>
Public Async Function TestTargetTypeFilterWithExperimentEnabled() As Task
SetExperimentOption(WellKnownExperimentNames.TargetTypedCompletionFilter, True)
......
......@@ -99,43 +99,60 @@ private ImmutableArray<ITypeSymbol> GetTypeSymbols(ImmutableArray<ISymbol> candi
{
if (candidateSymbol is IMethodSymbol method)
{
if (method.Parameters.Length > ordinalInInvocation)
ITypeSymbol type;
if (method.IsParams() && (ordinalInInvocation >= method.Parameters.Length - 1))
{
var type = method.Parameters[ordinalInInvocation].Type;
// If type is <see cref="Expression{TDelegate}"/>, ignore <see cref="Expression"/> and use TDelegate.
// Ignore this check if expressionSymbol is null, e.g. semantic model is broken or incomplete or if the framework does not contain <see cref="Expression"/>.
if (expressionSymbol != null &&
type is INamedTypeSymbol expressionSymbolNamedTypeCandidate &&
expressionSymbolNamedTypeCandidate.OriginalDefinition.Equals(expressionSymbol))
if (method.Parameters.LastOrDefault()?.Type is IArrayTypeSymbol arrayType)
{
var allTypeArguments = type.GetAllTypeArguments();
if (allTypeArguments.Length != 1)
{
continue;
}
type = arrayType.ElementType;
}
else
{
continue;
}
}
else if (ordinalInInvocation < method.Parameters.Length)
{
type = method.Parameters[ordinalInInvocation].Type;
}
else
{
continue;
}
type = allTypeArguments[0];
// If type is <see cref="Expression{TDelegate}"/>, ignore <see cref="Expression"/> and use TDelegate.
// Ignore this check if expressionSymbol is null, e.g. semantic model is broken or incomplete or if the framework does not contain <see cref="Expression"/>.
if (expressionSymbol != null &&
type is INamedTypeSymbol expressionSymbolNamedTypeCandidate &&
expressionSymbolNamedTypeCandidate.OriginalDefinition.Equals(expressionSymbol))
{
var allTypeArguments = type.GetAllTypeArguments();
if (allTypeArguments.Length != 1)
{
continue;
}
type = allTypeArguments[0];
}
if (type.IsDelegateType())
{
var methods = type.GetMembers(WellKnownMemberNames.DelegateInvokeName);
if (methods.Length != 1)
{
continue;
}
if (type.IsDelegateType())
var parameters = methods[0].GetParameters();
if (parameters.Length <= ordinalInLambda)
{
var methods = type.GetMembers(WellKnownMemberNames.DelegateInvokeName);
if (methods.Length != 1)
{
continue;
}
var parameters = methods[0].GetParameters();
if (parameters.Length <= ordinalInLambda)
{
continue;
}
type = parameters[ordinalInLambda].Type;
continue;
}
builder.Add(type);
type = parameters[ordinalInLambda].Type;
}
builder.Add(type);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册