diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs index df84a95efd910..47c3d16b97549 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs @@ -5146,6 +5146,17 @@ public void CreateTupleTypeSymbol_ElementTypeIsError() Assert.Equal(SymbolKind.ErrorType, types[1].Kind); } + [Fact, WorkItem(13277, "https://github.com/dotnet/roslyn/issues/13277")] + public void CreateTupleTypeSymbol_UnderlyingTypeIsError() + { + var comp = CSharpCompilation.Create("test", references: new[] { MscorlibRef }); + + TypeSymbol intType = comp.GetSpecialType(SpecialType.System_Int32); + var vt2 = comp.CreateErrorTypeSymbol(null, "ValueTuple", 2).Construct(intType, intType); + + Assert.Throws(() => comp.CreateTupleTypeSymbol(underlyingType: vt2)); + } + [Fact] public void CreateTupleTypeSymbol_BadNames() { diff --git a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFacts.vb b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFacts.vb index 8796cf3af2ef4..5cab96e299d9c 100644 --- a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFacts.vb +++ b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxFacts.vb @@ -107,6 +107,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Else Return parentQualName.Right Is node End If + Case SyntaxKind.TupleElement + Return DirectCast(parent, TupleElementSyntax).Type Is node End Select End If diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb index 73c0a48c48b65..296aa89e087ca 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb @@ -5896,6 +5896,47 @@ fourth]]>) End Sub + + + Public Sub CreateTupleTypeSymbol_UnderlyingTypeIsError() + + Dim comp = VisualBasicCompilation.Create("test", references:={MscorlibRef}) + + Dim intType As TypeSymbol = comp.GetSpecialType(SpecialType.System_Int32) + Dim vt2 = comp.CreateErrorTypeSymbol(Nothing, "ValueTuple", 2).Construct(intType, intType) + + Dim tuple = comp.CreateTupleTypeSymbol(vt2, Nothing) + ' Crashes in IsTupleCompatible + + End Sub + + + + Public Sub GetSymbolInfoOnTupleType() + Dim verifier = CompileAndVerify( + + +Module C + Function M() As (System.Int32, String) + throw new System.Exception() + End Function +End Module + + + , additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef}) + + Dim comp = verifier.Compilation + Dim tree = comp.SyntaxTrees(0) + Dim model = comp.GetSemanticModel(tree, ignoreAccessibility:=False) + Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes() + + Dim type = nodes.OfType(Of QualifiedNameSyntax)().First() + Assert.Equal("System.Int32", type.ToString()) + Assert.NotNull(model.GetSymbolInfo(type).Symbol) + Assert.Equal("System.Int32", model.GetSymbolInfo(type).Symbol.ToTestDisplayString()) + + End Sub + End Class End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/CodeActions/ExtractMethod/ExtractMethodTests.vb b/src/EditorFeatures/VisualBasicTest/CodeActions/ExtractMethod/ExtractMethodTests.vb index f5f0fab07cdf1..08866747d6e5a 100644 --- a/src/EditorFeatures/VisualBasicTest/CodeActions/ExtractMethod/ExtractMethodTests.vb +++ b/src/EditorFeatures/VisualBasicTest/CodeActions/ExtractMethod/ExtractMethodTests.vb @@ -293,5 +293,41 @@ End Class .Value.Replace(vbLf, vbCrLf), compareTokens:=False) End Function + + + + Public Async Function TestTuples() As Task + + Await TestAsync( +"Class Program + Sub Main(args As String()) + [|Dim x = (1, 2)|] + M(x) + End Sub + Private Sub M(x As (Integer, Integer)) + End Sub +End Class +Namespace System + Structure ValueTuple(Of T1, T2) + End Structure +End Namespace", +"Class Program + Sub Main(args As String()) + Dim x As (Integer, Integer) = {|Rename:NewMethod|}() + M(x) + End Sub + Private Shared Function NewMethod() As (Integer, Integer) + Return (1, 2) + End Function + Private Sub M(x As (Integer, Integer)) + End Sub +End Class +Namespace System + Structure ValueTuple(Of T1, T2) + End Structure +End Namespace") + + End Function + End Class End Namespace diff --git a/src/Workspaces/VisualBasic/Portable/Extensions/TypeSyntaxGeneratorVisitor.vb b/src/Workspaces/VisualBasic/Portable/Extensions/TypeSyntaxGeneratorVisitor.vb index 31b1a7b6d1e55..80d62d589d620 100644 --- a/src/Workspaces/VisualBasic/Portable/Extensions/TypeSyntaxGeneratorVisitor.vb +++ b/src/Workspaces/VisualBasic/Portable/Extensions/TypeSyntaxGeneratorVisitor.vb @@ -102,6 +102,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("DateTime")) End Select + If symbol.IsTupleType Then + Return CreateTupleTypeSyntax(symbol) + End If + If symbol.Name = String.Empty OrElse symbol.IsAnonymousType Then Return SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Object")) End If @@ -119,6 +123,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(symbol.TypeArguments.[Select](Function(t) t.Accept(Me))))) End Function + Private Shared Function CreateTupleTypeSyntax(symbol As INamedTypeSymbol) As TypeSyntax + Dim types = symbol.TupleElementTypes + Dim names = symbol.TupleElementNames + Dim hasNames = Not names.IsDefault + + Return SyntaxFactory.TupleType(SyntaxFactory.SeparatedList( + types.Select(Function(t, i) SyntaxFactory.TupleElement( + If(hasNames, SyntaxFactory.IdentifierName(names(i)), Nothing), t.GenerateTypeSyntax())))) + End Function + Public Overrides Function VisitNamedType(symbol As INamedTypeSymbol) As TypeSyntax Dim typeSyntax = CreateSimpleTypeSyntax(symbol) If Not (TypeOf typeSyntax Is SimpleNameSyntax) Then