File: Lowering\AsyncRewriter\AsyncRewriter.SpillBuilder.vb
Web Access
Project: src\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic)
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
 
Imports System.Collections.Immutable
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
 
Namespace Microsoft.CodeAnalysis.VisualBasic
 
    Partial Friend NotInheritable Class AsyncRewriter
        Inherits StateMachineRewriter(Of CapturedSymbolOrExpression)
 
        Private Structure SpillBuilder
            Private _locals As ArrayBuilder(Of LocalSymbol)
            Private _fields As ArrayBuilder(Of FieldSymbol)
            Private _statements As ArrayBuilder(Of BoundStatement)
 
            Friend Sub Free()
                If Me._locals IsNot Nothing Then
                    Me._locals.Free()
                    Me._locals = Nothing
                End If
 
                If Me._statements IsNot Nothing Then
                    Me._statements.Free()
                    Me._statements = Nothing
                End If
 
                If Me._fields IsNot Nothing Then
                    Me._fields.Free()
                    Me._fields = Nothing
                End If
            End Sub
 
            Friend Function BuildSequenceAndFree(F As SyntheticBoundNodeFactory, expression As BoundExpression) As BoundExpression
                If Not Me.IsEmpty Then
                    expression =
                        F.SpillSequence(If(Me._locals Is Nothing, ImmutableArray(Of LocalSymbol).Empty, Me._locals.ToImmutableAndFree()),
                                        If(Me._fields Is Nothing, ImmutableArray(Of FieldSymbol).Empty, Me._fields.ToImmutableAndFree()),
                                        If(Me._statements Is Nothing, ImmutableArray(Of BoundStatement).Empty, Me._statements.ToImmutableAndFree()),
                                        expression)
                    Me._locals = Nothing
                    Me._statements = Nothing
                    Me._fields = Nothing
                End If
                Return expression
            End Function
 
            Public ReadOnly Property IsEmpty As Boolean
                Get
                    Return Me._locals Is Nothing AndAlso Me._statements Is Nothing AndAlso Me._fields Is Nothing
                End Get
            End Property
 
            Friend Sub AddSpill(<[In]> ByRef spill As SpillBuilder)
                If Not spill.IsEmpty Then
                    AddRange(Me._locals, spill._locals)
                    AddRange(Me._fields, spill._fields)
                    AddRange(Me._statements, spill._statements)
                End If
            End Sub
 
            Friend Sub AddSpill(spill As BoundSpillSequence)
                AddRange(Me._locals, spill.Locals)
                AddRange(Me._fields, spill.SpillFields)
                AddRange(Me._statements, spill.Statements)
            End Sub
 
            Friend Sub AddFieldWithInitialization(field As FieldSymbol, init As BoundStatement)
                Debug.Assert(field IsNot Nothing)
                Debug.Assert(init IsNot Nothing)
 
                Add(Me._fields, field)
                Add(Me._statements, init)
            End Sub
 
            Friend Sub AddLocal(local As LocalSymbol)
                Add(Me._locals, local)
            End Sub
 
            Friend Sub AddLocals(locals As ImmutableArray(Of LocalSymbol))
                AddRange(Me._locals, locals)
            End Sub
 
            Friend Sub AddStatement(statement As BoundStatement)
                Add(Me._statements, statement)
            End Sub
 
            Friend Sub AssumeFieldsIfNeeded(<[In], Out> ByRef expression As BoundSpillSequence)
                Debug.Assert(expression IsNot Nothing)
                If Not expression.SpillFields.IsEmpty Then
                    AddRange(Me._fields, expression.SpillFields)
                    expression = expression.Update(expression.Locals,
                                                   ImmutableArray(Of FieldSymbol).Empty,
                                                   expression.Statements,
                                                   expression.ValueOpt,
                                                   expression.Type)
                End If
            End Sub
 
            Private Shared Sub EnsureArrayBuilder(Of T)(<[In], Out> ByRef array As ArrayBuilder(Of T))
                If array Is Nothing Then
                    array = ArrayBuilder(Of T).GetInstance()
                End If
            End Sub
 
            Private Shared Sub Add(Of T)(<[In], Out> ByRef array As ArrayBuilder(Of T), element As T)
                EnsureArrayBuilder(array)
                array.Add(element)
            End Sub
 
            Private Shared Sub AddRange(Of T)(<[In], Out> ByRef array As ArrayBuilder(Of T), other As ArrayBuilder(Of T))
                If other Is Nothing OrElse other.Count = 0 Then
                    Return
                End If
 
                EnsureArrayBuilder(array)
                array.AddRange(other)
            End Sub
 
            Private Shared Sub AddRange(Of T)(<[In], Out> ByRef array As ArrayBuilder(Of T), other As ImmutableArray(Of T))
                If other.IsEmpty Then
                    Return
                End If
 
                EnsureArrayBuilder(array)
                array.AddRange(other)
            End Sub
 
        End Structure
 
    End Class
 
End Namespace