提交 87ba2772 编写于 作者: V VSadov

Enable scenarios with Async

上级 b957de9b
' 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
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class LocalRewriter
Public Overrides Function VisitTupleLiteral(node As BoundTupleLiteral) As BoundNode
Return VisitTupleExpression(node)
End Function
Private Function VisitTupleExpression(node As BoundTupleExpression) As BoundNode
Dim rewrittenArguments As ImmutableArray(Of BoundExpression) = VisitList(node.Arguments)
Return RewriteTupleCreationExpression(node, rewrittenArguments)
End Function
''' <summary>
''' Converts the expression for creating a tuple instance into an expression creating a ValueTuple (if short) or nested ValueTuples (if longer).
'''
''' For instance, for a long tuple we'll generate:
''' creationExpression(ctor=largestCtor, args=firstArgs+(nested creationExpression for remainder, with smaller ctor and next few args))
''' </summary>
Private Function RewriteTupleCreationExpression(node As BoundTupleExpression, rewrittenArguments As ImmutableArray(Of BoundExpression)) As BoundExpression
Return MakeTupleCreationExpression(node.Syntax, DirectCast(node.Type, NamedTypeSymbol), rewrittenArguments)
End Function
Private Function MakeTupleCreationExpression(syntax As VisualBasicSyntaxNode, type As NamedTypeSymbol, rewrittenArguments As ImmutableArray(Of BoundExpression)) As BoundExpression
Dim underlyingTupleType As NamedTypeSymbol = If(type.TupleUnderlyingType, type)
Debug.Assert(underlyingTupleType.IsTupleCompatible())
Dim underlyingTupleTypeChain As ArrayBuilder(Of NamedTypeSymbol) = ArrayBuilder(Of NamedTypeSymbol).GetInstance()
TupleTypeSymbol.GetUnderlyingTypeChain(underlyingTupleType, underlyingTupleTypeChain)
Try
' make a creation expression for the smallest type
Dim smallestType As NamedTypeSymbol = underlyingTupleTypeChain.Pop()
Dim smallestCtorArguments As ImmutableArray(Of BoundExpression) = ImmutableArray.Create(rewrittenArguments,
underlyingTupleTypeChain.Count * (TupleTypeSymbol.RestPosition - 1),
smallestType.Arity)
Dim smallestCtor As MethodSymbol = DirectCast(TupleTypeSymbol.GetWellKnownMemberInType(smallestType.OriginalDefinition,
TupleTypeSymbol.GetTupleCtor(smallestType.Arity),
_diagnostics,
syntax), MethodSymbol)
If smallestCtor Is Nothing Then
Return New BoundBadExpression(
syntax,
LookupResultKind.Empty,
Nothing,
StaticCast(Of BoundNode).From(rewrittenArguments),
type,
hasErrors:=True)
End If
Dim smallestConstructor As MethodSymbol = smallestCtor.AsMember(smallestType)
Dim currentCreation As BoundObjectCreationExpression = New BoundObjectCreationExpression(syntax, smallestConstructor, smallestCtorArguments, initializerOpt:=Nothing, type:=smallestType)
If underlyingTupleTypeChain.Count > 0 Then
Dim tuple8Type As NamedTypeSymbol = underlyingTupleTypeChain.Peek()
Dim tuple8Ctor As MethodSymbol = DirectCast(TupleTypeSymbol.GetWellKnownMemberInType(tuple8Type.OriginalDefinition,
TupleTypeSymbol.GetTupleCtor(TupleTypeSymbol.RestPosition),
_diagnostics,
syntax), MethodSymbol)
If tuple8Ctor Is Nothing Then
Return New BoundBadExpression(
syntax,
LookupResultKind.Empty,
Nothing,
StaticCast(Of BoundNode).From(rewrittenArguments),
type,
hasErrors:=True)
End If
' make successively larger creation expressions containing the previous one
Do
Dim ctorArguments As ImmutableArray(Of BoundExpression) = ImmutableArray.Create(rewrittenArguments,
(underlyingTupleTypeChain.Count - 1) * (TupleTypeSymbol.RestPosition - 1),
TupleTypeSymbol.RestPosition - 1).Add(currentCreation)
Dim constructor As MethodSymbol = tuple8Ctor.AsMember(underlyingTupleTypeChain.Pop())
currentCreation = New BoundObjectCreationExpression(syntax, constructor, ctorArguments, initializerOpt:=Nothing, type:=constructor.ContainingType)
Loop While (underlyingTupleTypeChain.Count > 0)
End If
currentCreation = currentCreation.Update(
currentCreation.ConstructorOpt,
methodGroupOpt:=Nothing,
arguments:=currentCreation.Arguments,
initializerOpt:=currentCreation.InitializerOpt,
type:=type)
Public Overrides Function VisitExitStatement(node As BoundExitStatement) As BoundNode
Dim boundGoto As BoundStatement = New BoundGotoStatement(node.Syntax, node.Label, Nothing)
Return currentCreation
Finally
underlyingTupleTypeChain.Free()
end try
If ShouldGenerateUnstructuredExceptionHandlingResumeCode(node) Then
boundGoto = Concat(RegisterUnstructuredExceptionHandlingNonThrowingResumeTarget(node.Syntax), boundGoto)
End If
Return MarkStatementWithSequencePoint(boundGoto)
End Function
End Class
End Namespace
' 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.Diagnostics
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.Text
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class LocalRewriter
Public Overrides Function VisitExitStatement(node As BoundExitStatement) As BoundNode
Dim boundGoto As BoundStatement = New BoundGotoStatement(node.Syntax, node.Label, Nothing)
Public Overrides Function VisitTupleLiteral(node As BoundTupleLiteral) As BoundNode
Return VisitTupleExpression(node)
End Function
Private Function VisitTupleExpression(node As BoundTupleExpression) As BoundNode
Dim rewrittenArguments As ImmutableArray(Of BoundExpression) = VisitList(node.Arguments)
Return RewriteTupleCreationExpression(node, rewrittenArguments)
End Function
''' <summary>
''' Converts the expression for creating a tuple instance into an expression creating a ValueTuple (if short) or nested ValueTuples (if longer).
'''
''' For instance, for a long tuple we'll generate:
''' creationExpression(ctor=largestCtor, args=firstArgs+(nested creationExpression for remainder, with smaller ctor and next few args))
''' </summary>
Private Function RewriteTupleCreationExpression(node As BoundTupleExpression, rewrittenArguments As ImmutableArray(Of BoundExpression)) As BoundExpression
Return MakeTupleCreationExpression(node.Syntax, DirectCast(node.Type, NamedTypeSymbol), rewrittenArguments)
End Function
Private Function MakeTupleCreationExpression(syntax As VisualBasicSyntaxNode, type As NamedTypeSymbol, rewrittenArguments As ImmutableArray(Of BoundExpression)) As BoundExpression
Dim underlyingTupleType As NamedTypeSymbol = If(type.TupleUnderlyingType, type)
Debug.Assert(underlyingTupleType.IsTupleCompatible())
Dim underlyingTupleTypeChain As ArrayBuilder(Of NamedTypeSymbol) = ArrayBuilder(Of NamedTypeSymbol).GetInstance()
TupleTypeSymbol.GetUnderlyingTypeChain(underlyingTupleType, underlyingTupleTypeChain)
Try
' make a creation expression for the smallest type
Dim smallestType As NamedTypeSymbol = underlyingTupleTypeChain.Pop()
Dim smallestCtorArguments As ImmutableArray(Of BoundExpression) = ImmutableArray.Create(rewrittenArguments,
underlyingTupleTypeChain.Count * (TupleTypeSymbol.RestPosition - 1),
smallestType.Arity)
Dim smallestCtor As MethodSymbol = DirectCast(TupleTypeSymbol.GetWellKnownMemberInType(smallestType.OriginalDefinition,
TupleTypeSymbol.GetTupleCtor(smallestType.Arity),
_diagnostics,
syntax), MethodSymbol)
If smallestCtor Is Nothing Then
Return New BoundBadExpression(
syntax,
LookupResultKind.Empty,
ImmutableArray(Of Symbol).Empty,
StaticCast(Of BoundNode).From(rewrittenArguments),
type,
hasErrors:=True)
End If
Dim smallestConstructor As MethodSymbol = smallestCtor.AsMember(smallestType)
Dim currentCreation As BoundObjectCreationExpression = New BoundObjectCreationExpression(syntax, smallestConstructor, smallestCtorArguments, initializerOpt:=Nothing, type:=smallestType)
If underlyingTupleTypeChain.Count > 0 Then
Dim tuple8Type As NamedTypeSymbol = underlyingTupleTypeChain.Peek()
Dim tuple8Ctor As MethodSymbol = DirectCast(TupleTypeSymbol.GetWellKnownMemberInType(tuple8Type.OriginalDefinition,
TupleTypeSymbol.GetTupleCtor(TupleTypeSymbol.RestPosition),
_diagnostics,
syntax), MethodSymbol)
If tuple8Ctor Is Nothing Then
Return New BoundBadExpression(
syntax,
LookupResultKind.Empty,
ImmutableArray(Of Symbol).Empty,
StaticCast(Of BoundNode).From(rewrittenArguments),
type,
hasErrors:=True)
End If
' make successively larger creation expressions containing the previous one
Do
Dim ctorArguments As ImmutableArray(Of BoundExpression) = ImmutableArray.Create(rewrittenArguments,
(underlyingTupleTypeChain.Count - 1) * (TupleTypeSymbol.RestPosition - 1),
TupleTypeSymbol.RestPosition - 1).Add(currentCreation)
Dim constructor As MethodSymbol = tuple8Ctor.AsMember(underlyingTupleTypeChain.Pop())
currentCreation = New BoundObjectCreationExpression(syntax, constructor, ctorArguments, initializerOpt:=Nothing, type:=constructor.ContainingType)
Loop While (underlyingTupleTypeChain.Count > 0)
End If
'currentCreation = currentCreation.Update(
' currentCreation.ConstructorOpt,
' methodGroupOpt:=Nothing,
' arguments:=currentCreation.Arguments,
' initializerOpt:=currentCreation.InitializerOpt,
' type:=type)
If ShouldGenerateUnstructuredExceptionHandlingResumeCode(node) Then
boundGoto = Concat(RegisterUnstructuredExceptionHandlingNonThrowingResumeTarget(node.Syntax), boundGoto)
End If
Return currentCreation
Finally
underlyingTupleTypeChain.Free()
End Try
Return MarkStatementWithSequencePoint(boundGoto)
End Function
End Class
End Namespace
......@@ -320,7 +320,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' Assignment expressions in lowered form should always have suppressObjectClone = True
''' </summary>
Public Function AssignmentExpression(left As BoundExpression, right As BoundExpression) As BoundAssignmentOperator
Debug.Assert(left.Type = right.Type OrElse right.Type.IsErrorType() OrElse left.Type.IsErrorType())
Debug.Assert(left.Type.IsSameTypeIgnoringCustomModifiers(right.Type) OrElse right.Type.IsErrorType() OrElse left.Type.IsErrorType())
Dim boundNode = New BoundAssignmentOperator(_syntax, left, right, True)
boundNode.SetWasCompilerGenerated()
Return boundNode
......
......@@ -888,8 +888,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Dim myNames = Me.TupleElementNames
Dim otherNames = otherTuple.TupleElementNames
If myNames.IsDefaultOrEmpty AndAlso otherNames.IsDefaultOrEmpty Then
Return True
If myNames.IsDefaultOrEmpty Then
Return otherNames.IsDefaultOrEmpty
End If
If otherNames.IsDefaultOrEmpty Then
Return False
End If
Return myNames.SequenceEqual(otherNames)
......@@ -954,7 +958,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Function
Friend Overrides Function InternalSubstituteTypeParameters(substitution As TypeSubstitution) As TypeWithModifiers
Throw ExceptionUtilities.Unreachable
Dim substitutedUnderlying = DirectCast(Me.TupleUnderlyingType.InternalSubstituteTypeParameters(substitution).Type, NamedTypeSymbol)
Dim tupleType = TupleTypeSymbol.Create(Me._locations, substitutedUnderlying, Me._elementLocations, Me._elementNames)
Return New TypeWithModifiers(tupleType, Nothing)
End Function
Friend Overrides Function MakeDeclaredBase(basesBeingResolved As ConsList(Of Symbol), diagnostics As DiagnosticBag) As NamedTypeSymbol
......
......@@ -176,6 +176,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
<Extension()>
Friend Function IsSameTypeIgnoringCustomModifiers(t1 As TypeSymbol, t2 As TypeSymbol) As Boolean
If t1.IsTupleType Then
t1 = t1.TupleUnderlyingType
End If
If t2.IsTupleType Then
t2 = t2.TupleUnderlyingType
End If
If t1 Is t2 Then
Return True
End If
......
......@@ -205,6 +205,61 @@ End Namespace
]]>)
End Sub
<Fact()>
Public Sub TupleDefaultFieldBinding()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Module Module1
Sub Main()
Dim t As (Integer, Integer) = nothing
t.Item1 = 42
t.Item2 = t.Item1
Console.WriteLine(t.Item2)
Dim t1 = (A:=1, B:=123)
Console.WriteLine(t1.B)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
42
123
]]>, additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef})
verifier.VerifyIL("Module1.Main", <![CDATA[
{
// Code size 60 (0x3c)
.maxstack 2
.locals init (System.ValueTuple(Of Integer, Integer) V_0) //t
IL_0000: ldloca.s V_0
IL_0002: initobj "System.ValueTuple(Of Integer, Integer)"
IL_0008: ldloca.s V_0
IL_000a: ldc.i4.s 42
IL_000c: stfld "System.ValueTuple(Of Integer, Integer).Item1 As Integer"
IL_0011: ldloca.s V_0
IL_0013: ldloc.0
IL_0014: ldfld "System.ValueTuple(Of Integer, Integer).Item1 As Integer"
IL_0019: stfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_001e: ldloc.0
IL_001f: ldfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_0024: call "Sub System.Console.WriteLine(Integer)"
IL_0029: ldc.i4.1
IL_002a: ldc.i4.s 123
IL_002c: newobj "Sub System.ValueTuple(Of Integer, Integer)..ctor(Integer, Integer)"
IL_0031: ldfld "System.ValueTuple(Of Integer, Integer).Item2 As Integer"
IL_0036: call "Sub System.Console.WriteLine(Integer)"
IL_003b: ret
}
]]>)
End Sub
<Fact()>
Public Sub TupleNamedFieldBindingLong()
......@@ -258,7 +313,6 @@ End Module
]]>)
End Sub
<Fact()>
Public Sub TupleLiteralBinding()
......@@ -293,7 +347,6 @@ End Module
]]>)
End Sub
<Fact()>
Public Sub TupleLiteralBindingNamed()
......@@ -328,6 +381,69 @@ hello
]]>)
End Sub
<Fact()>
Public Sub TupleLiteralSample()
Dim verifier = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Imports System.Threading.Tasks
Module Module1
Sub Main()
Dim t As (Integer, Integer) = Nothing
t.Item1 = 42
t.Item2 = t.Item1
Console.WriteLine(t.Item2)
Dim t1 = (A:=1, B:=123)
Console.WriteLine(t1.B)
Dim numbers = {1, 2, 3, 4}
Dim t2 = Tally(numbers).Result
System.Console.WriteLine($"Sum: {t2.Sum}, Count: {t2.Count}")
End Sub
Public Async Function Tally(values As IEnumerable(Of Integer)) As Task(Of (Sum As Integer, Count As Integer))
Dim s = 0, c = 0
For Each n In values
s += n
c += 1
Next
'Await Task.Yield()
Return (Sum:=s, Count:=c)
End Function
End Module
Namespace System
Structure ValueTuple(Of T1, T2)
Public Item1 As T1
Public Item2 As T2
Sub New(item1 as T1, item2 as T2)
Me.Item1 = item1
Me.Item2 = item2
End Sub
End Structure
End Namespace
</file>
</compilation>, useLatestFramework:=True, expectedOutput:="42
123
Sum: 10, Count: 4")
End Sub
End Class
End Namespace
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册