VisualBasicOperationFactory.vb 75.8 KB
Newer Older
H
Heejae Chang 已提交
1
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
H
Heejae Chang 已提交
2

3
Imports System.Collections.Concurrent
H
Heejae Chang 已提交
4
Imports System.Collections.Immutable
F
Fredric Silberberg 已提交
5
Imports Microsoft.CodeAnalysis.PooledObjects
H
Heejae Chang 已提交
6 7 8
Imports Microsoft.CodeAnalysis.VisualBasic

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

11 12
        Private ReadOnly _cache As ConcurrentDictionary(Of BoundNode, IOperation) =
            New ConcurrentDictionary(Of BoundNode, IOperation)(concurrencyLevel:=2, capacity:=10)
H
Heejae Chang 已提交
13

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

19
            Return _cache.GetOrAdd(boundNode, Function(n) CreateInternal(n))
H
Heejae Chang 已提交
20 21
        End Function

22
        Private Function CreateInternal(boundNode As BoundNode) As IOperation
H
Heejae Chang 已提交
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
            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.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))
166 167 168
                Case BoundKind.InterpolatedStringExpression
                    Return CreateBoundInterpolatedStringExpressionOperation(DirectCast(boundNode, BoundInterpolatedStringExpression))
                Case BoundKind.Interpolation
M
Manish Vasani 已提交
169
                    Return CreateBoundInterpolationOperation(DirectCast(boundNode, BoundInterpolation))
170 171 172 173 174 175
                Case BoundKind.AnonymousTypeCreationExpression
                    Return CreateBoundAnonymousTypeCreationExpressionOperation(DirectCast(boundNode, BoundAnonymousTypeCreationExpression))
                Case BoundKind.AnonymousTypeFieldInitializer
                    Return Create(DirectCast(boundNode, BoundAnonymousTypeFieldInitializer).Value)
                Case BoundKind.AnonymousTypePropertyAccess
                    Return CreateBoundAnonymousTypePropertyAccessOperation(DirectCast(boundNode, BoundAnonymousTypePropertyAccess))
H
Heejae Chang 已提交
176
                Case Else
177
                    Dim constantValue = ConvertToOptional(TryCast(boundNode, BoundExpression)?.ConstantValueOpt)
H
Heejae Chang 已提交
178
                    Return Operation.CreateOperationNone(boundNode.Syntax, constantValue, Function() GetIOperationChildren(boundNode))
H
Heejae Chang 已提交
179 180
            End Select
        End Function
H
Heejae Chang 已提交
181

182
        Private Function GetIOperationChildren(boundNode As BoundNode) As ImmutableArray(Of IOperation)
183 184 185 186 187 188 189 190 191 192 193 194 195 196
            Dim boundNodeWithChildren = DirectCast(boundNode, IBoundNodeWithIOperationChildren)
            If boundNodeWithChildren.Children.IsDefaultOrEmpty Then
                Return ImmutableArray(Of IOperation).Empty
            End If

            Dim builder = ArrayBuilder(Of IOperation).GetInstance(boundNodeWithChildren.Children.Length)
            For Each childNode In boundNodeWithChildren.Children
                Dim operation = Create(childNode)
                builder.Add(operation)
            Next

            Return builder.ToImmutableAndFree()
        End Function

197
        Private Function CreateBoundAssignmentOperatorOperation(boundAssignmentOperator As BoundAssignmentOperator) As IOperation
H
Heejae Chang 已提交
198 199 200
            Dim kind = GetAssignmentKind(boundAssignmentOperator)
            If kind = OperationKind.CompoundAssignmentExpression Then
                Dim binaryOperationKind As BinaryOperationKind = DirectCast(Create(boundAssignmentOperator.Right), IBinaryOperatorExpression).BinaryOperationKind
H
Heejae Chang 已提交
201
                Dim target As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAssignmentOperator.Left))
H
Heejae Chang 已提交
202 203 204 205 206 207
                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 syntax As SyntaxNode = boundAssignmentOperator.Syntax
                Dim type As ITypeSymbol = boundAssignmentOperator.Type
                Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignmentOperator.ConstantValueOpt)
H
Heejae Chang 已提交
208
                Return New LazyCompoundAssignmentExpression(binaryOperationKind, target, value, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
209
            Else
H
Heejae Chang 已提交
210 211
                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 已提交
212 213 214
                Dim syntax As SyntaxNode = boundAssignmentOperator.Syntax
                Dim type As ITypeSymbol = boundAssignmentOperator.Type
                Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignmentOperator.ConstantValueOpt)
H
Heejae Chang 已提交
215
                Return New LazySimpleAssignmentExpression(target, value, syntax, type, constantValue)
H
Heejae Chang 已提交
216 217
            End If
        End Function
H
Heejae Chang 已提交
218

219
        Private Function CreateBoundMeReferenceOperation(boundMeReference As BoundMeReference) As IInstanceReferenceExpression
H
Heejae Chang 已提交
220 221 222 223
            Dim instanceReferenceKind As InstanceReferenceKind = If(boundMeReference.WasCompilerGenerated, InstanceReferenceKind.Implicit, InstanceReferenceKind.Explicit)
            Dim syntax As SyntaxNode = boundMeReference.Syntax
            Dim type As ITypeSymbol = boundMeReference.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundMeReference.ConstantValueOpt)
H
Heejae Chang 已提交
224
            Return New InstanceReferenceExpression(instanceReferenceKind, syntax, type, constantValue)
H
Heejae Chang 已提交
225
        End Function
H
Heejae Chang 已提交
226

227
        Private Function CreateBoundMyBaseReferenceOperation(boundMyBaseReference As BoundMyBaseReference) As IInstanceReferenceExpression
H
Heejae Chang 已提交
228 229 230 231
            Dim instanceReferenceKind As InstanceReferenceKind = InstanceReferenceKind.BaseClass
            Dim syntax As SyntaxNode = boundMyBaseReference.Syntax
            Dim type As ITypeSymbol = boundMyBaseReference.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundMyBaseReference.ConstantValueOpt)
H
Heejae Chang 已提交
232
            Return New InstanceReferenceExpression(instanceReferenceKind, syntax, type, constantValue)
H
Heejae Chang 已提交
233
        End Function
H
Heejae Chang 已提交
234

235
        Private Function CreateBoundMyClassReferenceOperation(boundMyClassReference As BoundMyClassReference) As IInstanceReferenceExpression
H
Heejae Chang 已提交
236 237 238 239
            Dim instanceReferenceKind As InstanceReferenceKind = InstanceReferenceKind.ThisClass
            Dim syntax As SyntaxNode = boundMyClassReference.Syntax
            Dim type As ITypeSymbol = boundMyClassReference.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundMyClassReference.ConstantValueOpt)
H
Heejae Chang 已提交
240
            Return New InstanceReferenceExpression(instanceReferenceKind, syntax, type, constantValue)
H
Heejae Chang 已提交
241
        End Function
H
Heejae Chang 已提交
242

243
        Private Function CreateBoundLiteralOperation(boundLiteral As BoundLiteral) As ILiteralExpression
H
Heejae Chang 已提交
244 245 246 247
            Dim text As String = boundLiteral.Syntax.ToString()
            Dim syntax As SyntaxNode = boundLiteral.Syntax
            Dim type As ITypeSymbol = boundLiteral.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLiteral.ConstantValueOpt)
H
Heejae Chang 已提交
248
            Return New LiteralExpression(text, syntax, type, constantValue)
H
Heejae Chang 已提交
249
        End Function
H
Heejae Chang 已提交
250

251
        Private Function CreateBoundAwaitOperatorOperation(boundAwaitOperator As BoundAwaitOperator) As IAwaitExpression
H
Heejae Chang 已提交
252
            Dim awaitedValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAwaitOperator.Operand))
H
Heejae Chang 已提交
253 254 255
            Dim syntax As SyntaxNode = boundAwaitOperator.Syntax
            Dim type As ITypeSymbol = boundAwaitOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAwaitOperator.ConstantValueOpt)
H
Heejae Chang 已提交
256
            Return New LazyAwaitExpression(awaitedValue, syntax, type, constantValue)
H
Heejae Chang 已提交
257
        End Function
H
Heejae Chang 已提交
258

259
        Private Function CreateBoundLambdaOperation(boundLambda As BoundLambda) As ILambdaExpression
H
Heejae Chang 已提交
260 261 262 263 264
            Dim signature As IMethodSymbol = boundLambda.LambdaSymbol
            Dim body As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundLambda.Body), IBlockStatement))
            Dim syntax As SyntaxNode = boundLambda.Syntax
            Dim type As ITypeSymbol = boundLambda.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLambda.ConstantValueOpt)
H
Heejae Chang 已提交
265
            Return New LazyLambdaExpression(signature, body, syntax, type, constantValue)
H
Heejae Chang 已提交
266
        End Function
H
Heejae Chang 已提交
267

268
        Private Function CreateBoundCallOperation(boundCall As BoundCall) As IInvocationExpression
H
Heejae Chang 已提交
269
            Dim targetMethod As IMethodSymbol = boundCall.Method
H
Heejae Chang 已提交
270
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() If(boundCall.Method.IsShared, Nothing, Create(boundCall.ReceiverOpt)))
H
Heejae Chang 已提交
271 272

            Dim method As IMethodSymbol = boundCall.Method
H
Heejae Chang 已提交
273
            Dim receiver As IOperation = Create(boundCall.ReceiverOpt)
H
Heejae Chang 已提交
274 275 276 277 278 279
            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 syntax As SyntaxNode = boundCall.Syntax
            Dim type As ITypeSymbol = boundCall.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundCall.ConstantValueOpt)
H
Heejae Chang 已提交
280
            Return New LazyInvocationExpression(targetMethod, instance, isVirtual, argumentsInEvaluationOrder, syntax, type, constantValue)
H
Heejae Chang 已提交
281
        End Function
H
Heejae Chang 已提交
282

283
        Private Function CreateBoundOmittedArgumentOperation(boundOmittedArgument As BoundOmittedArgument) As IOmittedArgumentExpression
H
Heejae Chang 已提交
284 285 286
            Dim syntax As SyntaxNode = boundOmittedArgument.Syntax
            Dim type As ITypeSymbol = boundOmittedArgument.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundOmittedArgument.ConstantValueOpt)
H
Heejae Chang 已提交
287
            Return New OmittedArgumentExpression(syntax, type, constantValue)
H
Heejae Chang 已提交
288
        End Function
H
Heejae Chang 已提交
289

290
        Private Function CreateBoundParenthesizedOperation(boundParenthesized As BoundParenthesized) As IParenthesizedExpression
H
Heejae Chang 已提交
291
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundParenthesized.Expression))
H
Heejae Chang 已提交
292 293 294
            Dim syntax As SyntaxNode = boundParenthesized.Syntax
            Dim type As ITypeSymbol = boundParenthesized.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundParenthesized.ConstantValueOpt)
H
Heejae Chang 已提交
295
            Return New LazyParenthesizedExpression(operand, syntax, type, constantValue)
H
Heejae Chang 已提交
296
        End Function
H
Heejae Chang 已提交
297

298
        Private Function CreateBoundArrayAccessOperation(boundArrayAccess As BoundArrayAccess) As IArrayElementReferenceExpression
H
Heejae Chang 已提交
299
            Dim arrayReference As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundArrayAccess.Expression))
H
Heejae Chang 已提交
300 301 302 303
            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 syntax As SyntaxNode = boundArrayAccess.Syntax
            Dim type As ITypeSymbol = boundArrayAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundArrayAccess.ConstantValueOpt)
H
Heejae Chang 已提交
304
            Return New LazyArrayElementReferenceExpression(arrayReference, indices, syntax, type, constantValue)
H
Heejae Chang 已提交
305
        End Function
H
Heejae Chang 已提交
306

307
        Private Function CreateBoundUnaryOperatorOperation(boundUnaryOperator As BoundUnaryOperator) As IUnaryOperatorExpression
H
Heejae Chang 已提交
308
            Dim unaryOperationKind As UnaryOperationKind = Helper.DeriveUnaryOperationKind(boundUnaryOperator.OperatorKind, boundUnaryOperator.Operand)
H
Heejae Chang 已提交
309
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUnaryOperator.Operand))
H
Heejae Chang 已提交
310 311 312 313 314
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim syntax As SyntaxNode = boundUnaryOperator.Syntax
            Dim type As ITypeSymbol = boundUnaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUnaryOperator.ConstantValueOpt)
H
Heejae Chang 已提交
315
            Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
316
        End Function
H
Heejae Chang 已提交
317

318
        Private Function CreateBoundUserDefinedUnaryOperatorOperation(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As IUnaryOperatorExpression
H
Heejae Chang 已提交
319 320 321 322 323 324 325 326 327 328 329 330 331
            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 syntax As SyntaxNode = boundUserDefinedUnaryOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedUnaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedUnaryOperator.ConstantValueOpt)
H
Heejae Chang 已提交
332
            Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
333
        End Function
H
Heejae Chang 已提交
334

335
        Private Function CreateBoundBinaryOperatorOperation(boundBinaryOperator As BoundBinaryOperator) As IBinaryOperatorExpression
H
Heejae Chang 已提交
336
            Dim binaryOperationKind As BinaryOperationKind = Helper.DeriveBinaryOperationKind(boundBinaryOperator.OperatorKind, boundBinaryOperator.Left)
H
Heejae Chang 已提交
337 338
            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 已提交
339 340 341 342 343
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim syntax As SyntaxNode = boundBinaryOperator.Syntax
            Dim type As ITypeSymbol = boundBinaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBinaryOperator.ConstantValueOpt)
H
Heejae Chang 已提交
344
            Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
345
        End Function
H
Heejae Chang 已提交
346

347
        Private Function CreateBoundUserDefinedBinaryOperatorOperation(boundUserDefinedBinaryOperator As BoundUserDefinedBinaryOperator) As IBinaryOperatorExpression
H
Heejae Chang 已提交
348
            Dim binaryOperationKind As BinaryOperationKind = Helper.DeriveBinaryOperationKind(boundUserDefinedBinaryOperator.OperatorKind)
H
Heejae Chang 已提交
349 350
            Dim leftOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetUserDefinedBinaryOperatorChild(boundUserDefinedBinaryOperator, 0))
            Dim rightOperand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetUserDefinedBinaryOperatorChild(boundUserDefinedBinaryOperator, 1))
H
Heejae Chang 已提交
351 352 353 354 355
            Dim operatorMethod As IMethodSymbol = If(boundUserDefinedBinaryOperator.UnderlyingExpression.Kind = BoundKind.Call, boundUserDefinedBinaryOperator.Call.Method, Nothing)
            Dim usesOperatorMethod As Boolean = operatorMethod IsNot Nothing
            Dim syntax As SyntaxNode = boundUserDefinedBinaryOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedBinaryOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedBinaryOperator.ConstantValueOpt)
H
Heejae Chang 已提交
356
            Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
357
        End Function
H
Heejae Chang 已提交
358

359
        Private Function CreateBoundBinaryConditionalExpressionOperation(boundBinaryConditionalExpression As BoundBinaryConditionalExpression) As INullCoalescingExpression
H
Heejae Chang 已提交
360 361
            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 已提交
362 363 364
            Dim syntax As SyntaxNode = boundBinaryConditionalExpression.Syntax
            Dim type As ITypeSymbol = boundBinaryConditionalExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBinaryConditionalExpression.ConstantValueOpt)
H
Heejae Chang 已提交
365
            Return New LazyNullCoalescingExpression(primaryOperand, secondaryOperand, syntax, type, constantValue)
H
Heejae Chang 已提交
366
        End Function
H
Heejae Chang 已提交
367

368
        Private Function CreateBoundUserDefinedShortCircuitingOperatorOperation(boundUserDefinedShortCircuitingOperator As BoundUserDefinedShortCircuitingOperator) As IBinaryOperatorExpression
H
Heejae Chang 已提交
369
            Dim binaryOperationKind As BinaryOperationKind = If((boundUserDefinedShortCircuitingOperator.BitwiseOperator.OperatorKind And BinaryOperatorKind.And) <> 0, BinaryOperationKind.OperatorMethodConditionalAnd, BinaryOperationKind.OperatorMethodConditionalOr)
H
Heejae Chang 已提交
370 371
            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 已提交
372 373 374 375 376
            Dim usesOperatorMethod As Boolean = True
            Dim operatorMethod As IMethodSymbol = boundUserDefinedShortCircuitingOperator.BitwiseOperator.Call.Method
            Dim syntax As SyntaxNode = boundUserDefinedShortCircuitingOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedShortCircuitingOperator.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedShortCircuitingOperator.ConstantValueOpt)
H
Heejae Chang 已提交
377
            Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
378
        End Function
H
Heejae Chang 已提交
379

380
        Private Function CreateBoundBadExpressionOperation(boundBadExpression As BoundBadExpression) As IInvalidExpression
H
Heejae Chang 已提交
381
            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 已提交
382 383 384
            Dim syntax As SyntaxNode = boundBadExpression.Syntax
            Dim type As ITypeSymbol = boundBadExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBadExpression.ConstantValueOpt)
H
Heejae Chang 已提交
385
            Return New LazyInvalidExpression(children, syntax, type, constantValue)
H
Heejae Chang 已提交
386
        End Function
H
Heejae Chang 已提交
387

388
        Private Function CreateBoundTryCastOperation(boundTryCast As BoundTryCast) As IConversionExpression
H
Heejae Chang 已提交
389
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTryCast.Operand))
H
Heejae Chang 已提交
390 391 392 393 394 395 396
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.TryCast
            Dim isExplicit As Boolean = True
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim syntax As SyntaxNode = boundTryCast.Syntax
            Dim type As ITypeSymbol = boundTryCast.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTryCast.ConstantValueOpt)
H
Heejae Chang 已提交
397
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
398
        End Function
H
Heejae Chang 已提交
399

400
        Private Function CreateBoundDirectCastOperation(boundDirectCast As BoundDirectCast) As IConversionExpression
H
Heejae Chang 已提交
401
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDirectCast.Operand))
H
Heejae Chang 已提交
402 403 404 405 406 407 408
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.Cast
            Dim isExplicit As Boolean = True
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim syntax As SyntaxNode = boundDirectCast.Syntax
            Dim type As ITypeSymbol = boundDirectCast.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundDirectCast.ConstantValueOpt)
H
Heejae Chang 已提交
409
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
410
        End Function
H
Heejae Chang 已提交
411

412
        Private Function CreateBoundConversionOperation(boundConversion As BoundConversion) As IConversionExpression
H
Heejae Chang 已提交
413
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundConversion.Operand))
H
Heejae Chang 已提交
414 415 416 417 418 419 420
            Dim conversionKind As ConversionKind = Semantics.ConversionKind.Basic
            Dim isExplicit As Boolean = boundConversion.ExplicitCastInCode
            Dim usesOperatorMethod As Boolean = False
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim syntax As SyntaxNode = boundConversion.Syntax
            Dim type As ITypeSymbol = boundConversion.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundConversion.ConstantValueOpt)
H
Heejae Chang 已提交
421
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
422
        End Function
H
Heejae Chang 已提交
423

424
        Private Function CreateBoundUserDefinedConversionOperation(boundUserDefinedConversion As BoundUserDefinedConversion) As IConversionExpression
H
Heejae Chang 已提交
425
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUserDefinedConversion.Operand))
H
Heejae Chang 已提交
426 427 428 429 430 431 432
            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 syntax As SyntaxNode = boundUserDefinedConversion.Syntax
            Dim type As ITypeSymbol = boundUserDefinedConversion.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedConversion.ConstantValueOpt)
H
Heejae Chang 已提交
433
            Return New LazyConversionExpression(operand, conversionKind, isExplicit, usesOperatorMethod, operatorMethod, syntax, type, constantValue)
H
Heejae Chang 已提交
434
        End Function
H
Heejae Chang 已提交
435

436
        Private Function CreateBoundTernaryConditionalExpressionOperation(boundTernaryConditionalExpression As BoundTernaryConditionalExpression) As IConditionalChoiceExpression
H
Heejae Chang 已提交
437 438 439
            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 已提交
440 441 442
            Dim syntax As SyntaxNode = boundTernaryConditionalExpression.Syntax
            Dim type As ITypeSymbol = boundTernaryConditionalExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTernaryConditionalExpression.ConstantValueOpt)
H
Heejae Chang 已提交
443
            Return New LazyConditionalChoiceExpression(condition, ifTrueValue, ifFalseValue, syntax, type, constantValue)
H
Heejae Chang 已提交
444
        End Function
H
Heejae Chang 已提交
445

446
        Private Function CreateBoundTypeOfOperation(boundTypeOf As BoundTypeOf) As IIsTypeExpression
H
Heejae Chang 已提交
447
            Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundTypeOf.Operand))
H
Heejae Chang 已提交
448 449 450 451
            Dim isType As ITypeSymbol = boundTypeOf.TargetType
            Dim syntax As SyntaxNode = boundTypeOf.Syntax
            Dim type As ITypeSymbol = boundTypeOf.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundTypeOf.ConstantValueOpt)
H
Heejae Chang 已提交
452
            Return New LazyIsTypeExpression(operand, isType, syntax, type, constantValue)
H
Heejae Chang 已提交
453
        End Function
H
Heejae Chang 已提交
454

455
        Private Function CreateBoundObjectCreationExpressionOperation(boundObjectCreationExpression As BoundObjectCreationExpression) As IObjectCreationExpression
H
Heejae Chang 已提交
456
            Dim constructor As IMethodSymbol = boundObjectCreationExpression.ConstructorOpt
H
Heejae Chang 已提交
457
            Dim memberInitializers As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
H
Heejae Chang 已提交
458
                Function()
H
Heejae Chang 已提交
459
                    Return GetObjectCreationInitializers(boundObjectCreationExpression)
H
Heejae Chang 已提交
460 461 462 463 464 465 466 467 468 469 470 471 472
                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 syntax As SyntaxNode = boundObjectCreationExpression.Syntax
            Dim type As ITypeSymbol = boundObjectCreationExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundObjectCreationExpression.ConstantValueOpt)
H
Heejae Chang 已提交
473
            Return New LazyObjectCreationExpression(constructor, memberInitializers, argumentsInEvaluationOrder, syntax, type, constantValue)
H
Heejae Chang 已提交
474
        End Function
H
Heejae Chang 已提交
475

476
        Private Function CreateBoundNewTOperation(boundNewT As BoundNewT) As ITypeParameterObjectCreationExpression
H
Heejae Chang 已提交
477 478 479
            Dim syntax As SyntaxNode = boundNewT.Syntax
            Dim type As ITypeSymbol = boundNewT.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundNewT.ConstantValueOpt)
H
Heejae Chang 已提交
480
            Return New TypeParameterObjectCreationExpression(syntax, type, constantValue)
H
Heejae Chang 已提交
481
        End Function
H
Heejae Chang 已提交
482

483
        Private Function CreateBoundArrayCreationOperation(boundArrayCreation As BoundArrayCreation) As IArrayCreationExpression
484
            Dim elementType As ITypeSymbol = TryCast(boundArrayCreation.Type, IArrayTypeSymbol)?.ElementType
H
Heejae Chang 已提交
485
            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 已提交
486 487 488 489
            Dim initializer As Lazy(Of IArrayInitializer) = New Lazy(Of IArrayInitializer)(Function() DirectCast(Create(boundArrayCreation.InitializerOpt), IArrayInitializer))
            Dim syntax As SyntaxNode = boundArrayCreation.Syntax
            Dim type As ITypeSymbol = boundArrayCreation.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundArrayCreation.ConstantValueOpt)
H
Heejae Chang 已提交
490
            Return New LazyArrayCreationExpression(elementType, dimensionSizes, initializer, syntax, type, constantValue)
H
Heejae Chang 已提交
491
        End Function
H
Heejae Chang 已提交
492

493
        Private Function CreateBoundArrayInitializationOperation(boundArrayInitialization As BoundArrayInitialization) As IArrayInitializer
H
Heejae Chang 已提交
494
            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 已提交
495 496 497
            Dim syntax As SyntaxNode = boundArrayInitialization.Syntax
            Dim type As ITypeSymbol = boundArrayInitialization.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundArrayInitialization.ConstantValueOpt)
H
Heejae Chang 已提交
498
            Return New LazyArrayInitializer(elementValues, syntax, type, constantValue)
H
Heejae Chang 已提交
499
        End Function
H
Heejae Chang 已提交
500

501
        Private Function CreateBoundPropertyAccessOperation(boundPropertyAccess As BoundPropertyAccess) As IPropertyReferenceExpression
H
Heejae Chang 已提交
502 503 504 505 506 507 508 509 510 511 512
            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
513 514 515 516 517 518
            Dim argumentsInEvaluationOrder As Lazy(Of ImmutableArray(Of IArgument)) = New Lazy(Of ImmutableArray(Of IArgument))(
                Function()
                    Return If(boundPropertyAccess.Arguments.Length = 0,
                        ImmutableArray(Of IArgument).Empty,
                        DeriveArguments(boundPropertyAccess.Arguments, boundPropertyAccess.PropertySymbol.Parameters))
                End Function)
H
Heejae Chang 已提交
519 520 521
            Dim syntax As SyntaxNode = boundPropertyAccess.Syntax
            Dim type As ITypeSymbol = boundPropertyAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundPropertyAccess.ConstantValueOpt)
H
Heejae Chang 已提交
522
            Return New LazyPropertyReferenceExpression([property], instance, member, argumentsInEvaluationOrder, syntax, type, constantValue)
H
Heejae Chang 已提交
523
        End Function
H
Heejae Chang 已提交
524

525
        Private Function CreateBoundEventAccessOperation(boundEventAccess As BoundEventAccess) As IEventReferenceExpression
H
Heejae Chang 已提交
526 527 528 529 530 531 532 533 534 535 536 537 538 539
            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 syntax As SyntaxNode = boundEventAccess.Syntax
            Dim type As ITypeSymbol = boundEventAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundEventAccess.ConstantValueOpt)
H
Heejae Chang 已提交
540
            Return New LazyEventReferenceExpression([event], instance, member, syntax, type, constantValue)
H
Heejae Chang 已提交
541
        End Function
H
Heejae Chang 已提交
542

543
        Private Function CreateBoundFieldAccessOperation(boundFieldAccess As BoundFieldAccess) As IFieldReferenceExpression
H
Heejae Chang 已提交
544 545 546 547 548 549
            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 已提交
550
                        Return Create(boundFieldAccess.ReceiverOpt)
H
Heejae Chang 已提交
551 552 553 554 555 556 557
                    End If
                End Function)

            Dim member As ISymbol = boundFieldAccess.FieldSymbol
            Dim syntax As SyntaxNode = boundFieldAccess.Syntax
            Dim type As ITypeSymbol = boundFieldAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundFieldAccess.ConstantValueOpt)
H
Heejae Chang 已提交
558
            Return New LazyFieldReferenceExpression(field, instance, member, syntax, type, constantValue)
H
Heejae Chang 已提交
559
        End Function
H
Heejae Chang 已提交
560

561
        Private Function CreateBoundConditionalAccessOperation(boundConditionalAccess As BoundConditionalAccess) As IConditionalAccessExpression
H
Heejae Chang 已提交
562 563
            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 已提交
564 565 566
            Dim syntax As SyntaxNode = boundConditionalAccess.Syntax
            Dim type As ITypeSymbol = boundConditionalAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundConditionalAccess.ConstantValueOpt)
H
Heejae Chang 已提交
567
            Return New LazyConditionalAccessExpression(conditionalValue, conditionalInstance, syntax, type, constantValue)
H
Heejae Chang 已提交
568
        End Function
H
Heejae Chang 已提交
569

570
        Private Function CreateBoundConditionalAccessReceiverPlaceholderOperation(boundConditionalAccessReceiverPlaceholder As BoundConditionalAccessReceiverPlaceholder) As IConditionalAccessInstanceExpression
H
Heejae Chang 已提交
571 572 573
            Dim syntax As SyntaxNode = boundConditionalAccessReceiverPlaceholder.Syntax
            Dim type As ITypeSymbol = boundConditionalAccessReceiverPlaceholder.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundConditionalAccessReceiverPlaceholder.ConstantValueOpt)
H
Heejae Chang 已提交
574
            Return New ConditionalAccessInstanceExpression(syntax, type, constantValue)
H
Heejae Chang 已提交
575
        End Function
H
Heejae Chang 已提交
576

577
        Private Function CreateBoundParameterOperation(boundParameter As BoundParameter) As IParameterReferenceExpression
H
Heejae Chang 已提交
578 579 580 581
            Dim parameter As IParameterSymbol = boundParameter.ParameterSymbol
            Dim syntax As SyntaxNode = boundParameter.Syntax
            Dim type As ITypeSymbol = boundParameter.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundParameter.ConstantValueOpt)
H
Heejae Chang 已提交
582
            Return New ParameterReferenceExpression(parameter, syntax, type, constantValue)
H
Heejae Chang 已提交
583
        End Function
H
Heejae Chang 已提交
584

585
        Private Function CreateBoundLocalOperation(boundLocal As BoundLocal) As ILocalReferenceExpression
H
Heejae Chang 已提交
586 587 588 589
            Dim local As ILocalSymbol = boundLocal.LocalSymbol
            Dim syntax As SyntaxNode = boundLocal.Syntax
            Dim type As ITypeSymbol = boundLocal.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLocal.ConstantValueOpt)
H
Heejae Chang 已提交
590
            Return New LocalReferenceExpression(local, syntax, type, constantValue)
H
Heejae Chang 已提交
591
        End Function
H
Heejae Chang 已提交
592

593
        Private Function CreateBoundLateMemberAccessOperation(boundLateMemberAccess As BoundLateMemberAccess) As ILateBoundMemberReferenceExpression
H
Heejae Chang 已提交
594
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundLateMemberAccess.ReceiverOpt))
H
Heejae Chang 已提交
595 596 597 598
            Dim memberName As String = boundLateMemberAccess.NameOpt
            Dim syntax As SyntaxNode = boundLateMemberAccess.Syntax
            Dim type As ITypeSymbol = boundLateMemberAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundLateMemberAccess.ConstantValueOpt)
H
Heejae Chang 已提交
599
            Return New LazyLateBoundMemberReferenceExpression(instance, memberName, syntax, type, constantValue)
H
Heejae Chang 已提交
600
        End Function
H
Heejae Chang 已提交
601

602
        Private Function CreateBoundFieldInitializerOperation(boundFieldInitializer As BoundFieldInitializer) As IFieldInitializer
H
Heejae Chang 已提交
603
            Dim initializedFields As ImmutableArray(Of IFieldSymbol) = ImmutableArray(Of IFieldSymbol).CastUp(boundFieldInitializer.InitializedFields)
H
Heejae Chang 已提交
604
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundFieldInitializer.InitialValue))
H
Heejae Chang 已提交
605 606 607 608
            Dim kind As OperationKind = OperationKind.FieldInitializerAtDeclaration
            Dim syntax As SyntaxNode = boundFieldInitializer.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
609
            Return New LazyFieldInitializer(initializedFields, value, kind, syntax, type, constantValue)
H
Heejae Chang 已提交
610
        End Function
H
Heejae Chang 已提交
611

612
        Private Function CreateBoundPropertyInitializerOperation(boundPropertyInitializer As BoundPropertyInitializer) As IPropertyInitializer
H
Heejae Chang 已提交
613
            Dim initializedProperty As IPropertySymbol = boundPropertyInitializer.InitializedProperties.FirstOrDefault()
H
Heejae Chang 已提交
614
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundPropertyInitializer.InitialValue))
H
Heejae Chang 已提交
615 616 617 618
            Dim kind As OperationKind = OperationKind.PropertyInitializerAtDeclaration
            Dim syntax As SyntaxNode = boundPropertyInitializer.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
619
            Return New LazyPropertyInitializer(initializedProperty, value, kind, syntax, type, constantValue)
H
Heejae Chang 已提交
620
        End Function
H
Heejae Chang 已提交
621

622
        Private Function CreateBoundParameterEqualsValueOperation(boundParameterEqualsValue As BoundParameterEqualsValue) As IParameterInitializer
H
Heejae Chang 已提交
623
            Dim parameter As IParameterSymbol = boundParameterEqualsValue.Parameter
H
Heejae Chang 已提交
624
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundParameterEqualsValue.Value))
H
Heejae Chang 已提交
625 626 627 628
            Dim kind As OperationKind = OperationKind.ParameterInitializerAtDeclaration
            Dim syntax As SyntaxNode = boundParameterEqualsValue.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
629
            Return New LazyParameterInitializer(parameter, value, kind, syntax, type, constantValue)
H
Heejae Chang 已提交
630
        End Function
H
Heejae Chang 已提交
631

632
        Private Function CreateBoundRValuePlaceholderOperation(boundRValuePlaceholder As BoundRValuePlaceholder) As IPlaceholderExpression
H
Heejae Chang 已提交
633 634 635
            Dim syntax As SyntaxNode = boundRValuePlaceholder.Syntax
            Dim type As ITypeSymbol = boundRValuePlaceholder.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundRValuePlaceholder.ConstantValueOpt)
H
Heejae Chang 已提交
636
            Return New PlaceholderExpression(syntax, type, constantValue)
H
Heejae Chang 已提交
637
        End Function
H
Heejae Chang 已提交
638

639
        Private Function CreateBoundIfStatementOperation(boundIfStatement As BoundIfStatement) As IIfStatement
H
Heejae Chang 已提交
640 641 642
            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 已提交
643 644 645
            Dim syntax As SyntaxNode = boundIfStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
646
            Return New LazyIfStatement(condition, ifTrueStatement, ifFalseStatement, syntax, type, constantValue)
H
Heejae Chang 已提交
647
        End Function
H
Heejae Chang 已提交
648

649
        Private Function CreateBoundSelectStatementOperation(boundSelectStatement As BoundSelectStatement) As ISwitchStatement
H
Heejae Chang 已提交
650
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundSelectStatement.ExpressionStatement.Expression))
H
Heejae Chang 已提交
651 652 653 654
            Dim cases As Lazy(Of ImmutableArray(Of ISwitchCase)) = New Lazy(Of ImmutableArray(Of ISwitchCase))(Function() GetSwitchStatementCases(boundSelectStatement))
            Dim syntax As SyntaxNode = boundSelectStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
655
            Return New LazySwitchStatement(value, cases, syntax, type, constantValue)
H
Heejae Chang 已提交
656
        End Function
H
Heejae Chang 已提交
657

658
        Private Function CreateBoundSimpleCaseClauseOperation(boundSimpleCaseClause As BoundSimpleCaseClause) As ISingleValueCaseClause
H
Heejae Chang 已提交
659 660 661 662 663 664
            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 syntax As SyntaxNode = boundSimpleCaseClause.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
665
            Return New LazySingleValueCaseClause(value, equality, caseKind, syntax, type, constantValue)
H
Heejae Chang 已提交
666
        End Function
H
Heejae Chang 已提交
667

668
        Private Function CreateBoundRangeCaseClauseOperation(boundRangeCaseClause As BoundRangeCaseClause) As IRangeCaseClause
H
Heejae Chang 已提交
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
            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 syntax As SyntaxNode = boundRangeCaseClause.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
703
            Return New LazyRangeCaseClause(minimumValue, maximumValue, caseKind, syntax, type, constantValue)
H
Heejae Chang 已提交
704
        End Function
H
Heejae Chang 已提交
705

706
        Private Function CreateBoundRelationalCaseClauseOperation(boundRelationalCaseClause As BoundRelationalCaseClause) As IRelationalCaseClause
H
Heejae Chang 已提交
707 708
            Dim valueExpression = GetRelationalCaseClauseValue(boundRelationalCaseClause)
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(valueExpression))
H
Heejae Chang 已提交
709
            Dim relation As BinaryOperationKind = If(valueExpression IsNot Nothing, Helper.DeriveBinaryOperationKind(boundRelationalCaseClause.OperatorKind, valueExpression), BinaryOperationKind.Invalid)
H
Heejae Chang 已提交
710 711 712 713
            Dim caseKind As CaseKind = CaseKind.Relational
            Dim syntax As SyntaxNode = boundRelationalCaseClause.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
714
            Return New LazyRelationalCaseClause(value, relation, caseKind, syntax, type, constantValue)
H
Heejae Chang 已提交
715
        End Function
H
Heejae Chang 已提交
716

717
        Private Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IWhileUntilLoopStatement
H
Heejae Chang 已提交
718 719
            Dim isTopTest As Boolean = boundDoLoopStatement.ConditionIsTop
            Dim isWhile As Boolean = Not boundDoLoopStatement.ConditionIsUntil
H
Heejae Chang 已提交
720
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.ConditionOpt))
H
Heejae Chang 已提交
721
            Dim loopKind As LoopKind = LoopKind.WhileUntil
H
Heejae Chang 已提交
722
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.Body))
H
Heejae Chang 已提交
723 724 725
            Dim syntax As SyntaxNode = boundDoLoopStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
726
            Return New LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, loopKind, body, syntax, type, constantValue)
H
Heejae Chang 已提交
727
        End Function
H
Heejae Chang 已提交
728

729
        Private Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForLoopStatement
H
Heejae Chang 已提交
730 731
            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 已提交
732
            Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
H
Heejae Chang 已提交
733
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetForWhileUntilLoopStatmentCondition(boundForToStatement))
H
Heejae Chang 已提交
734
            Dim loopKind As LoopKind = LoopKind.For
H
Heejae Chang 已提交
735
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.Body))
H
Heejae Chang 已提交
736 737 738
            Dim syntax As SyntaxNode = boundForToStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
739
            Return New LazyForLoopStatement(before, atLoopBottom, locals, condition, loopKind, body, syntax, type, constantValue)
H
Heejae Chang 已提交
740
        End Function
H
Heejae Chang 已提交
741

742
        Private Function CreateBoundForEachStatementOperation(boundForEachStatement As BoundForEachStatement) As IForEachLoopStatement
H
Heejae Chang 已提交
743
            Dim iterationVariable As ILocalSymbol = Nothing ' Manual
H
Heejae Chang 已提交
744
            Dim collection As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Collection))
H
Heejae Chang 已提交
745
            Dim loopKind As LoopKind = LoopKind.ForEach
H
Heejae Chang 已提交
746
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Body))
H
Heejae Chang 已提交
747 748 749
            Dim syntax As SyntaxNode = boundForEachStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
750
            Return New LazyForEachLoopStatement(iterationVariable, collection, loopKind, body, syntax, type, constantValue)
H
Heejae Chang 已提交
751
        End Function
H
Heejae Chang 已提交
752

753
        Private Function CreateBoundTryStatementOperation(boundTryStatement As BoundTryStatement) As ITryStatement
H
Heejae Chang 已提交
754 755 756 757 758 759
            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 syntax As SyntaxNode = boundTryStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
760
            Return New LazyTryStatement(body, catches, finallyHandler, syntax, type, constantValue)
H
Heejae Chang 已提交
761
        End Function
H
Heejae Chang 已提交
762

763
        Private Function CreateBoundCatchBlockOperation(boundCatchBlock As BoundCatchBlock) As ICatchClause
H
Heejae Chang 已提交
764 765
            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 已提交
766
            Dim filter As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundCatchBlock.ExceptionFilterOpt))
H
Heejae Chang 已提交
767 768 769 770
            Dim exceptionLocal As ILocalSymbol = boundCatchBlock.LocalOpt
            Dim syntax As SyntaxNode = boundCatchBlock.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
771
            Return New LazyCatchClause(handler, caughtType, filter, exceptionLocal, syntax, type, constantValue)
H
Heejae Chang 已提交
772
        End Function
H
Heejae Chang 已提交
773

774
        Private Function CreateBoundBlockOperation(boundBlock As BoundBlock) As IBlockStatement
775 776 777 778
            Dim statements As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
                Function()
                    Return boundBlock.Statements.Select(Function(n) Create(n)).Where(Function(s) s.Kind <> OperationKind.None).ToImmutableArray()
                End Function)
H
Heejae Chang 已提交
779 780 781 782
            Dim locals As ImmutableArray(Of ILocalSymbol) = boundBlock.Locals.As(Of ILocalSymbol)()
            Dim syntax As SyntaxNode = boundBlock.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
783
            Return New LazyBlockStatement(statements, locals, syntax, type, constantValue)
H
Heejae Chang 已提交
784
        End Function
H
Heejae Chang 已提交
785

786
        Private Function CreateBoundBadStatementOperation(boundBadStatement As BoundBadStatement) As IInvalidStatement
H
Heejae Chang 已提交
787 788 789 790 791 792 793 794 795 796 797 798
            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 已提交
799 800 801
            Dim syntax As SyntaxNode = boundBadStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
802
            Return New LazyInvalidStatement(children, syntax, type, constantValue)
H
Heejae Chang 已提交
803
        End Function
H
Heejae Chang 已提交
804

805
        Private Function CreateBoundReturnStatementOperation(boundReturnStatement As BoundReturnStatement) As IReturnStatement
H
Heejae Chang 已提交
806
            Dim returnedValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundReturnStatement.ExpressionOpt))
H
Heejae Chang 已提交
807 808 809
            Dim syntax As SyntaxNode = boundReturnStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
810
            Return New LazyReturnStatement(OperationKind.ReturnStatement, returnedValue, syntax, type, constantValue)
H
Heejae Chang 已提交
811
        End Function
H
Heejae Chang 已提交
812

813
        Private Function CreateBoundThrowStatementOperation(boundThrowStatement As BoundThrowStatement) As IThrowStatement
H
Heejae Chang 已提交
814
            Dim thrownObject As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundThrowStatement.ExpressionOpt))
H
Heejae Chang 已提交
815 816 817
            Dim syntax As SyntaxNode = boundThrowStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
818
            Return New LazyThrowStatement(thrownObject, syntax, type, constantValue)
H
Heejae Chang 已提交
819
        End Function
H
Heejae Chang 已提交
820

821
        Private Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileUntilLoopStatement
H
Heejae Chang 已提交
822 823
            Dim isTopTest As Boolean = True
            Dim isWhile As Boolean = True
H
Heejae Chang 已提交
824
            Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Condition))
H
Heejae Chang 已提交
825
            Dim loopKind As LoopKind = LoopKind.WhileUntil
H
Heejae Chang 已提交
826
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Body))
H
Heejae Chang 已提交
827 828 829
            Dim syntax As SyntaxNode = boundWhileStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
830
            Return New LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, loopKind, body, syntax, type, constantValue)
H
Heejae Chang 已提交
831
        End Function
H
Heejae Chang 已提交
832

833
        Private Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationStatement
H
Heejae Chang 已提交
834
            Dim declarations As Lazy(Of ImmutableArray(Of IVariableDeclaration)) = New Lazy(Of ImmutableArray(Of IVariableDeclaration))(Function() GetVariableDeclarationStatementVariables(boundDimStatement))
H
Heejae Chang 已提交
835 836 837
            Dim syntax As SyntaxNode = boundDimStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
838
            Return New LazyVariableDeclarationStatement(declarations, syntax, type, constantValue)
H
Heejae Chang 已提交
839
        End Function
H
Heejae Chang 已提交
840

841
        Private Function CreateBoundYieldStatementOperation(boundYieldStatement As BoundYieldStatement) As IReturnStatement
H
Heejae Chang 已提交
842
            Dim returnedValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundYieldStatement.Expression))
H
Heejae Chang 已提交
843 844 845
            Dim syntax As SyntaxNode = boundYieldStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
846
            Return New LazyReturnStatement(OperationKind.YieldReturnStatement, returnedValue, syntax, type, constantValue)
H
Heejae Chang 已提交
847
        End Function
H
Heejae Chang 已提交
848

849
        Private Function CreateBoundLabelStatementOperation(boundLabelStatement As BoundLabelStatement) As ILabelStatement
H
Heejae Chang 已提交
850
            Dim label As ILabelSymbol = boundLabelStatement.Label
H
Heejae Chang 已提交
851
            Dim labeledStatement As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(Nothing))
H
Heejae Chang 已提交
852 853 854
            Dim syntax As SyntaxNode = boundLabelStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
855
            Return New LazyLabelStatement(label, labeledStatement, syntax, type, constantValue)
H
Heejae Chang 已提交
856
        End Function
H
Heejae Chang 已提交
857

858
        Private Function CreateBoundGotoStatementOperation(boundGotoStatement As BoundGotoStatement) As IBranchStatement
H
Heejae Chang 已提交
859 860 861 862 863
            Dim target As ILabelSymbol = boundGotoStatement.Label
            Dim branchKind As BranchKind = BranchKind.GoTo
            Dim syntax As SyntaxNode = boundGotoStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
864
            Return New BranchStatement(target, branchKind, syntax, type, constantValue)
H
Heejae Chang 已提交
865
        End Function
H
Heejae Chang 已提交
866

867
        Private Function CreateBoundContinueStatementOperation(boundContinueStatement As BoundContinueStatement) As IBranchStatement
H
Heejae Chang 已提交
868 869 870 871 872
            Dim target As ILabelSymbol = boundContinueStatement.Label
            Dim branchKind As BranchKind = BranchKind.Continue
            Dim syntax As SyntaxNode = boundContinueStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
873
            Return New BranchStatement(target, branchKind, syntax, type, constantValue)
H
Heejae Chang 已提交
874
        End Function
H
Heejae Chang 已提交
875

876
        Private Function CreateBoundExitStatementOperation(boundExitStatement As BoundExitStatement) As IBranchStatement
H
Heejae Chang 已提交
877 878 879 880 881
            Dim target As ILabelSymbol = boundExitStatement.Label
            Dim branchKind As BranchKind = BranchKind.Break
            Dim syntax As SyntaxNode = boundExitStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
882
            Return New BranchStatement(target, branchKind, syntax, type, constantValue)
H
Heejae Chang 已提交
883
        End Function
H
Heejae Chang 已提交
884

885
        Private Function CreateBoundSyncLockStatementOperation(boundSyncLockStatement As BoundSyncLockStatement) As ILockStatement
H
Heejae Chang 已提交
886 887
            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 已提交
888 889 890
            Dim syntax As SyntaxNode = boundSyncLockStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
891
            Return New LazyLockStatement(lockedObject, body, syntax, type, constantValue)
H
Heejae Chang 已提交
892
        End Function
H
Heejae Chang 已提交
893

894
        Private Function CreateBoundNoOpStatementOperation(boundNoOpStatement As BoundNoOpStatement) As IEmptyStatement
H
Heejae Chang 已提交
895 896 897
            Dim syntax As SyntaxNode = boundNoOpStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
898
            Return New EmptyStatement(syntax, type, constantValue)
H
Heejae Chang 已提交
899
        End Function
H
Heejae Chang 已提交
900

901
        Private Function CreateBoundStopStatementOperation(boundStopStatement As BoundStopStatement) As IStopStatement
H
Heejae Chang 已提交
902 903 904
            Dim syntax As SyntaxNode = boundStopStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
905
            Return New StopStatement(syntax, type, constantValue)
H
Heejae Chang 已提交
906
        End Function
H
Heejae Chang 已提交
907

908
        Private Function CreateBoundEndStatementOperation(boundEndStatement As BoundEndStatement) As IEndStatement
H
Heejae Chang 已提交
909 910 911
            Dim syntax As SyntaxNode = boundEndStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
912
            Return New EndStatement(syntax, type, constantValue)
H
Heejae Chang 已提交
913
        End Function
H
Heejae Chang 已提交
914

915
        Private Function CreateBoundWithStatementOperation(boundWithStatement As BoundWithStatement) As IWithStatement
H
Heejae Chang 已提交
916 917
            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 已提交
918 919 920
            Dim syntax As SyntaxNode = boundWithStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
921
            Return New LazyWithStatement(body, value, syntax, type, constantValue)
H
Heejae Chang 已提交
922
        End Function
H
Heejae Chang 已提交
923

924
        Private Function CreateBoundUsingStatementOperation(boundUsingStatement As BoundUsingStatement) As IUsingStatement
H
Heejae Chang 已提交
925
            Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUsingStatement.Body))
H
Heejae Chang 已提交
926
            Dim declaration As Lazy(Of IVariableDeclarationStatement) = New Lazy(Of IVariableDeclarationStatement)(Function() GetUsingStatementDeclaration(boundUsingStatement))
H
Heejae Chang 已提交
927
            Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundUsingStatement.ResourceExpressionOpt))
H
Heejae Chang 已提交
928 929 930
            Dim syntax As SyntaxNode = boundUsingStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
931
            Return New LazyUsingStatement(body, declaration, value, syntax, type, constantValue)
H
Heejae Chang 已提交
932
        End Function
H
Heejae Chang 已提交
933

934
        Private Function CreateBoundExpressionStatementOperation(boundExpressionStatement As BoundExpressionStatement) As IExpressionStatement
H
Heejae Chang 已提交
935
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundExpressionStatement.Expression))
H
Heejae Chang 已提交
936 937 938
            Dim syntax As SyntaxNode = boundExpressionStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
939
            Return New LazyExpressionStatement(expression, syntax, type, constantValue)
H
Heejae Chang 已提交
940
        End Function
H
Heejae Chang 已提交
941

942
        Private Function CreateBoundRaiseEventStatementOperation(boundRaiseEventStatement As BoundRaiseEventStatement) As IExpressionStatement
H
Heejae Chang 已提交
943
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundRaiseEventStatement.EventInvocation))
H
Heejae Chang 已提交
944 945 946
            Dim syntax As SyntaxNode = boundRaiseEventStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
947
            Return New LazyExpressionStatement(expression, syntax, type, constantValue)
H
Heejae Chang 已提交
948
        End Function
H
Heejae Chang 已提交
949

950
        Private Function CreateBoundAddHandlerStatementOperation(boundAddHandlerStatement As BoundAddHandlerStatement) As IExpressionStatement
H
Heejae Chang 已提交
951
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetAddHandlerStatementExpression(boundAddHandlerStatement))
H
Heejae Chang 已提交
952 953 954
            Dim syntax As SyntaxNode = boundAddHandlerStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
955
            Return New LazyExpressionStatement(expression, syntax, type, constantValue)
H
Heejae Chang 已提交
956
        End Function
H
Heejae Chang 已提交
957

958
        Private Function CreateBoundRemoveHandlerStatementOperation(boundRemoveHandlerStatement As BoundRemoveHandlerStatement) As IExpressionStatement
H
Heejae Chang 已提交
959
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() GetRemoveStatementExpression(boundRemoveHandlerStatement))
H
Heejae Chang 已提交
960 961 962
            Dim syntax As SyntaxNode = boundRemoveHandlerStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
H
Heejae Chang 已提交
963
            Return New LazyExpressionStatement(expression, syntax, type, constantValue)
H
Heejae Chang 已提交
964
        End Function
965

966
        Private Function CreateBoundInterpolatedStringExpressionOperation(boundInterpolatedString As BoundInterpolatedStringExpression) As IInterpolatedStringExpression
967 968 969 970 971
            Dim parts As New Lazy(Of ImmutableArray(Of IInterpolatedStringContent))(
                Function()
                    Return boundInterpolatedString.Contents.SelectAsArray(Function(interpolatedStringContent) CreateBoundInterpolatedStringContentOperation(interpolatedStringContent))
                End Function)

972 973 974
            Dim syntax As SyntaxNode = boundInterpolatedString.Syntax
            Dim type As ITypeSymbol = boundInterpolatedString.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundInterpolatedString.ConstantValueOpt)
H
Heejae Chang 已提交
975
            Return New LazyInterpolatedStringExpression(parts, syntax, type, constantValue)
976 977
        End Function

978
        Private Function CreateBoundInterpolatedStringContentOperation(boundNode As BoundNode) As IInterpolatedStringContent
M
Manish Vasani 已提交
979
            If boundNode.Kind = BoundKind.Interpolation Then
M
Manish Vasani 已提交
980
                Return DirectCast(Create(boundNode), IInterpolatedStringContent)
M
Manish Vasani 已提交
981 982
            Else
                Return CreateBoundInterpolatedStringTextOperation(boundNode)
983 984 985
            End If
        End Function

986
        Private Function CreateBoundInterpolationOperation(boundInterpolation As BoundInterpolation) As IInterpolation
987 988 989 990 991 992
            Dim expression As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundInterpolation.Expression))
            Dim alignment As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundInterpolation.AlignmentOpt))
            Dim format As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundInterpolation.FormatStringOpt))
            Dim syntax As SyntaxNode = boundInterpolation.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = Nothing
H
Heejae Chang 已提交
993
            Return New LazyInterpolation(expression, alignment, format, syntax, type, constantValue)
994 995
        End Function

996
        Private Function CreateBoundInterpolatedStringTextOperation(boundNode As BoundNode) As IInterpolatedStringText
M
Manish Vasani 已提交
997 998
            Dim text As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundNode))
            Dim syntax As SyntaxNode = boundNode.Syntax
999 1000
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As [Optional](Of Object) = Nothing
H
Heejae Chang 已提交
1001
            Return New LazyInterpolatedStringText(text, syntax, type, constantValue)
1002
        End Function
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012

        Private Function CreateBoundAnonymousTypeCreationExpressionOperation(boundAnonymousTypeCreationExpression As BoundAnonymousTypeCreationExpression) As IAnonymousObjectCreationExpression
            Dim initializers As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
                Function()
                    Return GetAnonymousTypeCreationInitializers(boundAnonymousTypeCreationExpression)
                End Function)

            Dim syntax As SyntaxNode = boundAnonymousTypeCreationExpression.Syntax
            Dim type As ITypeSymbol = boundAnonymousTypeCreationExpression.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAnonymousTypeCreationExpression.ConstantValueOpt)
H
Heejae Chang 已提交
1013
            Return New LazyAnonymousObjectCreationExpression(initializers, syntax, type, constantValue)
1014 1015 1016 1017 1018 1019
        End Function

        Private Function CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess As BoundAnonymousTypePropertyAccess) As IPropertyReferenceExpression
            Dim instance As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Nothing)
            Dim [property] As IPropertySymbol = DirectCast(boundAnonymousTypePropertyAccess.ExpressionSymbol, IPropertySymbol)
            Dim member As ISymbol = boundAnonymousTypePropertyAccess.ExpressionSymbol
M
Manish Vasani 已提交
1020
            Dim argumentsInEvaluationOrder As Lazy(Of ImmutableArray(Of IArgument)) = New Lazy(Of ImmutableArray(Of IArgument))(Function() ImmutableArray(Of IArgument).Empty)
1021 1022 1023
            Dim syntax As SyntaxNode = boundAnonymousTypePropertyAccess.Syntax
            Dim type As ITypeSymbol = boundAnonymousTypePropertyAccess.Type
            Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAnonymousTypePropertyAccess.ConstantValueOpt)
H
Heejae Chang 已提交
1024
            Return New LazyPropertyReferenceExpression([property], instance, member, argumentsInEvaluationOrder, syntax, type, constantValue)
1025
        End Function
H
Heejae Chang 已提交
1026 1027 1028 1029
    End Class
End Namespace