提交 fa10f4ec 编写于 作者: V VSadov

Tuple type visualization

上级 fa83ec65
......@@ -329,7 +329,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Function BindNamespaceOrTypeOrExpressionSyntaxForSemanticModel(node As ExpressionSyntax, diagnostics As DiagnosticBag) As BoundExpression
If (node.Kind = SyntaxKind.PredefinedType) OrElse
(((TypeOf node Is NameSyntax) OrElse node.Kind = SyntaxKind.ArrayType) AndAlso SyntaxFacts.IsInNamespaceOrTypeContext(node)) Then
(((TypeOf node Is NameSyntax) OrElse node.Kind = SyntaxKind.ArrayType OrElse node.Kind = SyntaxKind.TupleType) AndAlso SyntaxFacts.IsInNamespaceOrTypeContext(node)) Then
Dim result As BoundExpression = Me.BindNamespaceOrTypeExpression(DirectCast(node, TypeSyntax), diagnostics)
' Deal with the case of a namespace group. We may need to bind more in order to see if the ambiguity can be resolved.
......
......@@ -103,7 +103,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
End If
If Me.IsMinimizing Then
If Me.IsMinimizing OrElse symbol.IsTupleType Then
MinimallyQualify(symbol)
Return
End If
......@@ -197,9 +197,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If symbol.IsAnonymousType Then
AddAnonymousTypeName(symbol)
Return
ElseIf (symbol.IsTupleType) Then
' If top level tuple uses non-default names, there is no way to preserve them
' unless we use tuple syntax for the type. So, we give them priority.
If HasNonDefaultTupleElementNames(symbol) OrElse CanUseTupleTypeName(symbol) Then
AddTupleTypeName(symbol)
Return
End If
' Fall back to displaying the underlying type.
symbol = symbol.TupleUnderlyingType
End If
If format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName) AndAlso
If format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName) AndAlso
String.IsNullOrEmpty(symbolName) Then
symbolName = StringConstants.NamedSymbolErrorName
......@@ -287,6 +298,75 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Select
End Sub
''' <summary>
''' Returns true if tuple type syntax can be used to refer to the tuple type without loss of information.
''' For example, it cannot be used when extension tuple is using non-default friendly names.
''' </summary>
''' <param name="tupleSymbol"></param>
''' <returns></returns>
Private Function CanUseTupleTypeName(tupleSymbol As INamedTypeSymbol) As Boolean
Dim currentUnderlying As INamedTypeSymbol = tupleSymbol.TupleUnderlyingType
While currentUnderlying.Arity = TupleTypeSymbol.RestPosition
tupleSymbol = DirectCast(currentUnderlying.TypeArguments(TupleTypeSymbol.RestPosition - 1), INamedTypeSymbol)
Debug.Assert(tupleSymbol.IsTupleType)
If HasNonDefaultTupleElementNames(tupleSymbol) Then
Return False
End If
currentUnderlying = tupleSymbol.TupleUnderlyingType
End While
Return True
End Function
Private Shared Function HasNonDefaultTupleElementNames(tupleSymbol As INamedTypeSymbol) As Boolean
Dim elementNames = tupleSymbol.TupleElementNames
If Not elementNames.IsDefault Then
For i As Integer = 0 To elementNames.Length - 1
If (elementNames(i) <> TupleTypeSymbol.TupleMemberName(i + 1)) Then
Return True
End If
Next
End If
Return False
End Function
Private Sub AddTupleTypeName(symbol As INamedTypeSymbol)
Debug.Assert(symbol.IsTupleType)
Dim elementTypes As ImmutableArray(Of ITypeSymbol) = symbol.TupleElementTypes
Dim elementNames As ImmutableArray(Of String) = symbol.TupleElementNames
Dim hasNames As Boolean = Not elementNames.IsDefault
AddPunctuation(SyntaxKind.OpenParenToken)
Dim first As Boolean = True
For i As Integer = 0 To elementTypes.Length - 1
If Not first Then
AddPunctuation(SyntaxKind.CommaToken)
AddSpace()
End If
first = False
If hasNames Then
builder.Add(CreatePart(SymbolDisplayPartKind.FieldName, symbol, elementNames(i), noEscaping:=False))
AddSpace()
AddPunctuation(SyntaxKind.AsKeyword)
AddSpace()
End If
elementTypes(i).Accept(Me.NotFirstVisitor)
Next
AddPunctuation(SyntaxKind.CloseParenToken)
End Sub
Private Function CreateAnonymousTypeMember(prop As IPropertySymbol) As String
Dim result = CreateAnonymousTypeMemberWorker(prop)
Return If(prop.IsReadOnly, "Key " & result, result)
......@@ -313,6 +393,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' NOTE: Not actually a keyword, but it's not worth introducing a new kind just for this.
builder.Add(New SymbolDisplayPart(SymbolDisplayPartKind.Keyword, Nothing, "AnonymousType"))
AddSpace()
ElseIf symbol.IsTupleType Then
builder.Add(New SymbolDisplayPart(SymbolDisplayPartKind.AnonymousTypeIndicator, Nothing, "Tuple"))
AddSpace()
Else
Dim keyword = GetTypeKindKeyword(symbol.TypeKind)
If keyword = SyntaxKind.None Then
......
......@@ -92,7 +92,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim visitedParents As Boolean = False
If Not symbol.IsAnonymousType Then
If Not (symbol.IsAnonymousType OrElse symbol.IsTupleType) Then
If Not NameBoundSuccessfullyToSameSymbol(symbol) Then
If IncludeNamedType(symbol.ContainingType) Then
symbol.ContainingType.Accept(NotFirstVisitor)
......
......@@ -510,7 +510,7 @@ Done:
Private ReadOnly Property ITypeSymbol_IsTupleSymbol As Boolean Implements ITypeSymbol.IsTupleType
Get
Return False
Return Me.IsTupleType
End Get
End Property
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册