提交 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.
Imports System.Collections.Immutable
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.Text
......@@ -10,8 +11,69 @@ Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class LocalRewriter
Public Overrides Function VisitFieldAccess(node As BoundFieldAccess) As BoundNode
Dim receiverOpt 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)
Dim rewrittenReceiver As BoundExpression = If(node.FieldSymbol.IsShared, Nothing, Me.VisitExpressionNode(node.ReceiverOpt))
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 Class
End Namespace
......@@ -407,7 +407,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End If
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)))
Else
typeArgumentsBuilder.Add(New TypeWithModifiers(extensionTuple))
......@@ -630,7 +630,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Dim namesOfVirtualFields = ArrayBuilder(Of String).GetInstance(_elementTypes.Length)
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))
Next
Else
......
......@@ -104,6 +104,56 @@ End Namespace
]]>)
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()>
Public Sub TupleNamedFieldBinding()
......@@ -152,6 +202,59 @@ End Namespace
IL_001c: call "Sub System.Console.WriteLine(Integer)"
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册