提交 8c88d8f1 编写于 作者: V VSadov

Long tuples

上级 fa10f4ec
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports System.Diagnostics Imports System.Diagnostics
Imports System.Runtime.InteropServices Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.Text
...@@ -10,8 +11,69 @@ Imports TypeKind = Microsoft.CodeAnalysis.TypeKind ...@@ -10,8 +11,69 @@ Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Namespace Microsoft.CodeAnalysis.VisualBasic Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class LocalRewriter Partial Friend NotInheritable Class LocalRewriter
Public Overrides Function VisitFieldAccess(node As BoundFieldAccess) As BoundNode Public Overrides Function VisitFieldAccess(node As BoundFieldAccess) As BoundNode
Dim receiverOpt As BoundExpression = If(node.FieldSymbol.IsShared, Nothing, Me.VisitExpressionNode(node.ReceiverOpt)) Dim rewrittenReceiver As BoundExpression = If(node.FieldSymbol.IsShared, Nothing, Me.VisitExpressionNode(node.ReceiverOpt))
Return node.Update(receiverOpt, node.FieldSymbol, node.IsLValue, node.SuppressVirtualCalls, node.ConstantsInProgressOpt, node.Type)
If node.FieldSymbol.IsTupleField Then
Return MakeTupleFieldAccess(node.Syntax, node.FieldSymbol, rewrittenReceiver, node.ConstantValueOpt, node.IsLValue)
End If
Return node.Update(rewrittenReceiver, node.FieldSymbol, node.IsLValue, node.SuppressVirtualCalls, node.ConstantsInProgressOpt, node.Type)
End Function
''' <summary>
''' Converts access to a tuple instance into access into the underlying ValueTuple(s).
'''
''' For instance, tuple.Item8
''' produces fieldAccess(field=Item1, receiver=fieldAccess(field=Rest, receiver=ValueTuple for tuple))
''' </summary>
Private Function MakeTupleFieldAccess(
syntax As VisualBasicSyntaxNode,
tupleField As FieldSymbol,
rewrittenReceiver As BoundExpression,
constantValueOpt As ConstantValue,
isLValue As Boolean) As BoundExpression
Dim tupleType = tupleField.ContainingType
Dim currentLinkType As NamedTypeSymbol = tupleType.TupleUnderlyingType
Dim underlyingField As FieldSymbol = tupleField.TupleUnderlyingField
If underlyingField Is Nothing Then
' Use-site error must have been reported elsewhere.
Return MakeBadFieldAccess(syntax, tupleField, rewrittenReceiver)
End If
If underlyingField.ContainingType <> currentLinkType Then
Dim wellKnownTupleRest As WellKnownMember = TupleTypeSymbol.GetTupleTypeMember(TupleTypeSymbol.RestPosition, TupleTypeSymbol.RestPosition)
Dim tupleRestField = DirectCast(TupleTypeSymbol.GetWellKnownMemberInType(currentLinkType.OriginalDefinition, wellKnownTupleRest, _diagnostics, syntax), FieldSymbol)
If tupleRestField Is Nothing Then
' error tolerance for cases when Rest is missing
Return MakeBadFieldAccess(syntax, tupleField, rewrittenReceiver)
End If
' make nested field accesses to Rest
Do
Dim nestedFieldSymbol As FieldSymbol = tupleRestField.AsMember(currentLinkType)
rewrittenReceiver = New BoundFieldAccess(syntax, rewrittenReceiver, nestedFieldSymbol, isLValue, nestedFieldSymbol.Type)
currentLinkType = currentLinkType.TypeArgumentsNoUseSiteDiagnostics(TupleTypeSymbol.RestPosition - 1).TupleUnderlyingType
Loop While underlyingField.ContainingType <> currentLinkType
End If
' make a field access for the most local access
Return New BoundFieldAccess(syntax, rewrittenReceiver, underlyingField, isLValue, underlyingField.Type)
End Function
Private Shared Function MakeBadFieldAccess(syntax As VisualBasicSyntaxNode, tupleField As FieldSymbol, rewrittenReceiver As BoundExpression) As BoundBadExpression
Return New BoundBadExpression(
syntax,
LookupResultKind.Empty,
ImmutableArray.Create(Of Symbol)(tupleField),
ImmutableArray.Create(Of BoundNode)(rewrittenReceiver),
tupleField.Type,
hasErrors:=True)
End Function End Function
End Class End Class
End Namespace End Namespace
...@@ -407,7 +407,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -407,7 +407,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End If End If
Next Next
If modifiers.IsDefault AndAlso Not modifiers(TupleTypeSymbol.RestPosition - 1).IsDefaultOrEmpty Then If Not modifiers.IsDefault AndAlso Not modifiers(TupleTypeSymbol.RestPosition - 1).IsDefaultOrEmpty Then
typeArgumentsBuilder.Add(New TypeWithModifiers(extensionTuple, modifiers(TupleTypeSymbol.RestPosition - 1))) typeArgumentsBuilder.Add(New TypeWithModifiers(extensionTuple, modifiers(TupleTypeSymbol.RestPosition - 1)))
Else Else
typeArgumentsBuilder.Add(New TypeWithModifiers(extensionTuple)) typeArgumentsBuilder.Add(New TypeWithModifiers(extensionTuple))
...@@ -630,7 +630,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -630,7 +630,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Dim namesOfVirtualFields = ArrayBuilder(Of String).GetInstance(_elementTypes.Length) Dim namesOfVirtualFields = ArrayBuilder(Of String).GetInstance(_elementTypes.Length)
If _elementNames.IsDefault Then If _elementNames.IsDefault Then
For i As Integer = 1 To _elementTypes.Length - 1 For i As Integer = 1 To _elementTypes.Length
namesOfVirtualFields.Add(TupleMemberName(i)) namesOfVirtualFields.Add(TupleMemberName(i))
Next Next
Else Else
......
...@@ -104,6 +104,56 @@ End Namespace ...@@ -104,6 +104,56 @@ End Namespace
]]>) ]]>)
End Sub End Sub
<Fact()>
Public Sub TupleFieldBindingLong()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Module C
Sub Main()
Dim t as (Integer, Integer, Integer, integer, integer, integer, integer, integer, integer, Integer, Integer, Integer, integer, integer, integer, integer, integer, integer)
t.Item17 = 42
t.Item12 = t.Item17
console.writeline(t.Item12)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
42
]]>, additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef})
verifier.VerifyIL("C.Main", <![CDATA[
{
// Code size 64 (0x40)
.maxstack 2
.locals init (System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)) V_0) //t
IL_0000: ldloca.s V_0
IL_0002: ldflda "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_0007: ldflda "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer)"
IL_000c: ldc.i4.s 42
IL_000e: stfld "System.ValueTuple(Of Integer, Integer, Integer, Integer).Item3 As Integer"
IL_0013: ldloca.s V_0
IL_0015: ldflda "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_001a: ldloc.0
IL_001b: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_0020: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer)"
IL_0025: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer).Item3 As Integer"
IL_002a: stfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Item5 As Integer"
IL_002f: ldloc.0
IL_0030: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_0035: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Item5 As Integer"
IL_003a: call "Sub System.Console.WriteLine(Integer)"
IL_003f: ret
}
]]>)
End Sub
<Fact()> <Fact()>
Public Sub TupleNamedFieldBinding() Public Sub TupleNamedFieldBinding()
...@@ -152,6 +202,59 @@ End Namespace ...@@ -152,6 +202,59 @@ End Namespace
IL_001c: call "Sub System.Console.WriteLine(Integer)" IL_001c: call "Sub System.Console.WriteLine(Integer)"
IL_0021: ret IL_0021: ret
} }
]]>)
End Sub
<Fact()>
Public Sub TupleNamedFieldBindingLong()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Module C
Sub Main()
Dim t as (a1 as Integer, a2 as Integer, a3 as Integer, a4 as integer,
a5 as integer, a6 as integer, a7 as integer, a8 as integer,
a9 as integer, a10 as Integer, a11 as Integer, a12 as Integer,
a13 as integer, a14 as integer, a15 as integer, a16 as integer,
a17 as integer, a18 as integer)
t.a17 = 42
t.a12 = t.a17
console.writeline(t.a12)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
42
]]>, additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef})
verifier.VerifyIL("C.Main", <![CDATA[
{
// Code size 64 (0x40)
.maxstack 2
.locals init (System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)) V_0) //t
IL_0000: ldloca.s V_0
IL_0002: ldflda "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_0007: ldflda "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer)"
IL_000c: ldc.i4.s 42
IL_000e: stfld "System.ValueTuple(Of Integer, Integer, Integer, Integer).Item3 As Integer"
IL_0013: ldloca.s V_0
IL_0015: ldflda "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_001a: ldloc.0
IL_001b: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_0020: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer)"
IL_0025: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer).Item3 As Integer"
IL_002a: stfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Item5 As Integer"
IL_002f: ldloc.0
IL_0030: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)).Rest As (Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer)"
IL_0035: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Item5 As Integer"
IL_003a: call "Sub System.Console.WriteLine(Integer)"
IL_003f: ret
}
]]>) ]]>)
End Sub End Sub
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册