提交 883f9e4b 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #19246 from CyrusNajmabadi/tupleTypeInference

Add type inference support for tuples.
......@@ -7262,7 +7262,7 @@ private object Method()
parseOptions: TestOptions.Regular);
}
[Fact/*(Skip = "https://github.com/dotnet/roslyn/issues/15508")*/, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)]
[WorkItem(14136, "https://github.com/dotnet/roslyn/issues/14136")]
public async Task TestDeconstruction4()
{
......@@ -7379,5 +7379,67 @@ public void Foo()
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)]
[WorkItem(18969, "https://github.com/dotnet/roslyn/issues/18969")]
public async Task TestTupleElement1()
{
await TestAsync(
@"using System;
class C
{
public void M1()
{
(int x, string y) t = ([|Method|](), null);
}
}",
@"using System;
class C
{
public void M1()
{
(int x, string y) t = (Method(), null);
}
private int Method()
{
throw new NotImplementedException();
}
}",
parseOptions: TestOptions.Regular);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)]
[WorkItem(18969, "https://github.com/dotnet/roslyn/issues/18969")]
public async Task TestTupleElement2()
{
await TestAsync(
@"using System;
class C
{
public void M1()
{
(int x, string y) t = (0, [|Method|]());
}
}",
@"using System;
class C
{
public void M1()
{
(int x, string y) t = (0, Method());
}
private string Method()
{
throw new NotImplementedException();
}
}",
parseOptions: TestOptions.Regular);
}
}
}
\ No newline at end of file
......@@ -3926,6 +3926,62 @@ Class Program
End Class")
End Function
<WorkItem(18969, "https://github.com/dotnet/roslyn/issues/18969")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)>
Public Async Function TupleElement1() As Task
Await TestInRegularAndScriptAsync(
"
Imports System
Public Class Q
Sub Main()
Dim x As (Integer, String) = ([|Foo|](), """")
End Sub
End Class
",
"
Imports System
Public Class Q
Sub Main()
Dim x As (Integer, String) = (Foo(), """")
End Sub
Private Function Foo() As Integer
Throw New NotImplementedException()
End Function
End Class
")
End Function
<WorkItem(18969, "https://github.com/dotnet/roslyn/issues/18969")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)>
Public Async Function TupleElement2() As Task
Await TestInRegularAndScriptAsync(
"
Imports System
Public Class Q
Sub Main()
Dim x As (Integer, String) = (0, [|Foo|]())
End Sub
End Class
",
"
Imports System
Public Class Q
Sub Main()
Dim x As (Integer, String) = (0, Foo())
End Sub
Private Function Foo() As String
Throw New NotImplementedException()
End Function
End Class
")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)>
Public Async Function MethodWithTupleWithNames() As Task
Await TestInRegularAndScriptAsync(
......
......@@ -310,6 +310,11 @@ private IEnumerable<TypeInferenceInfo> InferTypeInAnonymousObjectCreation(Anonym
return InferTypeInElementAccessExpression(elementAccess, index, argument);
}
if (argument.IsParentKind(SyntaxKind.TupleExpression))
{
return InferTypeInTupleExpression((TupleExpressionSyntax)argument.Parent, argument);
}
}
if (argument.Parent.IsParentKind(SyntaxKind.ImplicitElementAccess) &&
......@@ -331,6 +336,18 @@ private IEnumerable<TypeInferenceInfo> InferTypeInAnonymousObjectCreation(Anonym
return SpecializedCollections.EmptyEnumerable<TypeInferenceInfo>();
}
private IEnumerable<TypeInferenceInfo> InferTypeInTupleExpression(
TupleExpressionSyntax tupleExpression, ArgumentSyntax argument)
{
var index = tupleExpression.Arguments.IndexOf(argument);
var parentTypes = InferTypes(tupleExpression);
return parentTypes.Select(typeInfo => typeInfo.InferredType)
.OfType<INamedTypeSymbol>()
.Where(namedType => namedType.IsTupleType && index < namedType.TupleElements.Length)
.Select(tupleType => new TypeInferenceInfo(tupleType.TupleElements[index].Type));
}
private IEnumerable<TypeInferenceInfo> InferTypeInAttributeArgument(AttributeArgumentSyntax argument, SyntaxToken? previousToken = null, ArgumentSyntax argumentOpt = null)
{
if (previousToken.HasValue)
......
......@@ -53,7 +53,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return parent.TypeSwitch(
Function(addRemoveHandlerStatement As AddRemoveHandlerStatementSyntax) InferTypeInAddRemoveHandlerStatementSyntax(addRemoveHandlerStatement, expression),
Function(argument As ArgumentSyntax) InferTypeInArgumentList(TryCast(argument.Parent, ArgumentListSyntax), argument),
Function(argument As ArgumentSyntax) InferTypeInArgument(argument),
Function(arrayCreationExpression As ArrayCreationExpressionSyntax) InferTypeInArrayCreationExpression(arrayCreationExpression),
Function(arrayRank As ArrayRankSpecifierSyntax) InferTypeInArrayRankSpecifier(),
Function(arrayType As ArrayTypeSyntax) InferTypeInArrayType(arrayType),
......@@ -124,7 +124,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim parent = token.Parent
Return parent.TypeSwitch(
Function(argument As ArgumentSyntax) InferTypeInArgumentList(TryCast(argument.Parent, ArgumentListSyntax), previousToken:=token),
Function(argument As ArgumentSyntax) InferTypeInArgument(argument, previousToken:=token),
Function(argumentList As ArgumentListSyntax) InferTypeInArgumentList(argumentList, previousToken:=token),
Function(arrayCreationExpression As ArrayCreationExpressionSyntax) InferTypeInArrayCreationExpression(arrayCreationExpression),
Function(arrayRank As ArrayRankSpecifierSyntax) InferTypeInArrayRankSpecifier(),
......@@ -171,13 +171,42 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)())
End Function
Private Function InferTypeInArgument(argument As ArgumentSyntax,
Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo)
If TypeOf argument.Parent Is ArgumentListSyntax Then
Return InferTypeInArgumentList(
DirectCast(argument.Parent, ArgumentListSyntax), argument, previousToken)
End If
If TypeOf argument.Parent Is TupleExpressionSyntax Then
Return InferTypeInTupleExpression(
DirectCast(argument.Parent, TupleExpressionSyntax),
DirectCast(argument, SimpleArgumentSyntax))
End If
Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)
End Function
Private Function InferTypeInTupleExpression(tupleExpression As TupleExpressionSyntax,
argument As SimpleArgumentSyntax) As IEnumerable(Of TypeInferenceInfo)
Dim index = tupleExpression.Arguments.IndexOf(argument)
Dim parentTypes = InferTypes(tupleExpression)
Return parentTypes.Select(Function(TypeInfo) TypeInfo.InferredType).
OfType(Of INamedTypeSymbol)().
Where(Function(namedType) namedType.IsTupleType AndAlso index < namedType.TupleElements.Length).
Select(Function(tupleType) New TypeInferenceInfo(tupleType.TupleElements(index).Type))
End Function
Private Function InferTypeInArgumentList(argumentList As ArgumentListSyntax,
Optional argumentOpt As ArgumentSyntax = Nothing, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo)
Optional argumentOpt As ArgumentSyntax = Nothing,
Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo)
If argumentList Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)()
End If
If argumentList.Parent IsNot Nothing Then
If argumentList.IsParentKind(SyntaxKind.ArrayCreationExpression) Then
Return SpecializedCollections.SingletonEnumerable(New TypeInferenceInfo(Compilation.GetSpecialType(SpecialType.System_Int32)))
ElseIf argumentList.IsParentKind(SyntaxKind.InvocationExpression) Then
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册