VisualBasicOperationFactory.vb 78.3 KB
Newer Older
H
Heejae Chang 已提交
1 2 3 4 5 6 7 8 9
' 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.Linq
Imports System.Runtime.CompilerServices
Imports Microsoft.CodeAnalysis.VisualBasic

Namespace Microsoft.CodeAnalysis.Semantics
    Partial Friend NotInheritable Class VisualBasicOperationFactory
H
Heejae Chang 已提交
10

H
Heejae Chang 已提交
11
        Private Shared ReadOnly s_cache As New ConditionalWeakTable(Of BoundNode, IOperation)
H
Heejae Chang 已提交
12

H
Heejae Chang 已提交
13
        Public Shared Function Create(boundNode As BoundNode) As IOperation
H
Heejae Chang 已提交
14 15 16 17 18 19 20 21
            If boundNode Is Nothing Then
                Return Nothing
            End If

            Return s_cache.GetValue(boundNode, Function(n) CreateInternal(n))
        End Function

        Private Shared Function CreateInternal(boundNode As BoundNode) As IOperation
H
Heejae Chang 已提交
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
            Select Case boundNode.Kind
                Case BoundKind.AssignmentOperator
                    Return CreateBoundAssignmentOperatorOperation(DirectCast(boundNode, BoundAssignmentOperator))
                Case BoundKind.MeReference
                    Return CreateBoundMeReferenceOperation(DirectCast(boundNode, BoundMeReference))
                Case BoundKind.MyBaseReference
                    Return CreateBoundMyBaseReferenceOperation(DirectCast(boundNode, BoundMyBaseReference))
                Case BoundKind.MyClassReference
                    Return CreateBoundMyClassReferenceOperation(DirectCast(boundNode, BoundMyClassReference))
                Case BoundKind.Literal
                    Return CreateBoundLiteralOperation(DirectCast(boundNode, BoundLiteral))
                Case BoundKind.AwaitOperator
                    Return CreateBoundAwaitOperatorOperation(DirectCast(boundNode, BoundAwaitOperator))
                Case BoundKind.Lambda
                    Return CreateBoundLambdaOperation(DirectCast(boundNode, BoundLambda))
                Case BoundKind.Call
                    Return CreateBoundCallOperation(DirectCast(boundNode, BoundCall))
                Case BoundKind.OmittedArgument
                    Return CreateBoundOmittedArgumentOperation(DirectCast(boundNode, BoundOmittedArgument))
                Case BoundKind.Parenthesized
                    Return CreateBoundParenthesizedOperation(DirectCast(boundNode, BoundParenthesized))
                Case BoundKind.ArrayAccess
                    Return CreateBoundArrayAccessOperation(DirectCast(boundNode, BoundArrayAccess))
                Case BoundKind.UnaryOperator
                    Return CreateBoundUnaryOperatorOperation(DirectCast(boundNode, BoundUnaryOperator))
                Case BoundKind.UserDefinedUnaryOperator
                    Return CreateBoundUserDefinedUnaryOperatorOperation(DirectCast(boundNode, BoundUserDefinedUnaryOperator))
                Case BoundKind.BinaryOperator
                    Return CreateBoundBinaryOperatorOperation(DirectCast(boundNode, BoundBinaryOperator))
                Case BoundKind.UserDefinedBinaryOperator
                    Return CreateBoundUserDefinedBinaryOperatorOperation(DirectCast(boundNode, BoundUserDefinedBinaryOperator))
                Case BoundKind.BinaryConditionalExpression
                    Return CreateBoundBinaryConditionalExpressionOperation(DirectCast(boundNode, BoundBinaryConditionalExpression))
                Case BoundKind.UserDefinedShortCircuitingOperator
                    Return CreateBoundUserDefinedShortCircuitingOperatorOperation(DirectCast(boundNode, BoundUserDefinedShortCircuitingOperator))
                Case BoundKind.BadExpression
                    Return CreateBoundBadExpressionOperation(DirectCast(boundNode, BoundBadExpression))
                Case BoundKind.TryCast
                    Return CreateBoundTryCastOperation(DirectCast(boundNode, BoundTryCast))
                Case BoundKind.DirectCast
                    Return CreateBoundDirectCastOperation(DirectCast(boundNode, BoundDirectCast))
                Case BoundKind.Conversion
                    Return CreateBoundConversionOperation(DirectCast(boundNode, BoundConversion))
                Case BoundKind.UserDefinedConversion
                    Return CreateBoundUserDefinedConversionOperation(DirectCast(boundNode, BoundUserDefinedConversion))
                Case BoundKind.TernaryConditionalExpression
                    Return CreateBoundTernaryConditionalExpressionOperation(DirectCast(boundNode, BoundTernaryConditionalExpression))
                Case BoundKind.TypeOf
                    Return CreateBoundTypeOfOperation(DirectCast(boundNode, BoundTypeOf))
                Case BoundKind.ObjectCreationExpression
                    Return CreateBoundObjectCreationExpressionOperation(DirectCast(boundNode, BoundObjectCreationExpression))
                Case BoundKind.NewT
                    Return CreateBoundNewTOperation(DirectCast(boundNode, BoundNewT))
                Case BoundKind.ArrayCreation
                    Return CreateBoundArrayCreationOperation(DirectCast(boundNode, BoundArrayCreation))
                Case BoundKind.ArrayInitialization
                    Return CreateBoundArrayInitializationOperation(DirectCast(boundNode, BoundArrayInitialization))
                Case BoundKind.PropertyAccess
                    Return CreateBoundPropertyAccessOperation(DirectCast(boundNode, BoundPropertyAccess))
                Case BoundKind.EventAccess
                    Return CreateBoundEventAccessOperation(DirectCast(boundNode, BoundEventAccess))
                Case BoundKind.DelegateCreationExpression
                    Return CreateBoundDelegateCreationExpressionOperation(DirectCast(boundNode, BoundDelegateCreationExpression))
                Case BoundKind.FieldAccess
                    Return CreateBoundFieldAccessOperation(DirectCast(boundNode, BoundFieldAccess))
                Case BoundKind.ConditionalAccess
                    Return CreateBoundConditionalAccessOperation(DirectCast(boundNode, BoundConditionalAccess))
                Case BoundKind.ConditionalAccessReceiverPlaceholder
                    Return CreateBoundConditionalAccessReceiverPlaceholderOperation(DirectCast(boundNode, BoundConditionalAccessReceiverPlaceholder))
                Case BoundKind.Parameter
                    Return CreateBoundParameterOperation(DirectCast(boundNode, BoundParameter))
                Case BoundKind.Local
                    Return CreateBoundLocalOperation(DirectCast(boundNode, BoundLocal))
                Case BoundKind.LateMemberAccess
                    Return CreateBoundLateMemberAccessOperation(DirectCast(boundNode, BoundLateMemberAccess))
                Case BoundKind.FieldInitializer
                    Return CreateBoundFieldInitializerOperation(DirectCast(boundNode, BoundFieldInitializer))
                Case BoundKind.PropertyInitializer
                    Return CreateBoundPropertyInitializerOperation(DirectCast(boundNode, BoundPropertyInitializer))
                Case BoundKind.ParameterEqualsValue
                    Return CreateBoundParameterEqualsValueOperation(DirectCast(boundNode, BoundParameterEqualsValue))
                Case BoundKind.RValuePlaceholder
                    Return CreateBoundRValuePlaceholderOperation(DirectCast(boundNode, BoundRValuePlaceholder))
                Case BoundKind.IfStatement
                    Return CreateBoundIfStatementOperation(DirectCast(boundNode, BoundIfStatement))
                Case BoundKind.SelectStatement
                    Return CreateBoundSelectStatementOperation(DirectCast(boundNode, BoundSelectStatement))
                Case BoundKind.SimpleCaseClause
                    Return CreateBoundSimpleCaseClauseOperation(DirectCast(boundNode, BoundSimpleCaseClause))
                Case BoundKind.RangeCaseClause
                    Return CreateBoundRangeCaseClauseOperation(DirectCast(boundNode, BoundRangeCaseClause))
                Case BoundKind.RelationalCaseClause
                    Return CreateBoundRelationalCaseClauseOperation(DirectCast(boundNode, BoundRelationalCaseClause))
                Case BoundKind.DoLoopStatement
                    Return CreateBoundDoLoopStatementOperation(DirectCast(boundNode, BoundDoLoopStatement))
                Case BoundKind.ForToStatement
                    Return CreateBoundForToStatementOperation(DirectCast(boundNode, BoundForToStatement))
                Case BoundKind.ForEachStatement
                    Return CreateBoundForEachStatementOperation(DirectCast(boundNode, BoundForEachStatement))
                Case BoundKind.TryStatement
                    Return CreateBoundTryStatementOperation(DirectCast(boundNode, BoundTryStatement))
                Case BoundKind.CatchBlock
                    Return CreateBoundCatchBlockOperation(DirectCast(boundNode, BoundCatchBlock))
                Case BoundKind.Block
                    Return CreateBoundBlockOperation(DirectCast(boundNode, BoundBlock))
                Case BoundKind.BadStatement
                    Return CreateBoundBadStatementOperation(DirectCast(boundNode, BoundBadStatement))
                Case BoundKind.ReturnStatement
                    Return CreateBoundReturnStatementOperation(DirectCast(boundNode, BoundReturnStatement))
                Case BoundKind.ThrowStatement
                    Return CreateBoundThrowStatementOperation(DirectCast(boundNode, BoundThrowStatement))
                Case BoundKind.WhileStatement
                    Return CreateBoundWhileStatementOperation(DirectCast(boundNode, BoundWhileStatement))
                Case BoundKind.DimStatement
                    Return CreateBoundDimStatementOperation(DirectCast(boundNode, BoundDimStatement))
                Case BoundKind.YieldStatement
                    Return CreateBoundYieldStatementOperation(DirectCast(boundNode, BoundYieldStatement))
                Case BoundKind.LabelStatement
                    Return CreateBoundLabelStatementOperation(DirectCast(boundNode, BoundLabelStatement))
                Case BoundKind.GotoStatement
                    Return CreateBoundGotoStatementOperation(DirectCast(boundNode, BoundGotoStatement))
                Case BoundKind.ContinueStatement
                    Return CreateBoundContinueStatementOperation(DirectCast(boundNode, BoundContinueStatement))
                Case BoundKind.ExitStatement
                    Return CreateBoundExitStatementOperation(DirectCast(boundNode, BoundExitStatement))
                Case BoundKind.SyncLockStatement
                    Return CreateBoundSyncLockStatementOperation(DirectCast(boundNode, BoundSyncLockStatement))
                Case BoundKind.NoOpStatement
                    Return CreateBoundNoOpStatementOperation(DirectCast(boundNode, BoundNoOpStatement))
                Case BoundKind.StopStatement
                    Return CreateBoundStopStatementOperation(DirectCast(boundNode, BoundStopStatement))
                Case BoundKind.EndStatement
                    Return CreateBoundEndStatementOperation(DirectCast(boundNode, BoundEndStatement))
                Case BoundKind.WithStatement
                    Return CreateBoundWithStatementOperation(DirectCast(boundNode, BoundWithStatement))
                Case BoundKind.UsingStatement
                    Return CreateBoundUsingStatementOperation(DirectCast(boundNode, BoundUsingStatement))
                Case BoundKind.ExpressionStatement
                    Return CreateBoundExpressionStatementOperation(DirectCast(boundNode, BoundExpressionStatement))
                Case BoundKind.RaiseEventStatement
                    Return CreateBoundRaiseEventStatementOperation(DirectCast(boundNode, BoundRaiseEventStatement))
                Case BoundKind.AddHandlerStatement
                    Return CreateBoundAddHandlerStatementOperation(DirectCast(boundNode, BoundAddHandlerStatement))
                Case BoundKind.RemoveHandlerStatement
                    Return CreateBoundRemoveHandlerStatementOperation(DirectCast(boundNode, BoundRemoveHandlerStatement))
                Case Else
                    Return Operation.CreateOperationNone(boundNode.HasErrors, boundNode.Syntax)
            End Select
        End Function
        Private Shared Function CreateBoundAssignmentOperatorOperation(boundAssignmentOperator As BoundAssignmentOperator) As IOperation
            Dim kind = GetAssignmentKind(boundAssignmentOperator)
            If kind = OperationKind.CompoundAssignmentExpression Then
                Dim binaryOperationKind As BinaryOperationKind = DirectCast(Create(boundAssignmentOperator.Right), IBinaryOperatorExpression).BinaryOperationKind
H
Heejae Chang 已提交
175
                Dim target As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAssignmentOperator.Left))
H
Heejae Chang 已提交
176 177 178 179 180 181 182 183 184
                Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() DirectCast(Create(boundAssignmentOperator.Right), IBinaryOperatorExpression).RightOperand)
                Dim usesOperatorMethod As Boolean = DirectCast(Create(boundAssignmentOperator.Right), IBinaryOperatorExpression).UsesOperatorMethod
                Dim operatorMethod As IMethodSymbol = DirectCast(Create(boundAssignmentOperator.Right), IBinaryOperatorExpression).OperatorMethod
                Dim isInvalid As Boolean = boundAssignmentOperator.HasErrors
                Dim syntax As SyntaxNode = boundAssignmentOperator.Syntax
                Dim type As ITypeSymbol = boundAssignmentOperator.Type
                Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignmentOperator.ConstantValueOpt)
                Return New LazyCompoundAssignmentExpression(binaryOperationKind, target, value, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
            Else
H
Heejae Chang 已提交
185 186
                Dim target As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAssignmentOperator.Left))
                Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAssignmentOperator.Right))
H
Heejae Chang 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
                Dim isInvalid As Boolean = boundAssignmentOperator.HasErrors
                Dim syntax As SyntaxNode = boundAssignmentOperator.Syntax
                Dim type As ITypeSymbol = boundAssignmentOperator.Type
                Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignmentOperator.ConstantValueOpt)
                Return New LazyAssignmentExpression(target, value, isInvalid, syntax, type, constantValue)
            End If
        End Function
        Private Shared Function CreateBoundMeReferenceOperation(boundMeReference As BoundMeReference) As IInstanceReferenceExpression
            Dim instanceReferenceKind As InstanceReferenceKind = If(boundMeReference.WasCompilerGenerated, InstanceReferenceKind.Implicit, InstanceReferenceKind.Explicit)
            Dim isInvalid As Boolean = boundMeReference.HasErrors
            Dim syntax As SyntaxNode = boundMeReference.Syntax
            Dim type As ITypeSymbol = boundMeReference.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundMeReference.ConstantValueOpt)
            Return New InstanceReferenceExpression(instanceReferenceKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundMyBaseReferenceOperation(boundMyBaseReference As BoundMyBaseReference) As IInstanceReferenceExpression
            Dim instanceReferenceKind As InstanceReferenceKind = InstanceReferenceKind.BaseClass
            Dim isInvalid As Boolean = boundMyBaseReference.HasErrors
            Dim syntax As SyntaxNode = boundMyBaseReference.Syntax
            Dim type As ITypeSymbol = boundMyBaseReference.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundMyBaseReference.ConstantValueOpt)
            Return New InstanceReferenceExpression(instanceReferenceKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundMyClassReferenceOperation(boundMyClassReference As BoundMyClassReference) As IInstanceReferenceExpression
            Dim instanceReferenceKind As InstanceReferenceKind = InstanceReferenceKind.ThisClass
            Dim isInvalid As Boolean = boundMyClassReference.HasErrors
            Dim syntax As SyntaxNode = boundMyClassReference.Syntax
            Dim type As ITypeSymbol = boundMyClassReference.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundMyClassReference.ConstantValueOpt)
            Return New InstanceReferenceExpression(instanceReferenceKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundLiteralOperation(boundLiteral As BoundLiteral) As ILiteralExpression
            Dim text As String = boundLiteral.Syntax.ToString()
            Dim isInvalid As Boolean = boundLiteral.HasErrors
            Dim syntax As SyntaxNode = boundLiteral.Syntax
            Dim type As ITypeSymbol = boundLiteral.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLiteral.ConstantValueOpt)
            Return New LiteralExpression(text, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundAwaitOperatorOperation(boundAwaitOperator As BoundAwaitOperator) As IAwaitExpression
H
Heejae Chang 已提交
227
            Dim awaitedValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAwaitOperator.Operand))
H
Heejae Chang 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
            Dim isInvalid As Boolean = boundAwaitOperator.HasErrors
            Dim syntax As SyntaxNode = boundAwaitOperator.Syntax
            Dim type As ITypeSymbol = boundAwaitOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAwaitOperator.ConstantValueOpt)
            Return New LazyAwaitExpression(awaitedValue, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundLambdaOperation(boundLambda As BoundLambda) As ILambdaExpression
            Dim signature As IMethodSymbol = boundLambda.LambdaSymbol
            Dim body As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundLambda.Body), IBlockStatement))
            Dim isInvalid As Boolean = boundLambda.HasErrors
            Dim syntax As SyntaxNode = boundLambda.Syntax
            Dim type As ITypeSymbol = boundLambda.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLambda.ConstantValueOpt)
            Return New LazyLambdaExpression(signature, body, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundCallOperation(boundCall As BoundCall) As IInvocationExpression
            Dim targetMethod As IMethodSymbol = boundCall.Method
H
Heejae Chang 已提交
245
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() If(boundCall.Method.IsShared, Nothing, Create(boundCall.ReceiverOpt)))
H
Heejae Chang 已提交
246 247

            Dim method As IMethodSymbol = boundCall.Method
H
Heejae Chang 已提交
248
            Dim receiver As IOperation = Create(boundCall.ReceiverOpt)
H
Heejae Chang 已提交
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
            Dim isVirtual As Boolean = method IsNot Nothing AndAlso instance IsNot Nothing AndAlso (method.IsVirtual OrElse method.IsAbstract OrElse method.IsOverride) AndAlso receiver.Kind <> BoundKind.MyBaseReference AndAlso receiver.Kind <> BoundKind.MyClassReference

            Dim argumentsInEvaluationOrder As Lazy(Of ImmutableArray(Of IArgument)) = New Lazy(Of ImmutableArray(Of IArgument))(Function() DeriveArguments(boundCall.Arguments, boundCall.Method.Parameters))
            Dim isInvalid As Boolean = boundCall.HasErrors
            Dim syntax As SyntaxNode = boundCall.Syntax
            Dim type As ITypeSymbol = boundCall.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundCall.ConstantValueOpt)
            Return New LazyInvocationExpression(targetMethod, instance, isVirtual, argumentsInEvaluationOrder, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundOmittedArgumentOperation(boundOmittedArgument As BoundOmittedArgument) As IOmittedArgumentExpression
            Dim isInvalid As Boolean = boundOmittedArgument.HasErrors
            Dim syntax As SyntaxNode = boundOmittedArgument.Syntax
            Dim type As ITypeSymbol = boundOmittedArgument.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundOmittedArgument.ConstantValueOpt)
            Return New OmittedArgumentExpression(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundParenthesizedOperation(boundParenthesized As BoundParenthesized) As IParenthesizedExpression
H
Heejae Chang 已提交
266
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundParenthesized.Expression))
H
Heejae Chang 已提交
267 268 269 270 271 272 273
            Dim isInvalid As Boolean = boundParenthesized.HasErrors
            Dim syntax As SyntaxNode = boundParenthesized.Syntax
            Dim type As ITypeSymbol = boundParenthesized.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundParenthesized.ConstantValueOpt)
            Return New LazyParenthesizedExpression(operand, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundArrayAccessOperation(boundArrayAccess As BoundArrayAccess) As IArrayElementReferenceExpression
H
Heejae Chang 已提交
274
            Dim arrayReference As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundArrayAccess.Expression))
H
Heejae Chang 已提交
275 276 277 278 279 280 281 282 283
            Dim indices As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() boundArrayAccess.Indices.SelectAsArray(Function(n) DirectCast(Create(n), IOperation)))
            Dim isInvalid As Boolean = boundArrayAccess.HasErrors
            Dim syntax As SyntaxNode = boundArrayAccess.Syntax
            Dim type As ITypeSymbol = boundArrayAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundArrayAccess.ConstantValueOpt)
            Return New LazyArrayElementReferenceExpression(arrayReference, indices, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundUnaryOperatorOperation(boundUnaryOperator As BoundUnaryOperator) As IUnaryOperatorExpression
            Dim unaryOperationKind As UnaryOperationKind = Helper.DeriveUnaryOperationKind(boundUnaryOperator.OperatorKind, boundUnaryOperator.Operand)
H
Heejae Chang 已提交
284
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUnaryOperator.Operand))
H
Heejae Chang 已提交
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim isInvalid As Boolean = boundUnaryOperator.HasErrors
            Dim syntax As SyntaxNode = boundUnaryOperator.Syntax
            Dim type As ITypeSymbol = boundUnaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUnaryOperator.ConstantValueOpt)
            Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundUserDefinedUnaryOperatorOperation(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As IUnaryOperatorExpression
            Dim unaryOperationKind As UnaryOperationKind = Helper.DeriveUnaryOperationKind(boundUserDefinedUnaryOperator.OperatorKind)
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function()
                                                                             If boundUserDefinedUnaryOperator.UnderlyingExpression.Kind = BoundKind.Call Then
                                                                                 Return Create(boundUserDefinedUnaryOperator.Operand)
                                                                             Else
                                                                                 Return GetChildOfBadExpression(boundUserDefinedUnaryOperator.UnderlyingExpression, 0)
                                                                             End If
                                                                         End Function)
            Dim operatorMethod As IMethodSymbol = If(boundUserDefinedUnaryOperator.UnderlyingExpression.Kind = BoundKind.Call, boundUserDefinedUnaryOperator.Call.Method, Nothing)
            Dim usesOperatorMethod As Boolean = operatorMethod IsNot Nothing
            Dim isInvalid As Boolean = boundUserDefinedUnaryOperator.HasErrors
            Dim syntax As SyntaxNode = boundUserDefinedUnaryOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedUnaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedUnaryOperator.ConstantValueOpt)
            Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundBinaryOperatorOperation(boundBinaryOperator As BoundBinaryOperator) As IBinaryOperatorExpression
            Dim binaryOperationKind As BinaryOperationKind = Helper.DeriveBinaryOperationKind(boundBinaryOperator.OperatorKind, boundBinaryOperator.Left)
H
Heejae Chang 已提交
312 313
            Dim leftOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundBinaryOperator.Left))
            Dim rightOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundBinaryOperator.Right))
H
Heejae Chang 已提交
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim isInvalid As Boolean = boundBinaryOperator.HasErrors
            Dim syntax As SyntaxNode = boundBinaryOperator.Syntax
            Dim type As ITypeSymbol = boundBinaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBinaryOperator.ConstantValueOpt)
            Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundUserDefinedBinaryOperatorOperation(boundUserDefinedBinaryOperator As BoundUserDefinedBinaryOperator) As IBinaryOperatorExpression
            Dim binaryOperationKind As BinaryOperationKind = Helper.DeriveBinaryOperationKind(boundUserDefinedBinaryOperator.OperatorKind)
            Dim leftOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function()
                                                                                 If boundUserDefinedBinaryOperator.UnderlyingExpression.Kind = BoundKind.Call Then
                                                                                     Return Create(boundUserDefinedBinaryOperator.Left)
                                                                                 Else
                                                                                     Return GetChildOfBadExpression(boundUserDefinedBinaryOperator.UnderlyingExpression, 0)
                                                                                 End If
                                                                             End Function)
            Dim rightOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function()
                                                                                  If boundUserDefinedBinaryOperator.UnderlyingExpression.Kind = BoundKind.Call Then
                                                                                      Return Create(boundUserDefinedBinaryOperator.Right)
                                                                                  Else
                                                                                      Return GetChildOfBadExpression(boundUserDefinedBinaryOperator.UnderlyingExpression, 1)
                                                                                  End If
                                                                              End Function)
            Dim operatorMethod As IMethodSymbol = If(boundUserDefinedBinaryOperator.UnderlyingExpression.Kind = BoundKind.Call, boundUserDefinedBinaryOperator.Call.Method, Nothing)
            Dim usesOperatorMethod As Boolean = operatorMethod IsNot Nothing
            Dim isInvalid As Boolean = boundUserDefinedBinaryOperator.HasErrors
            Dim syntax As SyntaxNode = boundUserDefinedBinaryOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedBinaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedBinaryOperator.ConstantValueOpt)
            Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundBinaryConditionalExpressionOperation(boundBinaryConditionalExpression As BoundBinaryConditionalExpression) As INullCoalescingExpression
H
Heejae Chang 已提交
347 348
            Dim primaryOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundBinaryConditionalExpression.TestExpression))
            Dim secondaryOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundBinaryConditionalExpression.ElseExpression))
H
Heejae Chang 已提交
349 350 351 352 353 354 355 356
            Dim isInvalid As Boolean = boundBinaryConditionalExpression.HasErrors
            Dim syntax As SyntaxNode = boundBinaryConditionalExpression.Syntax
            Dim type As ITypeSymbol = boundBinaryConditionalExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBinaryConditionalExpression.ConstantValueOpt)
            Return New LazyNullCoalescingExpression(primaryOperand, secondaryOperand, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundUserDefinedShortCircuitingOperatorOperation(boundUserDefinedShortCircuitingOperator As BoundUserDefinedShortCircuitingOperator) As IBinaryOperatorExpression
            Dim binaryOperationKind As BinaryOperationKind = If((boundUserDefinedShortCircuitingOperator.BitwiseOperator.OperatorKind And BinaryOperatorKind.And) <> 0, BinaryOperationKind.OperatorMethodConditionalAnd, BinaryOperationKind.OperatorMethodConditionalOr)
H
Heejae Chang 已提交
357 358
            Dim leftOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUserDefinedShortCircuitingOperator.LeftOperand))
            Dim rightOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUserDefinedShortCircuitingOperator.BitwiseOperator.Right))
H
Heejae Chang 已提交
359 360 361 362 363 364 365 366 367
            Dim usesOperatorMethod As Boolean = True
            Dim operatorMethod As IMethodSymbol = boundUserDefinedShortCircuitingOperator.BitwiseOperator.Call.Method
            Dim isInvalid As Boolean = boundUserDefinedShortCircuitingOperator.HasErrors
            Dim syntax As SyntaxNode = boundUserDefinedShortCircuitingOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedShortCircuitingOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedShortCircuitingOperator.ConstantValueOpt)
            Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundBadExpressionOperation(boundBadExpression As BoundBadExpression) As IInvalidExpression
H
Heejae Chang 已提交
368
            Dim children As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() boundBadExpression.ChildBoundNodes.SelectAsArray(Function(n) Create(n)))
H
Heejae Chang 已提交
369 370 371 372 373 374 375
            Dim isInvalid As Boolean = boundBadExpression.HasErrors
            Dim syntax As SyntaxNode = boundBadExpression.Syntax
            Dim type As ITypeSymbol = boundBadExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBadExpression.ConstantValueOpt)
            Return New LazyInvalidExpression(children, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundTryCastOperation(boundTryCast As BoundTryCast) As IConversionExpression
H
Heejae Chang 已提交
376
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTryCast.Operand))
H
Heejae Chang 已提交
377 378 379 380 381 382 383 384 385 386 387
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.TryCast
            Dim isExplicit As Boolean = True
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim isInvalid As Boolean = boundTryCast.HasErrors
            Dim syntax As SyntaxNode = boundTryCast.Syntax
            Dim type As ITypeSymbol = boundTryCast.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTryCast.ConstantValueOpt)
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundDirectCastOperation(boundDirectCast As BoundDirectCast) As IConversionExpression
H
Heejae Chang 已提交
388
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDirectCast.Operand))
H
Heejae Chang 已提交
389 390 391 392 393 394 395 396 397 398 399
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.Cast
            Dim isExplicit As Boolean = True
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim isInvalid As Boolean = boundDirectCast.HasErrors
            Dim syntax As SyntaxNode = boundDirectCast.Syntax
            Dim type As ITypeSymbol = boundDirectCast.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundDirectCast.ConstantValueOpt)
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundConversionOperation(boundConversion As BoundConversion) As IConversionExpression
H
Heejae Chang 已提交
400
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundConversion.Operand))
H
Heejae Chang 已提交
401 402 403 404 405 406 407 408 409 410 411
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.Basic
            Dim isExplicit As Boolean = boundConversion.ExplicitCastInCode
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim isInvalid As Boolean = boundConversion.HasErrors
            Dim syntax As SyntaxNode = boundConversion.Syntax
            Dim type As ITypeSymbol = boundConversion.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundConversion.ConstantValueOpt)
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundUserDefinedConversionOperation(boundUserDefinedConversion As BoundUserDefinedConversion) As IConversionExpression
H
Heejae Chang 已提交
412
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUserDefinedConversion.Operand))
H
Heejae Chang 已提交
413 414 415 416 417 418 419 420 421 422 423
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.OperatorMethod
            Dim isExplicit As Boolean = Not boundUserDefinedConversion.WasCompilerGenerated
            Dim usesOperatorMethod As Boolean = True
            Dim operatorMethod As IMethodSymbol = boundUserDefinedConversion.Call.Method
            Dim isInvalid As Boolean = boundUserDefinedConversion.HasErrors
            Dim syntax As SyntaxNode = boundUserDefinedConversion.Syntax
            Dim type As ITypeSymbol = boundUserDefinedConversion.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedConversion.ConstantValueOpt)
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundTernaryConditionalExpressionOperation(boundTernaryConditionalExpression As BoundTernaryConditionalExpression) As IConditionalChoiceExpression
H
Heejae Chang 已提交
424 425 426
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTernaryConditionalExpression.Condition))
            Dim ifTrueValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTernaryConditionalExpression.WhenTrue))
            Dim ifFalseValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTernaryConditionalExpression.WhenFalse))
H
Heejae Chang 已提交
427 428 429 430 431 432 433
            Dim isInvalid As Boolean = boundTernaryConditionalExpression.HasErrors
            Dim syntax As SyntaxNode = boundTernaryConditionalExpression.Syntax
            Dim type As ITypeSymbol = boundTernaryConditionalExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTernaryConditionalExpression.ConstantValueOpt)
            Return New LazyConditionalChoiceExpression(condition, ifTrueValue, ifFalseValue, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundTypeOfOperation(boundTypeOf As BoundTypeOf) As IIsTypeExpression
H
Heejae Chang 已提交
434
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTypeOf.Operand))
H
Heejae Chang 已提交
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
            Dim isType As ITypeSymbol = boundTypeOf.TargetType
            Dim isInvalid As Boolean = boundTypeOf.HasErrors
            Dim syntax As SyntaxNode = boundTypeOf.Syntax
            Dim type As ITypeSymbol = boundTypeOf.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTypeOf.ConstantValueOpt)
            Return New LazyIsTypeExpression(operand, isType, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundObjectCreationExpressionOperation(boundObjectCreationExpression As BoundObjectCreationExpression) As IObjectCreationExpression
            Dim constructor As IMethodSymbol = boundObjectCreationExpression.ConstructorOpt
            Dim memberInitializers As Lazy(Of ImmutableArray(Of ISymbolInitializer)) = New Lazy(Of ImmutableArray(Of ISymbolInitializer))(
                Function()
                    Return GetObjectCreationMemberInitializers(boundObjectCreationExpression)
                End Function)

            Debug.Assert(boundObjectCreationExpression.ConstructorOpt IsNot Nothing OrElse boundObjectCreationExpression.Arguments.IsEmpty())
            Dim argumentsInEvaluationOrder As Lazy(Of ImmutableArray(Of IArgument)) = New Lazy(Of ImmutableArray(Of IArgument))(
                Function()
                    Return If(boundObjectCreationExpression.ConstructorOpt Is Nothing,
                        ImmutableArray(Of IArgument).Empty,
                        DeriveArguments(boundObjectCreationExpression.Arguments, boundObjectCreationExpression.ConstructorOpt.Parameters))
                End Function)

            Dim isInvalid As Boolean = boundObjectCreationExpression.HasErrors
            Dim syntax As SyntaxNode = boundObjectCreationExpression.Syntax
            Dim type As ITypeSymbol = boundObjectCreationExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundObjectCreationExpression.ConstantValueOpt)
            Return New LazyObjectCreationExpression(constructor, memberInitializers, argumentsInEvaluationOrder, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundNewTOperation(boundNewT As BoundNewT) As ITypeParameterObjectCreationExpression
            Dim isInvalid As Boolean = boundNewT.HasErrors
            Dim syntax As SyntaxNode = boundNewT.Syntax
            Dim type As ITypeSymbol = boundNewT.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundNewT.ConstantValueOpt)
            Return New TypeParameterObjectCreationExpression(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundArrayCreationOperation(boundArrayCreation As BoundArrayCreation) As IArrayCreationExpression
471
            Dim elementType As ITypeSymbol = TryCast(boundArrayCreation.Type, IArrayTypeSymbol)?.ElementType
H
Heejae Chang 已提交
472
            Dim dimensionSizes As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() boundArrayCreation.Bounds.SelectAsArray(Function(n) Create(n)))
H
Heejae Chang 已提交
473 474 475 476 477 478 479 480
            Dim initializer As Lazy(Of IArrayInitializer) = New Lazy(Of IArrayInitializer)(Function() DirectCast(Create(boundArrayCreation.InitializerOpt), IArrayInitializer))
            Dim isInvalid As Boolean = boundArrayCreation.HasErrors
            Dim syntax As SyntaxNode = boundArrayCreation.Syntax
            Dim type As ITypeSymbol = boundArrayCreation.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundArrayCreation.ConstantValueOpt)
            Return New LazyArrayCreationExpression(elementType, dimensionSizes, initializer, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundArrayInitializationOperation(boundArrayInitialization As BoundArrayInitialization) As IArrayInitializer
H
Heejae Chang 已提交
481
            Dim elementValues As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() boundArrayInitialization.Initializers.SelectAsArray(Function(n) Create(n)))
H
Heejae Chang 已提交
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
            Dim isInvalid As Boolean = boundArrayInitialization.HasErrors
            Dim syntax As SyntaxNode = boundArrayInitialization.Syntax
            Dim type As ITypeSymbol = boundArrayInitialization.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundArrayInitialization.ConstantValueOpt)
            Return New LazyArrayInitializer(elementValues, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundPropertyAccessOperation(boundPropertyAccess As BoundPropertyAccess) As IIndexedPropertyReferenceExpression
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(
                Function()
                    If boundPropertyAccess.PropertySymbol.IsShared Then
                        Return Nothing
                    Else
                        Return Create(boundPropertyAccess.ReceiverOpt)
                    End If
                End Function)

            Dim [property] As IPropertySymbol = boundPropertyAccess.PropertySymbol
            Dim member As ISymbol = boundPropertyAccess.PropertySymbol
            Dim argumentsInEvaluationOrder As Lazy(Of ImmutableArray(Of IArgument)) = New Lazy(Of ImmutableArray(Of IArgument))(Function() DeriveArguments(boundPropertyAccess.Arguments, boundPropertyAccess.PropertySymbol.Parameters))
            Dim isInvalid As Boolean = boundPropertyAccess.HasErrors
            Dim syntax As SyntaxNode = boundPropertyAccess.Syntax
            Dim type As ITypeSymbol = boundPropertyAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundPropertyAccess.ConstantValueOpt)
            Return New LazyIndexedPropertyReferenceExpression([property], instance, member, argumentsInEvaluationOrder, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundEventAccessOperation(boundEventAccess As BoundEventAccess) As IEventReferenceExpression
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(
                Function()
                    If boundEventAccess.EventSymbol.IsShared Then
                        Return Nothing
                    Else
                        Return Create(boundEventAccess.ReceiverOpt)
                    End If
                End Function)

            Dim [event] As IEventSymbol = boundEventAccess.EventSymbol
            Dim member As ISymbol = boundEventAccess.EventSymbol
            Dim isInvalid As Boolean = boundEventAccess.HasErrors
            Dim syntax As SyntaxNode = boundEventAccess.Syntax
            Dim type As ITypeSymbol = boundEventAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundEventAccess.ConstantValueOpt)
            Return New LazyEventReferenceExpression([event], instance, member, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundDelegateCreationExpressionOperation(boundDelegateCreationExpression As BoundDelegateCreationExpression) As IMethodBindingExpression
            Dim method As IMethodSymbol = boundDelegateCreationExpression.Method
            Dim isVirtual As Boolean = boundDelegateCreationExpression.Method IsNot Nothing AndAlso (boundDelegateCreationExpression.Method.IsOverridable OrElse boundDelegateCreationExpression.Method.IsOverrides OrElse boundDelegateCreationExpression.Method.IsMustOverride) AndAlso Not boundDelegateCreationExpression.SuppressVirtualCalls
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(
                Function()
                    If boundDelegateCreationExpression.Method.IsShared Then
                        Return Nothing
                    Else
                        Return Create(boundDelegateCreationExpression.ReceiverOpt)
                    End If
                End Function)

            Dim member As ISymbol = boundDelegateCreationExpression.Method
            Dim isInvalid As Boolean = boundDelegateCreationExpression.HasErrors
            Dim syntax As SyntaxNode = boundDelegateCreationExpression.Syntax
            Dim type As ITypeSymbol = boundDelegateCreationExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundDelegateCreationExpression.ConstantValueOpt)
            Return New LazyMethodBindingExpression(method, isVirtual, instance, member, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundFieldAccessOperation(boundFieldAccess As BoundFieldAccess) As IFieldReferenceExpression
            Dim field As IFieldSymbol = boundFieldAccess.FieldSymbol
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(
                Function()
                    If boundFieldAccess.FieldSymbol.IsShared Then
                        Return Nothing
                    Else
H
Heejae Chang 已提交
551
                        Return Create(boundFieldAccess.ReceiverOpt)
H
Heejae Chang 已提交
552 553 554 555 556 557 558 559 560 561 562
                    End If
                End Function)

            Dim member As ISymbol = boundFieldAccess.FieldSymbol
            Dim isInvalid As Boolean = boundFieldAccess.HasErrors
            Dim syntax As SyntaxNode = boundFieldAccess.Syntax
            Dim type As ITypeSymbol = boundFieldAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundFieldAccess.ConstantValueOpt)
            Return New LazyFieldReferenceExpression(field, instance, member, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundConditionalAccessOperation(boundConditionalAccess As BoundConditionalAccess) As IConditionalAccessExpression
H
Heejae Chang 已提交
563 564
            Dim conditionalValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundConditionalAccess.AccessExpression))
            Dim conditionalInstance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundConditionalAccess.Receiver))
H
Heejae Chang 已提交
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
            Dim isInvalid As Boolean = boundConditionalAccess.HasErrors
            Dim syntax As SyntaxNode = boundConditionalAccess.Syntax
            Dim type As ITypeSymbol = boundConditionalAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundConditionalAccess.ConstantValueOpt)
            Return New LazyConditionalAccessExpression(conditionalValue, conditionalInstance, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundConditionalAccessReceiverPlaceholderOperation(boundConditionalAccessReceiverPlaceholder As BoundConditionalAccessReceiverPlaceholder) As IConditionalAccessInstanceExpression
            Dim isInvalid As Boolean = boundConditionalAccessReceiverPlaceholder.HasErrors
            Dim syntax As SyntaxNode = boundConditionalAccessReceiverPlaceholder.Syntax
            Dim type As ITypeSymbol = boundConditionalAccessReceiverPlaceholder.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundConditionalAccessReceiverPlaceholder.ConstantValueOpt)
            Return New ConditionalAccessInstanceExpression(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundParameterOperation(boundParameter As BoundParameter) As IParameterReferenceExpression
            Dim parameter As IParameterSymbol = boundParameter.ParameterSymbol
            Dim isInvalid As Boolean = boundParameter.HasErrors
            Dim syntax As SyntaxNode = boundParameter.Syntax
            Dim type As ITypeSymbol = boundParameter.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundParameter.ConstantValueOpt)
            Return New ParameterReferenceExpression(parameter, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundLocalOperation(boundLocal As BoundLocal) As ILocalReferenceExpression
            Dim local As ILocalSymbol = boundLocal.LocalSymbol
            Dim isInvalid As Boolean = boundLocal.HasErrors
            Dim syntax As SyntaxNode = boundLocal.Syntax
            Dim type As ITypeSymbol = boundLocal.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLocal.ConstantValueOpt)
            Return New LocalReferenceExpression(local, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundLateMemberAccessOperation(boundLateMemberAccess As BoundLateMemberAccess) As ILateBoundMemberReferenceExpression
H
Heejae Chang 已提交
595
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundLateMemberAccess.ReceiverOpt))
H
Heejae Chang 已提交
596 597 598 599 600 601 602 603 604
            Dim memberName As String = boundLateMemberAccess.NameOpt
            Dim isInvalid As Boolean = boundLateMemberAccess.HasErrors
            Dim syntax As SyntaxNode = boundLateMemberAccess.Syntax
            Dim type As ITypeSymbol = boundLateMemberAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLateMemberAccess.ConstantValueOpt)
            Return New LazyLateBoundMemberReferenceExpression(instance, memberName, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundFieldInitializerOperation(boundFieldInitializer As BoundFieldInitializer) As IFieldInitializer
            Dim initializedFields As ImmutableArray(Of IFieldSymbol) = ImmutableArray(Of IFieldSymbol).CastUp(boundFieldInitializer.InitializedFields)
H
Heejae Chang 已提交
605
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundFieldInitializer.InitialValue))
H
Heejae Chang 已提交
606 607 608 609 610 611 612 613 614
            Dim kind As OperationKind = OperationKind.FieldInitializerAtDeclaration
            Dim isInvalid As Boolean = boundFieldInitializer.HasErrors
            Dim syntax As SyntaxNode = boundFieldInitializer.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyFieldInitializer(initializedFields, value, kind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundPropertyInitializerOperation(boundPropertyInitializer As BoundPropertyInitializer) As IPropertyInitializer
            Dim initializedProperty As IPropertySymbol = boundPropertyInitializer.InitializedProperties.FirstOrDefault()
H
Heejae Chang 已提交
615
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundPropertyInitializer.InitialValue))
H
Heejae Chang 已提交
616 617 618 619 620 621 622 623 624
            Dim kind As OperationKind = OperationKind.PropertyInitializerAtDeclaration
            Dim isInvalid As Boolean = boundPropertyInitializer.HasErrors
            Dim syntax As SyntaxNode = boundPropertyInitializer.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyPropertyInitializer(initializedProperty, value, kind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundParameterEqualsValueOperation(boundParameterEqualsValue As BoundParameterEqualsValue) As IParameterInitializer
            Dim parameter As IParameterSymbol = boundParameterEqualsValue.Parameter
H
Heejae Chang 已提交
625
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundParameterEqualsValue.Value))
H
Heejae Chang 已提交
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
            Dim kind As OperationKind = OperationKind.ParameterInitializerAtDeclaration
            Dim isInvalid As Boolean = DirectCast(boundParameterEqualsValue.Value, IOperation).IsInvalid
            Dim syntax As SyntaxNode = boundParameterEqualsValue.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyParameterInitializer(parameter, value, kind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundRValuePlaceholderOperation(boundRValuePlaceholder As BoundRValuePlaceholder) As IPlaceholderExpression
            Dim isInvalid As Boolean = boundRValuePlaceholder.HasErrors
            Dim syntax As SyntaxNode = boundRValuePlaceholder.Syntax
            Dim type As ITypeSymbol = boundRValuePlaceholder.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundRValuePlaceholder.ConstantValueOpt)
            Return New PlaceholderExpression(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundIfStatementOperation(boundIfStatement As BoundIfStatement) As IIfStatement
H
Heejae Chang 已提交
641 642 643
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundIfStatement.Condition))
            Dim ifTrueStatement As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundIfStatement.Consequence))
            Dim ifFalseStatement As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundIfStatement.AlternativeOpt))
H
Heejae Chang 已提交
644 645 646 647 648 649 650
            Dim isInvalid As Boolean = boundIfStatement.HasErrors
            Dim syntax As SyntaxNode = boundIfStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyIfStatement(condition, ifTrueStatement, ifFalseStatement, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundSelectStatementOperation(boundSelectStatement As BoundSelectStatement) As ISwitchStatement
H
Heejae Chang 已提交
651
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundSelectStatement.ExpressionStatement.Expression))
H
Heejae Chang 已提交
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
            Dim cases As Lazy(Of ImmutableArray(Of ISwitchCase)) = New Lazy(Of ImmutableArray(Of ISwitchCase))(Function() GetSwitchStatementCases(boundSelectStatement))
            Dim isInvalid As Boolean = boundSelectStatement.HasErrors
            Dim syntax As SyntaxNode = boundSelectStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazySwitchStatement(value, cases, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundSimpleCaseClauseOperation(boundSimpleCaseClause As BoundSimpleCaseClause) As ISingleValueCaseClause
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(GetSingleValueCaseClauseValue(boundSimpleCaseClause)))
            Dim equality As BinaryOperationKind = GetSingleValueCaseClauseEquality(boundSimpleCaseClause)
            Dim caseKind As CaseKind = CaseKind.SingleValue
            Dim isInvalid As Boolean = boundSimpleCaseClause.HasErrors
            Dim syntax As SyntaxNode = boundSimpleCaseClause.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazySingleValueCaseClause(value, equality, caseKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundRangeCaseClauseOperation(boundRangeCaseClause As BoundRangeCaseClause) As IRangeCaseClause
            Dim minimumValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(
                Function()
                    If boundRangeCaseClause.LowerBoundOpt IsNot Nothing Then
                        Return Create(boundRangeCaseClause.LowerBoundOpt)
                    End If

                    If boundRangeCaseClause.LowerBoundConditionOpt.Kind = BoundKind.BinaryOperator Then
                        Dim lowerBound As BoundBinaryOperator = DirectCast(boundRangeCaseClause.LowerBoundConditionOpt, BoundBinaryOperator)
                        If lowerBound.OperatorKind = BinaryOperatorKind.GreaterThanOrEqual Then
                            Return Create(lowerBound.Right)
                        End If
                    End If

                    Return Nothing
                End Function)
            Dim maximumValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(
                Function()
                    If boundRangeCaseClause.UpperBoundOpt IsNot Nothing Then
                        Return Create(boundRangeCaseClause.UpperBoundOpt)
                    End If

                    If boundRangeCaseClause.UpperBoundConditionOpt.Kind = BoundKind.BinaryOperator Then
                        Dim upperBound As BoundBinaryOperator = DirectCast(boundRangeCaseClause.UpperBoundConditionOpt, BoundBinaryOperator)
                        If upperBound.OperatorKind = BinaryOperatorKind.LessThanOrEqual Then
                            Return Create(upperBound.Right)
                        End If
                    End If

                    Return Nothing
                End Function)
            Dim caseKind As CaseKind = CaseKind.Range
            Dim isInvalid As Boolean = boundRangeCaseClause.HasErrors
            Dim syntax As SyntaxNode = boundRangeCaseClause.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyRangeCaseClause(minimumValue, maximumValue, caseKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundRelationalCaseClauseOperation(boundRelationalCaseClause As BoundRelationalCaseClause) As IRelationalCaseClause
            Dim valueExpression = GetRelationalCaseClauseValue(boundRelationalCaseClause)
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(valueExpression))
H
Heejae Chang 已提交
710
            Dim relation As BinaryOperationKind = If(valueExpression IsNot Nothing, Helper.DeriveBinaryOperationKind(boundRelationalCaseClause.OperatorKind, valueExpression), BinaryOperationKind.Invalid)
H
Heejae Chang 已提交
711 712 713 714 715 716 717 718 719 720
            Dim caseKind As CaseKind = CaseKind.Relational
            Dim isInvalid As Boolean = boundRelationalCaseClause.HasErrors
            Dim syntax As SyntaxNode = boundRelationalCaseClause.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyRelationalCaseClause(value, relation, caseKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IWhileUntilLoopStatement
            Dim isTopTest As Boolean = boundDoLoopStatement.ConditionIsTop
            Dim isWhile As Boolean = Not boundDoLoopStatement.ConditionIsUntil
H
Heejae Chang 已提交
721
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.ConditionOpt))
H
Heejae Chang 已提交
722
            Dim loopKind As LoopKind = LoopKind.WhileUntil
H
Heejae Chang 已提交
723
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.Body))
H
Heejae Chang 已提交
724 725 726 727 728 729 730
            Dim isInvalid As Boolean = boundDoLoopStatement.HasErrors
            Dim syntax As SyntaxNode = boundDoLoopStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, loopKind, body, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForLoopStatement
H
Heejae Chang 已提交
731 732
            Dim before As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() GetForLoopStatementBefore(boundForToStatement))
            Dim atLoopBottom As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() GetForLoopStatementAtLoopBottom(boundForToStatement))
H
Heejae Chang 已提交
733
            Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
H
Heejae Chang 已提交
734
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetForWhileUntilLoopStatmentCondition(boundForToStatement))
H
Heejae Chang 已提交
735
            Dim loopKind As LoopKind = LoopKind.For
H
Heejae Chang 已提交
736
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.Body))
H
Heejae Chang 已提交
737 738 739 740 741 742 743 744
            Dim isInvalid As Boolean = boundForToStatement.HasErrors
            Dim syntax As SyntaxNode = boundForToStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyForLoopStatement(before, atLoopBottom, locals, condition, loopKind, body, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundForEachStatementOperation(boundForEachStatement As BoundForEachStatement) As IForEachLoopStatement
            Dim iterationVariable As ILocalSymbol = Nothing ' Manual
H
Heejae Chang 已提交
745
            Dim collection As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Collection))
H
Heejae Chang 已提交
746
            Dim loopKind As LoopKind = LoopKind.ForEach
H
Heejae Chang 已提交
747
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Body))
H
Heejae Chang 已提交
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
            Dim isInvalid As Boolean = boundForEachStatement.HasErrors
            Dim syntax As SyntaxNode = boundForEachStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyForEachLoopStatement(iterationVariable, collection, loopKind, body, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundTryStatementOperation(boundTryStatement As BoundTryStatement) As ITryStatement
            Dim body As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundTryStatement.TryBlock), IBlockStatement))
            Dim catches As Lazy(Of ImmutableArray(Of ICatchClause)) = New Lazy(Of ImmutableArray(Of ICatchClause))(Function() boundTryStatement.CatchBlocks.As(Of ICatchClause)())
            Dim finallyHandler As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundTryStatement.FinallyBlockOpt), IBlockStatement))
            Dim isInvalid As Boolean = boundTryStatement.HasErrors
            Dim syntax As SyntaxNode = boundTryStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyTryStatement(body, catches, finallyHandler, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundCatchBlockOperation(boundCatchBlock As BoundCatchBlock) As ICatchClause
            Dim handler As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundCatchBlock.Body), IBlockStatement))
            Dim caughtType As ITypeSymbol = Nothing ' Manual
H
Heejae Chang 已提交
767
            Dim filter As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundCatchBlock.ExceptionFilterOpt))
H
Heejae Chang 已提交
768 769 770 771 772 773 774 775
            Dim exceptionLocal As ILocalSymbol = boundCatchBlock.LocalOpt
            Dim isInvalid As Boolean = boundCatchBlock.HasErrors
            Dim syntax As SyntaxNode = boundCatchBlock.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyCatchClause(handler, caughtType, filter, exceptionLocal, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundBlockOperation(boundBlock As BoundBlock) As IBlockStatement
H
Heejae Chang 已提交
776
            Dim statements As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() GetBlockStatementStatements(boundBlock))
H
Heejae Chang 已提交
777 778 779 780 781 782 783 784
            Dim locals As ImmutableArray(Of ILocalSymbol) = boundBlock.Locals.As(Of ILocalSymbol)()
            Dim isInvalid As Boolean = boundBlock.HasErrors
            Dim syntax As SyntaxNode = boundBlock.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyBlockStatement(statements, locals, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundBadStatementOperation(boundBadStatement As BoundBadStatement) As IInvalidStatement
H
Heejae Chang 已提交
785 786 787 788 789 790 791 792 793 794 795 796
            Dim children As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
                Function()
                    Dim builder As ArrayBuilder(Of IOperation) = ArrayBuilder(Of IOperation).GetInstance(boundBadStatement.ChildBoundNodes.Length)
                    For Each childNode In boundBadStatement.ChildBoundNodes
                        Dim operation = Create(childNode)
                        If operation IsNot Nothing Then
                            builder.Add(operation)
                        End If
                    Next

                    Return builder.ToImmutableAndFree()
                End Function)
H
Heejae Chang 已提交
797 798 799 800 801 802 803
            Dim isInvalid As Boolean = boundBadStatement.HasErrors
            Dim syntax As SyntaxNode = boundBadStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyInvalidStatement(children, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundReturnStatementOperation(boundReturnStatement As BoundReturnStatement) As IReturnStatement
H
Heejae Chang 已提交
804
            Dim returnedValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundReturnStatement.ExpressionOpt))
H
Heejae Chang 已提交
805 806 807 808 809 810 811
            Dim isInvalid As Boolean = boundReturnStatement.HasErrors
            Dim syntax As SyntaxNode = boundReturnStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyReturnStatement(returnedValue, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundThrowStatementOperation(boundThrowStatement As BoundThrowStatement) As IThrowStatement
H
Heejae Chang 已提交
812
            Dim thrownObject As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundThrowStatement.ExpressionOpt))
H
Heejae Chang 已提交
813 814 815 816 817 818 819 820 821
            Dim isInvalid As Boolean = boundThrowStatement.HasErrors
            Dim syntax As SyntaxNode = boundThrowStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyThrowStatement(thrownObject, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileUntilLoopStatement
            Dim isTopTest As Boolean = True
            Dim isWhile As Boolean = True
H
Heejae Chang 已提交
822
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Condition))
H
Heejae Chang 已提交
823
            Dim loopKind As LoopKind = LoopKind.WhileUntil
H
Heejae Chang 已提交
824
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Body))
H
Heejae Chang 已提交
825 826 827 828 829 830 831
            Dim isInvalid As Boolean = boundWhileStatement.HasErrors
            Dim syntax As SyntaxNode = boundWhileStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, loopKind, body, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationStatement
H
Heejae Chang 已提交
832
            Dim declarations As Lazy(Of ImmutableArray(Of IVariableDeclaration)) = New Lazy(Of ImmutableArray(Of IVariableDeclaration))(Function() GetVariableDeclarationStatementVariables(boundDimStatement))
H
Heejae Chang 已提交
833 834 835 836 837 838 839
            Dim isInvalid As Boolean = boundDimStatement.HasErrors
            Dim syntax As SyntaxNode = boundDimStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyVariableDeclarationStatement(declarations, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundYieldStatementOperation(boundYieldStatement As BoundYieldStatement) As IReturnStatement
H
Heejae Chang 已提交
840
            Dim returnedValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundYieldStatement.Expression))
H
Heejae Chang 已提交
841 842 843 844 845 846 847 848
            Dim isInvalid As Boolean = boundYieldStatement.HasErrors
            Dim syntax As SyntaxNode = boundYieldStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyReturnStatement(returnedValue, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundLabelStatementOperation(boundLabelStatement As BoundLabelStatement) As ILabelStatement
            Dim label As ILabelSymbol = boundLabelStatement.Label
H
Heejae Chang 已提交
849
            Dim labeledStatement As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(Nothing))
H
Heejae Chang 已提交
850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
            Dim isInvalid As Boolean = boundLabelStatement.HasErrors
            Dim syntax As SyntaxNode = boundLabelStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyLabelStatement(label, labeledStatement, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundGotoStatementOperation(boundGotoStatement As BoundGotoStatement) As IBranchStatement
            Dim target As ILabelSymbol = boundGotoStatement.Label
            Dim branchKind As BranchKind = BranchKind.GoTo
            Dim isInvalid As Boolean = boundGotoStatement.HasErrors
            Dim syntax As SyntaxNode = boundGotoStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New BranchStatement(target, branchKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundContinueStatementOperation(boundContinueStatement As BoundContinueStatement) As IBranchStatement
            Dim target As ILabelSymbol = boundContinueStatement.Label
            Dim branchKind As BranchKind = BranchKind.Continue
            Dim isInvalid As Boolean = boundContinueStatement.HasErrors
            Dim syntax As SyntaxNode = boundContinueStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New BranchStatement(target, branchKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundExitStatementOperation(boundExitStatement As BoundExitStatement) As IBranchStatement
            Dim target As ILabelSymbol = boundExitStatement.Label
            Dim branchKind As BranchKind = BranchKind.Break
            Dim isInvalid As Boolean = boundExitStatement.HasErrors
            Dim syntax As SyntaxNode = boundExitStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New BranchStatement(target, branchKind, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundSyncLockStatementOperation(boundSyncLockStatement As BoundSyncLockStatement) As ILockStatement
H
Heejae Chang 已提交
884 885
            Dim lockedObject As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundSyncLockStatement.LockExpression))
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundSyncLockStatement.Body))
H
Heejae Chang 已提交
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
            Dim isInvalid As Boolean = boundSyncLockStatement.HasErrors
            Dim syntax As SyntaxNode = boundSyncLockStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyLockStatement(lockedObject, body, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundNoOpStatementOperation(boundNoOpStatement As BoundNoOpStatement) As IEmptyStatement
            Dim isInvalid As Boolean = boundNoOpStatement.HasErrors
            Dim syntax As SyntaxNode = boundNoOpStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New EmptyStatement(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundStopStatementOperation(boundStopStatement As BoundStopStatement) As IStopStatement
            Dim isInvalid As Boolean = boundStopStatement.HasErrors
            Dim syntax As SyntaxNode = boundStopStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New StopStatement(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundEndStatementOperation(boundEndStatement As BoundEndStatement) As IEndStatement
            Dim isInvalid As Boolean = boundEndStatement.HasErrors
            Dim syntax As SyntaxNode = boundEndStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New EndStatement(isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundWithStatementOperation(boundWithStatement As BoundWithStatement) As IWithStatement
H
Heejae Chang 已提交
914 915
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWithStatement.Body))
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWithStatement.OriginalExpression))
H
Heejae Chang 已提交
916 917 918 919 920 921 922
            Dim isInvalid As Boolean = boundWithStatement.HasErrors
            Dim syntax As SyntaxNode = boundWithStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyWithStatement(body, value, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundUsingStatementOperation(boundUsingStatement As BoundUsingStatement) As IUsingStatement
H
Heejae Chang 已提交
923
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUsingStatement.Body))
H
Heejae Chang 已提交
924
            Dim declaration As Lazy(Of IVariableDeclarationStatement) = New Lazy(Of IVariableDeclarationStatement)(Function() GetUsingStatementDeclaration(boundUsingStatement))
H
Heejae Chang 已提交
925
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUsingStatement.ResourceExpressionOpt))
H
Heejae Chang 已提交
926 927 928 929 930 931 932
            Dim isInvalid As Boolean = boundUsingStatement.HasErrors
            Dim syntax As SyntaxNode = boundUsingStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyUsingStatement(body, declaration, value, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundExpressionStatementOperation(boundExpressionStatement As BoundExpressionStatement) As IExpressionStatement
H
Heejae Chang 已提交
933
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundExpressionStatement.Expression))
H
Heejae Chang 已提交
934 935 936 937 938 939 940
            Dim isInvalid As Boolean = boundExpressionStatement.HasErrors
            Dim syntax As SyntaxNode = boundExpressionStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyExpressionStatement(expression, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundRaiseEventStatementOperation(boundRaiseEventStatement As BoundRaiseEventStatement) As IExpressionStatement
H
Heejae Chang 已提交
941
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundRaiseEventStatement.EventInvocation))
H
Heejae Chang 已提交
942 943 944 945 946 947 948
            Dim isInvalid As Boolean = boundRaiseEventStatement.HasErrors
            Dim syntax As SyntaxNode = boundRaiseEventStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyExpressionStatement(expression, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundAddHandlerStatementOperation(boundAddHandlerStatement As BoundAddHandlerStatement) As IExpressionStatement
H
Heejae Chang 已提交
949
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetAddHandlerStatementExpression(boundAddHandlerStatement))
H
Heejae Chang 已提交
950 951 952 953 954 955 956
            Dim isInvalid As Boolean = boundAddHandlerStatement.HasErrors
            Dim syntax As SyntaxNode = boundAddHandlerStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyExpressionStatement(expression, isInvalid, syntax, type, constantValue)
        End Function
        Private Shared Function CreateBoundRemoveHandlerStatementOperation(boundRemoveHandlerStatement As BoundRemoveHandlerStatement) As IExpressionStatement
H
Heejae Chang 已提交
957
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetRemoveStatementExpression(boundRemoveHandlerStatement))
H
Heejae Chang 已提交
958 959 960 961 962 963 964 965 966 967
            Dim isInvalid As Boolean = boundRemoveHandlerStatement.HasErrors
            Dim syntax As SyntaxNode = boundRemoveHandlerStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
            Return New LazyExpressionStatement(expression, isInvalid, syntax, type, constantValue)
        End Function
    End Class
End Namespace