/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb
1 703 строки
121 KB
Tomáš Matoušek
ReferenceEqualityComparer (#78350)
28 апр 2025, 21:25
Не верифицирован
28 апр 2025, 21:25
0ec9acf
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports System.Collections.Concurrent Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.Operations Partial Friend NotInheritable Class VisualBasicOperationFactory Private _lazyPlaceholderToParentMap As ConcurrentDictionary(Of BoundValuePlaceholderBase, BoundNode) = Nothing Private ReadOnly _semanticModel As SemanticModel Public Sub New(semanticModel As SemanticModel) _semanticModel = semanticModel End Sub ''' <summary> ''' Returns <code>Nothing</code> if parent is not known. ''' </summary> Private Function TryGetParent(placeholder As BoundValuePlaceholderBase) As BoundNode Dim knownParent As BoundNode = Nothing If _lazyPlaceholderToParentMap IsNot Nothing AndAlso _lazyPlaceholderToParentMap.TryGetValue(placeholder, knownParent) Then Return knownParent End If Return Nothing End Function Private Sub RecordParent(placeholderOpt As BoundValuePlaceholderBase, parent As BoundNode) Debug.Assert(parent IsNot Nothing) If placeholderOpt Is Nothing Then Return End If If _lazyPlaceholderToParentMap Is Nothing Then Interlocked.CompareExchange(_lazyPlaceholderToParentMap, New ConcurrentDictionary(Of BoundValuePlaceholderBase, BoundNode)(concurrencyLevel:=2, capacity:=10, comparer:=ReferenceEqualityComparer.Instance), Nothing) End If Dim knownParent = _lazyPlaceholderToParentMap.GetOrAdd(placeholderOpt, parent) Debug.Assert(knownParent Is parent) End Sub Public Function Create(boundNode As BoundNode) As IOperation If boundNode Is Nothing Then Return Nothing End If ' A BoundUserDefined conversion is always the operand of a BoundConversion, and is handled ' by the BoundConversion creation. We should never receive one in this top level create call. Debug.Assert(boundNode.Kind <> BoundKind.UserDefinedConversion) 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.NameOfOperator Return CreateBoundNameOfOperatorOperation(DirectCast(boundNode, BoundNameOfOperator)) 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.DelegateCreationExpression Return CreateBoundDelegateCreationExpressionOperation(DirectCast(boundNode, BoundDelegateCreationExpression)) Case BoundKind.TernaryConditionalExpression Return CreateBoundTernaryConditionalExpressionOperation(DirectCast(boundNode, BoundTernaryConditionalExpression)) Case BoundKind.TypeOf Return CreateBoundTypeOfOperation(DirectCast(boundNode, BoundTypeOf)) Case BoundKind.GetType Return CreateBoundGetTypeOperation(DirectCast(boundNode, BoundGetType)) Case BoundKind.ObjectCreationExpression Return CreateBoundObjectCreationExpressionOperation(DirectCast(boundNode, BoundObjectCreationExpression)) Case BoundKind.ObjectInitializerExpression Return CreateBoundObjectInitializerExpressionOperation(DirectCast(boundNode, BoundObjectInitializerExpression)) Case BoundKind.CollectionInitializerExpression Return CreateBoundCollectionInitializerExpressionOperation(DirectCast(boundNode, BoundCollectionInitializerExpression)) Case BoundKind.NewT Return CreateBoundNewTOperation(DirectCast(boundNode, BoundNewT)) Case BoundKind.NoPiaObjectCreationExpression Return CreateNoPiaObjectCreationExpressionOperation(DirectCast(boundNode, BoundNoPiaObjectCreationExpression)) 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.LocalDeclaration Return CreateBoundLocalDeclarationOperation(DirectCast(boundNode, BoundLocalDeclaration)) Case BoundKind.LateInvocation Return CreateBoundLateInvocationOperation(DirectCast(boundNode, BoundLateInvocation)) 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.CaseBlock Return CreateBoundCaseBlockOperation(DirectCast(boundNode, BoundCaseBlock)) 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 BoundKind.TupleLiteral Return CreateBoundTupleLiteralOperation(DirectCast(boundNode, BoundTupleLiteral)) Case BoundKind.ConvertedTupleLiteral Return CreateBoundConvertedTupleLiteralOperation(DirectCast(boundNode, BoundConvertedTupleLiteral)) Case BoundKind.InterpolatedStringExpression Return CreateBoundInterpolatedStringExpressionOperation(DirectCast(boundNode, BoundInterpolatedStringExpression)) Case BoundKind.Interpolation Return CreateBoundInterpolationOperation(DirectCast(boundNode, BoundInterpolation)) 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)) Case BoundKind.WithLValueExpressionPlaceholder Return CreateBoundWithLValueExpressionPlaceholder(DirectCast(boundNode, BoundWithLValueExpressionPlaceholder)) Case BoundKind.WithRValueExpressionPlaceholder Return CreateBoundWithRValueExpressionPlaceholder(DirectCast(boundNode, BoundWithRValueExpressionPlaceholder)) Case BoundKind.QueryExpression Return CreateBoundQueryExpressionOperation(DirectCast(boundNode, BoundQueryExpression)) Case BoundKind.LValueToRValueWrapper Return CreateBoundLValueToRValueWrapper(DirectCast(boundNode, BoundLValueToRValueWrapper)) Case BoundKind.QueryClause ' Query clause has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundQueryClause).UnderlyingExpression) Case BoundKind.QueryableSource ' Queryable source has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundQueryableSource).Source) Case BoundKind.AggregateClause Return CreateBoundAggregateClauseOperation(DirectCast(boundNode, BoundAggregateClause)) Case BoundKind.Ordering ' Ordering clause has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundOrdering).UnderlyingExpression) Case BoundKind.GroupAggregation ' Group aggregation has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundGroupAggregation).Group) Case BoundKind.QuerySource ' Query source has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundQuerySource).Expression) Case BoundKind.ToQueryableCollectionConversion ' Queryable collection conversion has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundToQueryableCollectionConversion).ConversionCall) Case BoundKind.QueryLambda ' Query lambda must be lowered to the regular lambda form for the operation tree. Dim rewrittenLambda As BoundNode = RewriteQueryLambda(DirectCast(boundNode, BoundQueryLambda)) Return Create(rewrittenLambda) Case BoundKind.RangeVariableAssignment ' Range variable assignment has no special representation in the IOperation tree Return Create(DirectCast(boundNode, BoundRangeVariableAssignment).Value) Case BoundKind.BadVariable Return Create(DirectCast(boundNode, BoundBadVariable).Expression) Case BoundKind.NullableIsTrueOperator Return CreateBoundNullableIsTrueOperator(DirectCast(boundNode, BoundNullableIsTrueOperator)) Case BoundKind.RedimStatement Return CreateBoundReDimOperation(DirectCast(boundNode, BoundRedimStatement)) Case BoundKind.RedimClause Return CreateBoundReDimClauseOperation(DirectCast(boundNode, BoundRedimClause)) Case BoundKind.TypeArguments Return CreateBoundTypeArgumentsOperation(DirectCast(boundNode, BoundTypeArguments)) Case BoundKind.Attribute Return CreateBoundAttributeOperation(DirectCast(boundNode, BoundAttribute)) Case BoundKind.AddressOfOperator, BoundKind.ArrayLiteral, BoundKind.ByRefArgumentWithCopyBack, BoundKind.CompoundAssignmentTargetPlaceholder, BoundKind.EraseStatement, BoundKind.Label, BoundKind.LateAddressOfOperator, BoundKind.MethodGroup, BoundKind.MidResult, BoundKind.NamespaceExpression, BoundKind.OnErrorStatement, BoundKind.PropertyGroup, BoundKind.RangeVariable, BoundKind.ResumeStatement, BoundKind.TypeAsValueExpression, BoundKind.TypeExpression, BoundKind.TypeOrValueExpression, BoundKind.XmlCData, BoundKind.XmlComment, BoundKind.XmlDocument, BoundKind.XmlElement, BoundKind.XmlEmbeddedExpression, BoundKind.XmlMemberAccess, BoundKind.XmlNamespace, BoundKind.XmlProcessingInstruction, BoundKind.UnboundLambda, BoundKind.UnstructuredExceptionHandlingStatement Dim constantValue As ConstantValue = Nothing Dim type As TypeSymbol = Nothing Dim expression = TryCast(boundNode, BoundExpression) If expression IsNot Nothing Then constantValue = expression.ConstantValueOpt type = expression.Type End If Dim isImplicit As Boolean = boundNode.WasCompilerGenerated Dim children As ImmutableArray(Of IOperation) = GetIOperationChildren(boundNode) Return New NoneOperation(children, _semanticModel, boundNode.Syntax, type, constantValue, isImplicit) Case Else ' If you're hitting this because the IOperation test hook has failed, see ' <roslyn-root>/docs/Compilers/IOperation Test Hook.md for instructions on how to fix. Throw ExceptionUtilities.UnexpectedValue(boundNode.Kind) End Select End Function Public Function CreateFromArray(Of TBoundNode As BoundNode, TOperation As {Class, IOperation})(nodeArray As ImmutableArray(Of TBoundNode)) As ImmutableArray(Of TOperation) Dim builder = ArrayBuilder(Of TOperation).GetInstance(nodeArray.Length) For Each node In nodeArray builder.AddIfNotNull(DirectCast(Create(node), TOperation)) Next Return builder.ToImmutableAndFree() End Function Friend Function GetIOperationChildren(boundNode As BoundNode) As ImmutableArray(Of IOperation) 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) If operation Is Nothing Then Continue For End If builder.Add(operation) Next Return builder.ToImmutableAndFree() End Function Private Function CreateBoundAssignmentOperatorOperation(boundAssignmentOperator As BoundAssignmentOperator) As IOperation If IsMidStatement(boundAssignmentOperator.Right) Then ' We don't support mid statements currently. Return a none operation for them ' https://github.com/dotnet/roslyn/issues/23109 Dim constantValue As ConstantValue = boundAssignmentOperator.ConstantValueOpt Dim isImplicit As Boolean = boundAssignmentOperator.WasCompilerGenerated Dim children As ImmutableArray(Of IOperation) = GetIOperationChildren(boundAssignmentOperator) Return New NoneOperation(children, _semanticModel, boundAssignmentOperator.Syntax, type:=Nothing, constantValue, isImplicit) ElseIf boundAssignmentOperator.LeftOnTheRightOpt IsNot Nothing Then Return CreateCompoundAssignment(boundAssignmentOperator) Else Dim target As IOperation = Create(boundAssignmentOperator.Left) Dim value As IOperation = Create(boundAssignmentOperator.Right) Dim isImplicit As Boolean = boundAssignmentOperator.WasCompilerGenerated Dim isRef As Boolean = False Dim syntax As SyntaxNode = boundAssignmentOperator.Syntax Dim type As ITypeSymbol = boundAssignmentOperator.Type Dim constantValue As ConstantValue = boundAssignmentOperator.ConstantValueOpt Return New SimpleAssignmentOperation(isRef, target, value, _semanticModel, syntax, type, constantValue, isImplicit) End If End Function Private Function CreateBoundMeReferenceOperation(boundMeReference As BoundMeReference) As IInstanceReferenceOperation Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ContainingTypeInstance Dim syntax As SyntaxNode = boundMeReference.Syntax Dim type As ITypeSymbol = boundMeReference.Type Dim isImplicit As Boolean = boundMeReference.WasCompilerGenerated Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundMyBaseReferenceOperation(boundMyBaseReference As BoundMyBaseReference) As IInstanceReferenceOperation Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ContainingTypeInstance Dim syntax As SyntaxNode = boundMyBaseReference.Syntax Dim type As ITypeSymbol = boundMyBaseReference.Type Dim isImplicit As Boolean = boundMyBaseReference.WasCompilerGenerated Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundMyClassReferenceOperation(boundMyClassReference As BoundMyClassReference) As IInstanceReferenceOperation Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ContainingTypeInstance Dim syntax As SyntaxNode = boundMyClassReference.Syntax Dim type As ITypeSymbol = boundMyClassReference.Type Dim isImplicit As Boolean = boundMyClassReference.WasCompilerGenerated Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit) End Function Friend Function CreateBoundLiteralOperation(boundLiteral As BoundLiteral, Optional implicit As Boolean = False) As ILiteralOperation Dim syntax As SyntaxNode = boundLiteral.Syntax Dim type As ITypeSymbol = boundLiteral.Type Dim constantValue As ConstantValue = boundLiteral.ConstantValueOpt Dim isImplicit As Boolean = boundLiteral.WasCompilerGenerated OrElse implicit Return New LiteralOperation(_semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundAwaitOperatorOperation(boundAwaitOperator As BoundAwaitOperator) As IAwaitOperation Dim awaitedValue As IOperation = Create(boundAwaitOperator.Operand) Dim syntax As SyntaxNode = boundAwaitOperator.Syntax Dim type As ITypeSymbol = boundAwaitOperator.Type Dim isImplicit As Boolean = boundAwaitOperator.WasCompilerGenerated Return New AwaitOperation(awaitedValue, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundNameOfOperatorOperation(boundNameOfOperator As BoundNameOfOperator) As INameOfOperation Dim argument As IOperation = Create(boundNameOfOperator.Argument) Dim syntax As SyntaxNode = boundNameOfOperator.Syntax Dim type As ITypeSymbol = boundNameOfOperator.Type Dim constantValue As ConstantValue = boundNameOfOperator.ConstantValueOpt Dim isImplicit As Boolean = boundNameOfOperator.WasCompilerGenerated Return New NameOfOperation(argument, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundLambdaOperation(boundLambda As BoundLambda) As IAnonymousFunctionOperation Dim symbol As IMethodSymbol = boundLambda.LambdaSymbol Dim body As IBlockOperation = DirectCast(Create(boundLambda.Body), IBlockOperation) Dim syntax As SyntaxNode = boundLambda.Syntax Dim isImplicit As Boolean = boundLambda.WasCompilerGenerated Return New AnonymousFunctionOperation(symbol, body, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundCallOperation(boundCall As BoundCall) As IInvocationOperation Dim targetMethod As IMethodSymbol = boundCall.Method Dim isVirtual As Boolean = targetMethod IsNot Nothing AndAlso (targetMethod.IsVirtual OrElse targetMethod.IsAbstract OrElse targetMethod.IsOverride) AndAlso If(boundCall.ReceiverOpt?.Kind <> BoundKind.MyBaseReference, False) AndAlso If(boundCall.ReceiverOpt?.Kind <> BoundKind.MyClassReference, False) Dim boundReceiver As BoundExpression = If(boundCall.ReceiverOpt, boundCall.MethodGroupOpt?.ReceiverOpt) Dim receiver As IOperation = CreateReceiverOperation(boundReceiver, targetMethod) Dim arguments As ImmutableArray(Of IArgumentOperation) = DeriveArguments(boundCall) Dim syntax As SyntaxNode = boundCall.Syntax Dim type As ITypeSymbol = boundCall.Type Dim isImplicit As Boolean = boundCall.WasCompilerGenerated Return New InvocationOperation(targetMethod, constrainedToType:=Nothing, receiver, isVirtual, arguments, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundOmittedArgumentOperation(boundOmittedArgument As BoundOmittedArgument) As IOmittedArgumentOperation Dim syntax As SyntaxNode = boundOmittedArgument.Syntax Dim type As ITypeSymbol = boundOmittedArgument.Type Dim isImplicit As Boolean = boundOmittedArgument.WasCompilerGenerated Return New OmittedArgumentOperation(_semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundParenthesizedOperation(boundParenthesized As BoundParenthesized) As IParenthesizedOperation Dim operand As IOperation = Create(boundParenthesized.Expression) Dim syntax As SyntaxNode = boundParenthesized.Syntax Dim type As ITypeSymbol = boundParenthesized.Type Dim constantValue As ConstantValue = boundParenthesized.ConstantValueOpt Dim isImplicit As Boolean = boundParenthesized.WasCompilerGenerated Return New ParenthesizedOperation(operand, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundArrayAccessOperation(boundArrayAccess As BoundArrayAccess) As IArrayElementReferenceOperation Dim arrayReference As IOperation = Create(boundArrayAccess.Expression) Dim indices = CreateFromArray(Of BoundExpression, IOperation)(boundArrayAccess.Indices) Dim syntax As SyntaxNode = boundArrayAccess.Syntax Dim type As ITypeSymbol = boundArrayAccess.Type Dim isImplicit As Boolean = boundArrayAccess.WasCompilerGenerated Return New ArrayElementReferenceOperation(arrayReference, indices, _semanticModel, syntax, type, isImplicit) End Function Friend Function CreateBoundUnaryOperatorChild(boundOperator As BoundExpression) As IOperation Select Case boundOperator.Kind Case BoundKind.UnaryOperator Return Create(DirectCast(boundOperator, BoundUnaryOperator).Operand) Case BoundKind.UserDefinedUnaryOperator Dim userDefined = DirectCast(boundOperator, BoundUserDefinedUnaryOperator) If userDefined.UnderlyingExpression.Kind = BoundKind.Call Then Return Create(userDefined.Operand) Else Return GetChildOfBadExpression(userDefined.UnderlyingExpression, 0) End If Case Else Throw ExceptionUtilities.UnexpectedValue(boundOperator.Kind) End Select End Function Private Function CreateBoundUnaryOperatorOperation(boundUnaryOperator As BoundUnaryOperator) As IUnaryOperation Dim operand As IOperation = CreateBoundUnaryOperatorChild(boundUnaryOperator) Dim operatorKind As UnaryOperatorKind = Helper.DeriveUnaryOperatorKind(boundUnaryOperator.OperatorKind) Dim operatorMethod As IMethodSymbol = Nothing Dim syntax As SyntaxNode = boundUnaryOperator.Syntax Dim type As ITypeSymbol = boundUnaryOperator.Type Dim constantValue As ConstantValue = boundUnaryOperator.ConstantValueOpt Dim isLifted As Boolean = (boundUnaryOperator.OperatorKind And VisualBasic.UnaryOperatorKind.Lifted) <> 0 Dim isChecked As Boolean = boundUnaryOperator.Checked Dim isImplicit As Boolean = boundUnaryOperator.WasCompilerGenerated Return New UnaryOperation(operatorKind, operand, isLifted, isChecked, operatorMethod, constrainedToType:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundUserDefinedUnaryOperatorOperation(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As IUnaryOperation Dim operand As IOperation = CreateBoundUnaryOperatorChild(boundUserDefinedUnaryOperator) Dim operatorKind As UnaryOperatorKind = Helper.DeriveUnaryOperatorKind(boundUserDefinedUnaryOperator.OperatorKind) Dim operatorMethod As IMethodSymbol = TryGetOperatorMethod(boundUserDefinedUnaryOperator) Dim syntax As SyntaxNode = boundUserDefinedUnaryOperator.Syntax Dim type As ITypeSymbol = boundUserDefinedUnaryOperator.Type Dim constantValue As ConstantValue = boundUserDefinedUnaryOperator.ConstantValueOpt Dim isLifted As Boolean = (boundUserDefinedUnaryOperator.OperatorKind And VisualBasic.UnaryOperatorKind.Lifted) <> 0 Dim isChecked As Boolean = False Dim isImplicit As Boolean = boundUserDefinedUnaryOperator.WasCompilerGenerated Return New UnaryOperation(operatorKind, operand, isLifted, isChecked, operatorMethod, constrainedToType:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Shared Function TryGetOperatorMethod(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As MethodSymbol Return If(boundUserDefinedUnaryOperator.UnderlyingExpression.Kind = BoundKind.Call, boundUserDefinedUnaryOperator.Call.Method, Nothing) End Function Friend Function CreateBoundBinaryOperatorChild(binaryOperator As BoundExpression, isLeft As Boolean) As IOperation Select Case binaryOperator.Kind Case BoundKind.UserDefinedBinaryOperator Dim boundUserDefined = DirectCast(binaryOperator, BoundUserDefinedBinaryOperator) Dim binaryOperatorInfo As BinaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(boundUserDefined) Return GetUserDefinedBinaryOperatorChild(boundUserDefined, If(isLeft, binaryOperatorInfo.LeftOperand, binaryOperatorInfo.RightOperand)) Case BoundKind.UserDefinedShortCircuitingOperator Dim boundShortCircuiting = DirectCast(binaryOperator, BoundUserDefinedShortCircuitingOperator) Dim binaryOperatorInfo As BinaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(boundShortCircuiting.BitwiseOperator) If isLeft Then Return If(boundShortCircuiting.LeftOperand IsNot Nothing, Create(boundShortCircuiting.LeftOperand), ' Possibly dropping conversions https://github.com/dotnet/roslyn/issues/23236 GetUserDefinedBinaryOperatorChild(boundShortCircuiting.BitwiseOperator, binaryOperatorInfo.LeftOperand)) Else Return GetUserDefinedBinaryOperatorChild(boundShortCircuiting.BitwiseOperator, binaryOperatorInfo.RightOperand) End If Case Else Throw ExceptionUtilities.UnexpectedValue(binaryOperator.Kind) End Select End Function Private Function CreateBoundBinaryOperatorOperation(boundBinaryOperator As BoundBinaryOperator) As IOperation ' Binary operators can be nested _many_ levels deep, and cause a stack overflow if we manually recurse. ' To solve this, we use a manual stack for the left side. Dim stack As ArrayBuilder(Of BoundBinaryOperator) = ArrayBuilder(Of BoundBinaryOperator).GetInstance() Dim currentBinary As BoundBinaryOperator = boundBinaryOperator Do stack.Push(currentBinary) currentBinary = TryCast(currentBinary.Left, BoundBinaryOperator) Loop While currentBinary IsNot Nothing Debug.Assert(stack.Count > 0) Dim left As IOperation = Nothing While stack.TryPop(currentBinary) left = If(left, Create(currentBinary.Left)) Dim right As IOperation = Create(currentBinary.Right) Dim binaryOperatorInfo = GetBinaryOperatorInfo(currentBinary) Dim syntax As SyntaxNode = currentBinary.Syntax Dim type As ITypeSymbol = currentBinary.Type Dim constantValue As ConstantValue = currentBinary.ConstantValueOpt Dim isImplicit As Boolean = currentBinary.WasCompilerGenerated left = New BinaryOperation(binaryOperatorInfo.OperatorKind, left, right, binaryOperatorInfo.IsLifted, binaryOperatorInfo.IsChecked, binaryOperatorInfo.IsCompareText, binaryOperatorInfo.OperatorMethod, constrainedToType:=Nothing, unaryOperatorMethod:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit) End While Debug.Assert(left IsNot Nothing AndAlso stack.Count = 0) stack.Free() Return left End Function Private Function CreateBoundUserDefinedBinaryOperatorOperation(boundUserDefinedBinaryOperator As BoundUserDefinedBinaryOperator) As IBinaryOperation Dim left As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedBinaryOperator, isLeft:=True) Dim right As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedBinaryOperator, isLeft:=False) Dim binaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(boundUserDefinedBinaryOperator) Dim syntax As SyntaxNode = boundUserDefinedBinaryOperator.Syntax Dim type As ITypeSymbol = boundUserDefinedBinaryOperator.Type Dim constantValue As ConstantValue = boundUserDefinedBinaryOperator.ConstantValueOpt Dim isImplicit As Boolean = boundUserDefinedBinaryOperator.WasCompilerGenerated Return New BinaryOperation(binaryOperatorInfo.OperatorKind, left, right, binaryOperatorInfo.IsLifted, binaryOperatorInfo.IsChecked, binaryOperatorInfo.IsCompareText, binaryOperatorInfo.OperatorMethod, constrainedToType:=Nothing, unaryOperatorMethod:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundBinaryConditionalExpressionOperation(boundBinaryConditionalExpression As BoundBinaryConditionalExpression) As ICoalesceOperation Dim value As IOperation = Create(boundBinaryConditionalExpression.TestExpression) Dim whenFalse As IOperation = Create(boundBinaryConditionalExpression.ElseExpression) Dim syntax As SyntaxNode = boundBinaryConditionalExpression.Syntax Dim type As ITypeSymbol = boundBinaryConditionalExpression.Type Dim constantValue As ConstantValue = boundBinaryConditionalExpression.ConstantValueOpt Dim isImplicit As Boolean = boundBinaryConditionalExpression.WasCompilerGenerated Dim valueConversion = New Conversion(Conversions.Identity) If Not TypeSymbol.Equals(boundBinaryConditionalExpression.Type, boundBinaryConditionalExpression.TestExpression.Type, TypeCompareKind.ConsiderEverything) Then Dim convertedTestExpression As BoundExpression = boundBinaryConditionalExpression.ConvertedTestExpression If convertedTestExpression IsNot Nothing Then If convertedTestExpression.Kind = BoundKind.Conversion Then valueConversion = CreateConversion(convertedTestExpression) Else Debug.Assert(convertedTestExpression.Kind = BoundKind.BadExpression) valueConversion = New Conversion() End If End If End If Return New CoalesceOperation(value, whenFalse, valueConversion, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundUserDefinedShortCircuitingOperatorOperation(boundUserDefinedShortCircuitingOperator As BoundUserDefinedShortCircuitingOperator) As IBinaryOperation Dim left As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedShortCircuitingOperator, isLeft:=True) Dim right As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedShortCircuitingOperator, isLeft:=False) Dim bitwiseOperator As BoundUserDefinedBinaryOperator = boundUserDefinedShortCircuitingOperator.BitwiseOperator Dim binaryOperatorInfo As BinaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(bitwiseOperator) Dim operatorKind As BinaryOperatorKind = If(binaryOperatorInfo.OperatorKind = BinaryOperatorKind.And, BinaryOperatorKind.ConditionalAnd, BinaryOperatorKind.ConditionalOr) Dim syntax As SyntaxNode = boundUserDefinedShortCircuitingOperator.Syntax Dim type As ITypeSymbol = boundUserDefinedShortCircuitingOperator.Type Dim constantValue As ConstantValue = boundUserDefinedShortCircuitingOperator.ConstantValueOpt Dim isChecked As Boolean = False Dim isCompareText As Boolean = False Dim isImplicit As Boolean = boundUserDefinedShortCircuitingOperator.WasCompilerGenerated Dim unaryOperatorMethod As IMethodSymbol = Nothing Dim leftTest As BoundExpression = boundUserDefinedShortCircuitingOperator.LeftTest If leftTest IsNot Nothing Then unaryOperatorMethod = TryGetOperatorMethod(DirectCast(If(leftTest.Kind = BoundKind.UserDefinedUnaryOperator, leftTest, DirectCast(leftTest, BoundNullableIsTrueOperator).Operand), BoundUserDefinedUnaryOperator)) End If Return New BinaryOperation(operatorKind, left, right, binaryOperatorInfo.IsLifted, isChecked, isCompareText, binaryOperatorInfo.OperatorMethod, constrainedToType:=Nothing, unaryOperatorMethod, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundBadExpressionOperation(boundBadExpression As BoundBadExpression) As IInvalidOperation Dim syntax As SyntaxNode = boundBadExpression.Syntax ' We match semantic model here: If the Then expression IsMissing, we have a null type, rather than the ErrorType Of the bound node. Dim type As ITypeSymbol = If(syntax.IsMissing, Nothing, boundBadExpression.Type) Dim constantValue As ConstantValue = boundBadExpression.ConstantValueOpt ' if child has syntax node point to same syntax node as bad expression, then this invalid expression Is implicit Dim isImplicit = boundBadExpression.WasCompilerGenerated OrElse boundBadExpression.ChildBoundNodes.Any(Function(e) e?.Syntax Is boundBadExpression.Syntax) Dim children = CreateFromArray(Of BoundExpression, IOperation)(boundBadExpression.ChildBoundNodes) Return New InvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundTypeArgumentsOperation(boundTypeArguments As BoundTypeArguments) As IInvalidOperation ' This can occur in scenarios involving latebound member accesses in Strict mode, such as ' element.UnresolvedMember(Of String) ' The BadExpression has 2 children in this case: the receiver, and the type arguments. ' Just create an invalid operation to represent the node, as it won't ever be surfaced in good code. Dim syntax As SyntaxNode = boundTypeArguments.Syntax ' Match GetTypeInfo behavior for the syntax Dim type As ITypeSymbol = Nothing Dim constantValue As ConstantValue = boundTypeArguments.ConstantValueOpt Dim isImplicit As Boolean = boundTypeArguments.WasCompilerGenerated Dim children As ImmutableArray(Of IOperation) = ImmutableArray(Of IOperation).Empty Return New InvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundAttributeOperation(boundAttribute As BoundAttribute) As IAttributeOperation Dim isAttributeImplicit = boundAttribute.WasCompilerGenerated If boundAttribute.Constructor Is Nothing OrElse boundAttribute.ConstructorArguments.Length <> boundAttribute.Constructor.ParameterCount Then Dim invalidOperation = OperationFactory.CreateInvalidOperation(_semanticModel, boundAttribute.Syntax, GetIOperationChildren(boundAttribute), isImplicit:=True) Return New AttributeOperation(invalidOperation, _semanticModel, boundAttribute.Syntax, isAttributeImplicit) End If Dim initializer As ObjectOrCollectionInitializerOperation = Nothing If Not boundAttribute.NamedArguments.IsEmpty Then Dim namedArguments = CreateFromArray(Of BoundExpression, IOperation)(boundAttribute.NamedArguments) initializer = New ObjectOrCollectionInitializerOperation(namedArguments, _semanticModel, boundAttribute.Syntax, boundAttribute.Type, isImplicit:=True) End If Dim objectCreationOperation = New ObjectCreationOperation(boundAttribute.Constructor, initializer, DeriveArguments(boundAttribute), _semanticModel, boundAttribute.Syntax, boundAttribute.Type, boundAttribute.ConstantValueOpt, isImplicit:=True) Return New AttributeOperation(objectCreationOperation, _semanticModel, boundAttribute.Syntax, isAttributeImplicit) End Function Private Function CreateBoundTryCastOperation(boundTryCast As BoundTryCast) As IOperation Return CreateBoundConversionOrCastOperation(boundTryCast, isTryCast:=True) End Function Private Function CreateBoundDirectCastOperation(boundDirectCast As BoundDirectCast) As IOperation Return CreateBoundConversionOrCastOperation(boundDirectCast, isTryCast:=False) End Function Private Function CreateBoundConversionOperation(boundConversion As BoundConversion) As IOperation Dim syntax As SyntaxNode = boundConversion.Syntax If syntax.IsMissing AndAlso boundConversion.Operand.Kind = BoundKind.BadExpression Then ' If the underlying syntax IsMissing, then that means we're in case where the compiler generated a piece of syntax to fill in for ' an error, such as this case: ' ' Dim i = ' ' Semantic model has a special case here that we match: if the underlying syntax is missing, don't create a conversion expression, ' and instead directly return the operand, which will be a BoundBadExpression. When we generate a node for the BoundBadExpression, ' the resulting IOperation will also have a null Type. Return Create(boundConversion.Operand) End If Return CreateBoundConversionOrCastOperation(boundConversion, isTryCast:=False) End Function Private Function CreateBoundConversionOrCastOperation(boundConversionOrCast As BoundConversionOrCast, isTryCast As Boolean) As IOperation Dim isChecked As Boolean = False Dim type As ITypeSymbol = boundConversionOrCast.Type Dim constantValue As ConstantValue = boundConversionOrCast.ConstantValueOpt Dim syntax As SyntaxNode = boundConversionOrCast.Syntax Dim isImplicit As Boolean = boundConversionOrCast.WasCompilerGenerated OrElse Not boundConversionOrCast.ExplicitCastInCode Dim boundOperand = GetConversionOperand(boundConversionOrCast) If boundOperand.Syntax Is boundConversionOrCast.Syntax Then If boundOperand.Kind = BoundKind.ConvertedTupleLiteral AndAlso TypeSymbol.Equals(boundOperand.Type, boundConversionOrCast.Type, TypeCompareKind.ConsiderEverything) Then ' Erase this conversion, this is an artificial conversion added on top of BoundConvertedTupleLiteral ' in Binder.ReclassifyTupleLiteral Return Create(boundOperand) Else ' Make this conversion implicit isImplicit = True End If End If Dim conversionInfo = GetConversionInfo(boundConversionOrCast) Dim conversion As Conversion = conversionInfo.Conversion If conversionInfo.IsDelegateCreation Then Return New DelegateCreationOperation(conversionInfo.Operation, _semanticModel, syntax, type, isImplicit) Else Return New ConversionOperation(conversionInfo.Operation, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit) End If End Function Private Function CreateBoundDelegateCreationExpressionOperation(boundDelegateCreationExpression As BoundDelegateCreationExpression) As IDelegateCreationOperation Dim target As IOperation = CreateBoundDelegateCreationExpressionChildOperation(boundDelegateCreationExpression) Dim syntax As SyntaxNode = boundDelegateCreationExpression.Syntax Dim type As ITypeSymbol = boundDelegateCreationExpression.Type ' The operand for this is going to be using the same syntax node as this, and since that node can be Explicit, this node cannot be. Dim isImplicit As Boolean = True Return New DelegateCreationOperation(target, _semanticModel, syntax, type, isImplicit) End Function Friend Function CreateBoundDelegateCreationExpressionChildOperation(boundDelegateCreationExpression As BoundDelegateCreationExpression) As IMethodReferenceOperation Dim method As IMethodSymbol = boundDelegateCreationExpression.Method Dim isVirtual As Boolean = method IsNot Nothing AndAlso (method.IsAbstract OrElse method.IsOverride OrElse method.IsVirtual) AndAlso Not boundDelegateCreationExpression.SuppressVirtualCalls Dim receiverOpt As IOperation = CreateReceiverOperation( If(boundDelegateCreationExpression.ReceiverOpt, boundDelegateCreationExpression.MethodGroupOpt?.ReceiverOpt), method) ' The compiler creates a BoundDelegateCreationExpression node for the AddressOf expression, and that's the node we want to use for the operand ' of the IDelegateCreationExpression parent Dim syntax As SyntaxNode = boundDelegateCreationExpression.Syntax Dim type As ITypeSymbol = Nothing Dim isImplicit As Boolean = boundDelegateCreationExpression.WasCompilerGenerated Return New MethodReferenceOperation(method, constrainedToType:=Nothing, isVirtual, receiverOpt, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundTernaryConditionalExpressionOperation(boundTernaryConditionalExpression As BoundTernaryConditionalExpression) As IConditionalOperation Dim condition As IOperation = Create(boundTernaryConditionalExpression.Condition) Dim whenTrue As IOperation = Create(boundTernaryConditionalExpression.WhenTrue) Dim whenFalse As IOperation = Create(boundTernaryConditionalExpression.WhenFalse) Dim syntax As SyntaxNode = boundTernaryConditionalExpression.Syntax Dim type As ITypeSymbol = boundTernaryConditionalExpression.Type Dim constantValue As ConstantValue = boundTernaryConditionalExpression.ConstantValueOpt Dim isImplicit As Boolean = boundTernaryConditionalExpression.WasCompilerGenerated Dim isRef As Boolean = False Return New ConditionalOperation(condition, whenTrue, whenFalse, isRef, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundTypeOfOperation(boundTypeOf As BoundTypeOf) As IIsTypeOperation Dim valueOperand = Create(boundTypeOf.Operand) Dim typeOperand As ITypeSymbol = boundTypeOf.TargetType Dim isNegated As Boolean = boundTypeOf.IsTypeOfIsNotExpression Dim syntax As SyntaxNode = boundTypeOf.Syntax Dim type As ITypeSymbol = boundTypeOf.Type Dim isImplicit As Boolean = boundTypeOf.WasCompilerGenerated Return New IsTypeOperation(valueOperand, typeOperand, isNegated, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundGetTypeOperation(boundGetType As BoundGetType) As ITypeOfOperation Dim typeOperand As ITypeSymbol = boundGetType.SourceType.Type Dim syntax As SyntaxNode = boundGetType.Syntax Dim type As ITypeSymbol = boundGetType.Type Dim isImplicit As Boolean = boundGetType.WasCompilerGenerated Return New TypeOfOperation(typeOperand, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundLateInvocationOperation(boundLateInvocation As BoundLateInvocation) As IOperation Dim operation As IOperation = Create(boundLateInvocation.Member) Dim arguments As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundLateInvocation.ArgumentsOpt) Dim argumentNames As ImmutableArray(Of String) = boundLateInvocation.ArgumentNamesOpt Dim argumentRefKinds As ImmutableArray(Of RefKind) = Nothing Dim syntax As SyntaxNode = boundLateInvocation.Syntax Dim type As ITypeSymbol = boundLateInvocation.Type Dim isImplicit As Boolean = boundLateInvocation.WasCompilerGenerated Return New DynamicInvocationOperation(operation, arguments, argumentNames, argumentRefKinds, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundObjectCreationExpressionOperation(boundObjectCreationExpression As BoundObjectCreationExpression) As IObjectCreationOperation Debug.Assert(boundObjectCreationExpression.ConstructorOpt IsNot Nothing OrElse boundObjectCreationExpression.Arguments.IsEmpty()) Dim constructor As IMethodSymbol = boundObjectCreationExpression.ConstructorOpt Dim initializer As IObjectOrCollectionInitializerOperation = DirectCast(Create(boundObjectCreationExpression.InitializerOpt), IObjectOrCollectionInitializerOperation) Dim arguments As ImmutableArray(Of IArgumentOperation) = DeriveArguments(boundObjectCreationExpression) Dim syntax As SyntaxNode = boundObjectCreationExpression.Syntax Dim type As ITypeSymbol = boundObjectCreationExpression.Type Dim constantValue As ConstantValue = boundObjectCreationExpression.ConstantValueOpt Dim isImplicit As Boolean = boundObjectCreationExpression.WasCompilerGenerated Return New ObjectCreationOperation(constructor, initializer, arguments, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundObjectInitializerExpressionOperation(boundObjectInitializerExpression As BoundObjectInitializerExpression) As IObjectOrCollectionInitializerOperation Dim initializers As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundObjectInitializerExpression.Initializers) Dim syntax As SyntaxNode = boundObjectInitializerExpression.Syntax Dim type As ITypeSymbol = boundObjectInitializerExpression.Type Dim isImplicit As Boolean = boundObjectInitializerExpression.WasCompilerGenerated Return New ObjectOrCollectionInitializerOperation(initializers, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundCollectionInitializerExpressionOperation(boundCollectionInitializerExpression As BoundCollectionInitializerExpression) As IObjectOrCollectionInitializerOperation Dim initializers As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundCollectionInitializerExpression.Initializers) Dim syntax As SyntaxNode = boundCollectionInitializerExpression.Syntax Dim type As ITypeSymbol = boundCollectionInitializerExpression.Type Dim isImplicit As Boolean = boundCollectionInitializerExpression.WasCompilerGenerated Return New ObjectOrCollectionInitializerOperation(initializers, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundNewTOperation(boundNewT As BoundNewT) As ITypeParameterObjectCreationOperation Dim initializer As IObjectOrCollectionInitializerOperation = DirectCast(Create(boundNewT.InitializerOpt), IObjectOrCollectionInitializerOperation) Dim syntax As SyntaxNode = boundNewT.Syntax Dim type As ITypeSymbol = boundNewT.Type Dim isImplicit As Boolean = boundNewT.WasCompilerGenerated Return New TypeParameterObjectCreationOperation(initializer, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateNoPiaObjectCreationExpressionOperation(creation As BoundNoPiaObjectCreationExpression) As INoPiaObjectCreationOperation Dim initializer As IObjectOrCollectionInitializerOperation = DirectCast(Create(creation.InitializerOpt), IObjectOrCollectionInitializerOperation) Dim syntax As SyntaxNode = creation.Syntax Dim type As ITypeSymbol = creation.Type Dim isImplicit As Boolean = creation.WasCompilerGenerated Return New NoPiaObjectCreationOperation(initializer, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundArrayCreationOperation(boundArrayCreation As BoundArrayCreation) As IArrayCreationOperation Dim dimensionSizes As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundArrayCreation.Bounds) Dim initializer As IArrayInitializerOperation = DirectCast(Create(boundArrayCreation.InitializerOpt), IArrayInitializerOperation) Dim syntax As SyntaxNode = boundArrayCreation.Syntax Dim type As ITypeSymbol = boundArrayCreation.Type Dim isImplicit As Boolean = boundArrayCreation.WasCompilerGenerated Return New ArrayCreationOperation(dimensionSizes, initializer, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundArrayInitializationOperation(boundArrayInitialization As BoundArrayInitialization) As IArrayInitializerOperation Dim elementValues As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundArrayInitialization.Initializers) Dim syntax As SyntaxNode = boundArrayInitialization.Syntax Dim isImplicit As Boolean = boundArrayInitialization.WasCompilerGenerated Return New ArrayInitializerOperation(elementValues, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundPropertyAccessOperation(boundPropertyAccess As BoundPropertyAccess) As IPropertyReferenceOperation Dim [property] As IPropertySymbol = boundPropertyAccess.PropertySymbol Dim instance As IOperation = CreateReceiverOperation( If(boundPropertyAccess.ReceiverOpt, boundPropertyAccess.PropertyGroupOpt?.ReceiverOpt), [property]) Dim arguments As ImmutableArray(Of IArgumentOperation) = DeriveArguments(boundPropertyAccess) Dim syntax As SyntaxNode = boundPropertyAccess.Syntax Dim type As ITypeSymbol = boundPropertyAccess.Type Dim isImplicit As Boolean = boundPropertyAccess.WasCompilerGenerated Return New PropertyReferenceOperation([property], constrainedToType:=Nothing, arguments, instance, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundWithLValueExpressionPlaceholder(boundWithLValueExpressionPlaceholder As BoundWithLValueExpressionPlaceholder) As IInstanceReferenceOperation Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ImplicitReceiver Dim syntax As SyntaxNode = boundWithLValueExpressionPlaceholder.Syntax Dim type As ITypeSymbol = boundWithLValueExpressionPlaceholder.Type Dim isImplicit As Boolean = boundWithLValueExpressionPlaceholder.WasCompilerGenerated Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundWithRValueExpressionPlaceholder(boundWithRValueExpressionPlaceholder As BoundWithRValueExpressionPlaceholder) As IInstanceReferenceOperation Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ImplicitReceiver Dim syntax As SyntaxNode = boundWithRValueExpressionPlaceholder.Syntax Dim type As ITypeSymbol = boundWithRValueExpressionPlaceholder.Type Dim isImplicit As Boolean = boundWithRValueExpressionPlaceholder.WasCompilerGenerated Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundEventAccessOperation(boundEventAccess As BoundEventAccess) As IEventReferenceOperation Dim [event] As IEventSymbol = boundEventAccess.EventSymbol Dim instance As IOperation = CreateReceiverOperation(boundEventAccess.ReceiverOpt, [event]) Dim syntax As SyntaxNode = boundEventAccess.Syntax Dim type As ITypeSymbol = boundEventAccess.Type Dim isImplicit As Boolean = boundEventAccess.WasCompilerGenerated Return New EventReferenceOperation([event], constrainedToType:=Nothing, instance, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundFieldAccessOperation(boundFieldAccess As BoundFieldAccess) As IFieldReferenceOperation Dim field As IFieldSymbol = boundFieldAccess.FieldSymbol Dim isDeclaration As Boolean = False Dim instance As IOperation = CreateReceiverOperation(boundFieldAccess.ReceiverOpt, field) Dim syntax As SyntaxNode = boundFieldAccess.Syntax Dim type As ITypeSymbol = boundFieldAccess.Type Dim constantValue As ConstantValue = boundFieldAccess.ConstantValueOpt Dim isImplicit As Boolean = boundFieldAccess.WasCompilerGenerated Return New FieldReferenceOperation(field, isDeclaration, instance, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundConditionalAccessOperation(boundConditionalAccess As BoundConditionalAccess) As IConditionalAccessOperation RecordParent(boundConditionalAccess.Placeholder, boundConditionalAccess) Dim operation As IOperation = Create(boundConditionalAccess.Receiver) Dim whenNotNull As IOperation = Create(boundConditionalAccess.AccessExpression) Dim syntax As SyntaxNode = boundConditionalAccess.Syntax Dim type As ITypeSymbol = boundConditionalAccess.Type Dim isImplicit As Boolean = boundConditionalAccess.WasCompilerGenerated Return New ConditionalAccessOperation(operation, whenNotNull, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundConditionalAccessReceiverPlaceholderOperation(boundConditionalAccessReceiverPlaceholder As BoundConditionalAccessReceiverPlaceholder) As IConditionalAccessInstanceOperation Dim syntax As SyntaxNode = boundConditionalAccessReceiverPlaceholder.Syntax Dim type As ITypeSymbol = boundConditionalAccessReceiverPlaceholder.Type Dim isImplicit As Boolean = boundConditionalAccessReceiverPlaceholder.WasCompilerGenerated Return New ConditionalAccessInstanceOperation(_semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundParameterOperation(boundParameter As BoundParameter) As IParameterReferenceOperation Dim parameter As IParameterSymbol = boundParameter.ParameterSymbol Dim syntax As SyntaxNode = boundParameter.Syntax Dim type As ITypeSymbol = boundParameter.Type Dim isImplicit As Boolean = boundParameter.WasCompilerGenerated Return New ParameterReferenceOperation(parameter, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundLocalOperation(boundLocal As BoundLocal) As IOperation Dim local As ILocalSymbol = boundLocal.LocalSymbol Dim isDeclaration As Boolean = False Dim syntax As SyntaxNode = boundLocal.Syntax Dim type As ITypeSymbol = boundLocal.Type Dim constantValue As ConstantValue = boundLocal.ConstantValueOpt Dim isImplicit As Boolean = boundLocal.WasCompilerGenerated Return New LocalReferenceOperation(local, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundLateMemberAccessOperation(boundLateMemberAccess As BoundLateMemberAccess) As IDynamicMemberReferenceOperation Debug.Assert(boundLateMemberAccess.ReceiverOpt Is Nothing OrElse boundLateMemberAccess.ReceiverOpt.Kind <> BoundKind.TypeExpression) Dim instance As IOperation = Create(boundLateMemberAccess.ReceiverOpt) Dim memberName As String = boundLateMemberAccess.NameOpt Dim typeArguments As ImmutableArray(Of ITypeSymbol) = ImmutableArray(Of ITypeSymbol).Empty If boundLateMemberAccess.TypeArgumentsOpt IsNot Nothing Then typeArguments = ImmutableArray(Of ITypeSymbol).CastUp(boundLateMemberAccess.TypeArgumentsOpt.Arguments) End If Dim containingType As ITypeSymbol = Nothing ' If there's nothing being late-bound against, something is very wrong Debug.Assert(boundLateMemberAccess.ReceiverOpt IsNot Nothing OrElse boundLateMemberAccess.ContainerTypeOpt IsNot Nothing) ' Only set containing type if the container is set to something, and either there is no receiver, or the receiver's type ' does not match the type of the containing type. If (boundLateMemberAccess.ContainerTypeOpt IsNot Nothing AndAlso (boundLateMemberAccess.ReceiverOpt Is Nothing OrElse Not TypeSymbol.Equals(boundLateMemberAccess.ContainerTypeOpt, boundLateMemberAccess.ReceiverOpt.Type, TypeCompareKind.ConsiderEverything))) Then containingType = boundLateMemberAccess.ContainerTypeOpt End If Dim syntax As SyntaxNode = boundLateMemberAccess.Syntax Dim type As ITypeSymbol = boundLateMemberAccess.Type Dim isImplicit As Boolean = boundLateMemberAccess.WasCompilerGenerated Return New DynamicMemberReferenceOperation(instance, memberName, typeArguments, containingType, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundFieldInitializerOperation(boundFieldInitializer As BoundFieldInitializer) As IFieldInitializerOperation Dim initializedFields As ImmutableArray(Of IFieldSymbol) = boundFieldInitializer.InitializedFields.As(Of IFieldSymbol) Dim value As IOperation = Create(boundFieldInitializer.InitialValue) Dim syntax As SyntaxNode = boundFieldInitializer.Syntax Dim isImplicit As Boolean = boundFieldInitializer.WasCompilerGenerated Return New FieldInitializerOperation(initializedFields, ImmutableArray(Of ILocalSymbol).Empty, value, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundPropertyInitializerOperation(boundPropertyInitializer As BoundPropertyInitializer) As IPropertyInitializerOperation Dim initializedProperties As ImmutableArray(Of IPropertySymbol) = boundPropertyInitializer.InitializedProperties.As(Of IPropertySymbol) Dim value As IOperation = Create(boundPropertyInitializer.InitialValue) Dim syntax As SyntaxNode = boundPropertyInitializer.Syntax Dim isImplicit As Boolean = boundPropertyInitializer.WasCompilerGenerated Return New PropertyInitializerOperation(initializedProperties, ImmutableArray(Of ILocalSymbol).Empty, value, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundParameterEqualsValueOperation(boundParameterEqualsValue As BoundParameterEqualsValue) As IParameterInitializerOperation Dim parameter As IParameterSymbol = boundParameterEqualsValue.Parameter Dim value As IOperation = Create(boundParameterEqualsValue.Value) Dim syntax As SyntaxNode = boundParameterEqualsValue.Syntax Dim isImplicit As Boolean = boundParameterEqualsValue.WasCompilerGenerated Return New ParameterInitializerOperation(parameter, ImmutableArray(Of ILocalSymbol).Empty, value, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundLValueToRValueWrapper(boundNode As BoundLValueToRValueWrapper) As IOperation ' This is created in cases like collection initializers, where the implicit receiver is wrapped ' by this node. The node itself doesn't have anything interesting we want to expose, so we ' just pass through. Return Create(boundNode.UnderlyingLValue) End Function Private Function CreateBoundRValuePlaceholderOperation(boundRValuePlaceholder As BoundRValuePlaceholder) As IOperation Dim syntax As SyntaxNode = boundRValuePlaceholder.Syntax Dim type As ITypeSymbol = boundRValuePlaceholder.Type Dim isImplicit As Boolean = boundRValuePlaceholder.WasCompilerGenerated Dim knownParent As BoundNode = TryGetParent(boundRValuePlaceholder) Dim placeholderKind As PlaceholderKind = PlaceholderKind.Unspecified If knownParent IsNot Nothing Then Select Case knownParent.Kind Case BoundKind.ConditionalAccess ' BoundConditionalAccessReceiver isn't actually used until local rewriting, until then that node will be a ' BoundRValuePlaceholder with a syntax node of the entire conditional access. So we dig through the syntax ' to get the expression being conditionally accessed, and return an IConditionalAccessInstanceOperation ' instead of a PlaceholderOperation syntax = If(TryCast(syntax, ConditionalAccessExpressionSyntax)?.Expression, syntax) Return New ConditionalAccessInstanceOperation(_semanticModel, syntax, type, isImplicit) Case BoundKind.SelectStatement placeholderKind = PlaceholderKind.SwitchOperationExpression Case BoundKind.ForToStatement Dim operators As BoundForToUserDefinedOperators = DirectCast(knownParent, BoundForToStatement).OperatorsOpt If boundRValuePlaceholder Is operators.LeftOperandPlaceholder Then placeholderKind = PlaceholderKind.ForToLoopBinaryOperatorLeftOperand Else Debug.Assert(boundRValuePlaceholder Is operators.RightOperandPlaceholder) placeholderKind = PlaceholderKind.ForToLoopBinaryOperatorRightOperand End If Case BoundKind.AggregateClause placeholderKind = PlaceholderKind.AggregationGroup End Select End If Return New PlaceholderOperation(placeholderKind, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundIfStatementOperation(boundIfStatement As BoundIfStatement) As IConditionalOperation Dim condition As IOperation = Create(boundIfStatement.Condition) Dim whenTrue As IOperation = Create(boundIfStatement.Consequence) Dim whenFalse As IOperation = Create(boundIfStatement.AlternativeOpt) Dim syntax As SyntaxNode = boundIfStatement.Syntax Dim type As ITypeSymbol = Nothing Dim constantValue As ConstantValue = Nothing Dim isImplicit As Boolean = boundIfStatement.WasCompilerGenerated Dim isRef As Boolean = False Return New ConditionalOperation(condition, whenTrue, whenFalse, isRef, _semanticModel, syntax, type, constantValue, isImplicit) End Function Private Function CreateBoundSelectStatementOperation(boundSelectStatement As BoundSelectStatement) As ISwitchOperation RecordParent(boundSelectStatement.ExprPlaceholderOpt, boundSelectStatement) Dim value As IOperation = Create(boundSelectStatement.ExpressionStatement.Expression) Dim cases As ImmutableArray(Of ISwitchCaseOperation) = CreateFromArray(Of BoundCaseBlock, ISwitchCaseOperation)(boundSelectStatement.CaseBlocks) Dim exitLabel As ILabelSymbol = boundSelectStatement.ExitLabel Dim syntax As SyntaxNode = boundSelectStatement.Syntax Dim isImplicit As Boolean = boundSelectStatement.WasCompilerGenerated Return New SwitchOperation(ImmutableArray(Of ILocalSymbol).Empty, value, cases, exitLabel, _semanticModel, syntax, isImplicit) End Function Friend Function CreateBoundCaseBlockClauses(boundCaseBlock As BoundCaseBlock) As ImmutableArray(Of ICaseClauseOperation) ' `CaseElseClauseSyntax` is bound to `BoundCaseStatement` with an empty list of case clauses, ' so we explicitly create an IOperation node for Case-Else clause to differentiate it from Case clause. Dim caseStatement = boundCaseBlock.CaseStatement If caseStatement.CaseClauses.IsEmpty AndAlso caseStatement.Syntax.Kind() = SyntaxKind.CaseElseStatement Then Return ImmutableArray.Create(Of ICaseClauseOperation)( New DefaultCaseClauseOperation( label:=Nothing, _semanticModel, caseStatement.Syntax, isImplicit:=boundCaseBlock.WasCompilerGenerated)) Else Return caseStatement.CaseClauses.SelectAsArray(Function(n) DirectCast(Create(n), ICaseClauseOperation)) End If End Function Friend Function CreateBoundCaseBlockBody(boundCaseBlock As BoundCaseBlock) As ImmutableArray(Of IOperation) Return ImmutableArray.Create(Create(boundCaseBlock.Body)) End Function Friend Function CreateBoundCaseBlockCondition(boundCaseBlock As BoundCaseBlock) As IOperation Return Create(boundCaseBlock.CaseStatement.ConditionOpt) End Function Private Function CreateBoundCaseBlockOperation(boundCaseBlock As BoundCaseBlock) As ISwitchCaseOperation Dim clauses As ImmutableArray(Of ICaseClauseOperation) = CreateBoundCaseBlockClauses(boundCaseBlock) Dim body As ImmutableArray(Of IOperation) = ImmutableArray.Create(Create(boundCaseBlock.Body)) Dim condition As IOperation = CreateBoundCaseBlockCondition(boundCaseBlock) Dim syntax As SyntaxNode = boundCaseBlock.Syntax Dim isImplicit As Boolean = boundCaseBlock.WasCompilerGenerated Return New SwitchCaseOperation(clauses, body, ImmutableArray(Of ILocalSymbol).Empty, condition, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundSimpleCaseClauseOperation(boundSimpleCaseClause As BoundSimpleCaseClause) As ISingleValueCaseClauseOperation Dim clauseValue As IOperation = Create(GetSingleValueCaseClauseValue(boundSimpleCaseClause)) Dim syntax As SyntaxNode = boundSimpleCaseClause.Syntax Dim isImplicit As Boolean = boundSimpleCaseClause.WasCompilerGenerated Return New SingleValueCaseClauseOperation(clauseValue, label:=Nothing, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundRangeCaseClauseOperation(boundRangeCaseClause As BoundRangeCaseClause) As IRangeCaseClauseOperation Dim minimumValue As IOperation = Create(GetCaseClauseValue(boundRangeCaseClause.LowerBoundOpt, boundRangeCaseClause.LowerBoundConditionOpt)) Dim maximumValue As IOperation = Create(GetCaseClauseValue(boundRangeCaseClause.UpperBoundOpt, boundRangeCaseClause.UpperBoundConditionOpt)) Debug.Assert(minimumValue IsNot Nothing AndAlso maximumValue IsNot Nothing) Dim syntax As SyntaxNode = boundRangeCaseClause.Syntax Dim isImplicit As Boolean = boundRangeCaseClause.WasCompilerGenerated Return New RangeCaseClauseOperation(minimumValue, maximumValue, label:=Nothing, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundRelationalCaseClauseOperation(boundRelationalCaseClause As BoundRelationalCaseClause) As IRelationalCaseClauseOperation Dim valueExpression As IOperation = Create(GetSingleValueCaseClauseValue(boundRelationalCaseClause)) Dim relation As BinaryOperatorKind = If(valueExpression IsNot Nothing, Helper.DeriveBinaryOperatorKind(boundRelationalCaseClause.OperatorKind, leftOpt:=Nothing), BinaryOperatorKind.None) Dim syntax As SyntaxNode = boundRelationalCaseClause.Syntax Dim isImplicit As Boolean = boundRelationalCaseClause.WasCompilerGenerated Return New RelationalCaseClauseOperation(valueExpression, relation, label:=Nothing, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IWhileLoopOperation Dim condition As IOperation = Create(boundDoLoopStatement.ConditionOpt) Dim body As IOperation = Create(boundDoLoopStatement.Body) Dim ignoredCondition As IOperation = If(boundDoLoopStatement.TopConditionOpt IsNot Nothing AndAlso boundDoLoopStatement.BottomConditionOpt IsNot Nothing, Create(boundDoLoopStatement.BottomConditionOpt), Nothing) Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty Dim continueLabel As ILabelSymbol = boundDoLoopStatement.ContinueLabel Dim exitLabel As ILabelSymbol = boundDoLoopStatement.ExitLabel Dim conditionIsTop As Boolean = boundDoLoopStatement.ConditionIsTop Dim conditionIsUntil As Boolean = boundDoLoopStatement.ConditionIsUntil Dim syntax As SyntaxNode = boundDoLoopStatement.Syntax Dim isImplicit As Boolean = boundDoLoopStatement.WasCompilerGenerated Return New WhileLoopOperation(condition, conditionIsTop, conditionIsUntil, ignoredCondition, body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForToLoopOperation Dim loopControlVariable As IOperation = CreateBoundControlVariableOperation(boundForToStatement) Dim initialValue As IOperation = Create(boundForToStatement.InitialValue) Dim limitValue As IOperation = Create(boundForToStatement.LimitValue) Dim stepValue As IOperation = Create(boundForToStatement.StepValue) Dim body As IOperation = Create(boundForToStatement.Body) Dim nextVariables As ImmutableArray(Of IOperation) = If(boundForToStatement.NextVariablesOpt.IsDefault, ImmutableArray(Of IOperation).Empty, CreateFromArray(Of BoundExpression, IOperation)(boundForToStatement.NextVariablesOpt)) Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundForToStatement.DeclaredOrInferredLocalOpt IsNot Nothing, ImmutableArray.Create(Of ILocalSymbol)(boundForToStatement.DeclaredOrInferredLocalOpt), ImmutableArray(Of ILocalSymbol).Empty) Dim continueLabel As ILabelSymbol = boundForToStatement.ContinueLabel Dim exitLabel As ILabelSymbol = boundForToStatement.ExitLabel Dim syntax As SyntaxNode = boundForToStatement.Syntax Dim isImplicit As Boolean = boundForToStatement.WasCompilerGenerated Dim loopObj = If(boundForToStatement.ControlVariable.Type.IsObjectType, New SynthesizedLocal(DirectCast(_semanticModel.GetEnclosingSymbol(boundForToStatement.Syntax.SpanStart), Symbol), boundForToStatement.ControlVariable.Type, SynthesizedLocalKind.ForInitialValue, boundForToStatement.Syntax), Nothing) Dim userDefinedInfo As ForToLoopOperationUserDefinedInfo = Nothing Dim operatorsOpt As BoundForToUserDefinedOperators = boundForToStatement.OperatorsOpt If operatorsOpt IsNot Nothing Then RecordParent(operatorsOpt.LeftOperandPlaceholder, boundForToStatement) RecordParent(operatorsOpt.RightOperandPlaceholder, boundForToStatement) userDefinedInfo = New ForToLoopOperationUserDefinedInfo(DirectCast(Operation.SetParentOperation(Create(operatorsOpt.Addition), Nothing), IBinaryOperation), DirectCast(Operation.SetParentOperation(Create(operatorsOpt.Subtraction), Nothing), IBinaryOperation), Operation.SetParentOperation(Create(operatorsOpt.LessThanOrEqual), Nothing), Operation.SetParentOperation(Create(operatorsOpt.GreaterThanOrEqual), Nothing)) End If Return New ForToLoopOperation(loopControlVariable, initialValue, limitValue, stepValue, boundForToStatement.Checked, nextVariables, (loopObj, userDefinedInfo), body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit) End Function Friend Function GetForEachLoopOperationInfo(boundForEachStatement As BoundForEachStatement) As ForEachLoopOperationInfo Dim getEnumeratorArguments As ImmutableArray(Of BoundExpression) = Nothing Dim getEnumeratorDefaultArguments As BitVector = BitVector.Null Dim moveNextArguments As ImmutableArray(Of BoundExpression) = Nothing Dim moveNextDefaultArguments As BitVector = BitVector.Null Dim currentArguments As ImmutableArray(Of BoundExpression) = Nothing Dim currentDefaultArguments As BitVector = BitVector.Null Dim statementInfo As ForEachStatementInfo = MemberSemanticModel.GetForEachStatementInfo(boundForEachStatement, DirectCast(_semanticModel.Compilation, VisualBasicCompilation), getEnumeratorArguments, getEnumeratorDefaultArguments, moveNextArguments, moveNextDefaultArguments, currentArguments, currentDefaultArguments) Return New ForEachLoopOperationInfo(statementInfo.ElementType, statementInfo.GetEnumeratorMethod, statementInfo.CurrentProperty, statementInfo.MoveNextMethod, isAsynchronous:=False, inlineArrayConversion:=Nothing, collectionIsInlineArrayValue:=False, boundForEachStatement.EnumeratorInfo.NeedToDispose, knownToImplementIDisposable:=boundForEachStatement.EnumeratorInfo.NeedToDispose AndAlso boundForEachStatement.EnumeratorInfo.IsOrInheritsFromOrImplementsIDisposable, patternDisposeMethod:=Nothing, statementInfo.CurrentConversion, statementInfo.ElementConversion, If(getEnumeratorArguments.IsDefaultOrEmpty, Nothing, Operation.SetParentOperation( DeriveArguments(getEnumeratorArguments, DirectCast(statementInfo.GetEnumeratorMethod, MethodSymbol).Parameters, getEnumeratorDefaultArguments), Nothing)), If(moveNextArguments.IsDefaultOrEmpty, Nothing, Operation.SetParentOperation( DeriveArguments(moveNextArguments, DirectCast(statementInfo.MoveNextMethod, MethodSymbol).Parameters, moveNextDefaultArguments), Nothing)), If(currentArguments.IsDefaultOrEmpty, Nothing, Operation.SetParentOperation( DeriveArguments(currentArguments, DirectCast(statementInfo.CurrentProperty, PropertySymbol).Parameters, currentDefaultArguments), Nothing))) End Function Private Function CreateBoundForEachStatementOperation(boundForEachStatement As BoundForEachStatement) As IForEachLoopOperation Dim info As ForEachLoopOperationInfo = GetForEachLoopOperationInfo(boundForEachStatement) Dim controlVariable As IOperation = CreateBoundControlVariableOperation(boundForEachStatement) Dim collection As IOperation = Create(boundForEachStatement.Collection) Dim nextVariables = If(boundForEachStatement.NextVariablesOpt.IsDefault, ImmutableArray(Of IOperation).Empty, CreateFromArray(Of BoundExpression, IOperation)(boundForEachStatement.NextVariablesOpt)) Dim body As IOperation = Create(boundForEachStatement.Body) Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundForEachStatement.DeclaredOrInferredLocalOpt IsNot Nothing, ImmutableArray.Create(Of ILocalSymbol)(boundForEachStatement.DeclaredOrInferredLocalOpt), ImmutableArray(Of ILocalSymbol).Empty) Dim continueLabel As ILabelSymbol = boundForEachStatement.ContinueLabel Dim exitLabel As ILabelSymbol = boundForEachStatement.ExitLabel Dim syntax As SyntaxNode = boundForEachStatement.Syntax Dim isImplicit As Boolean = boundForEachStatement.WasCompilerGenerated Return New ForEachLoopOperation(controlVariable, collection, nextVariables, info, isAsynchronous:=False, body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit) End Function Friend Function CreateBoundControlVariableOperation(boundForStatement As BoundForStatement) As IOperation Dim localOpt As LocalSymbol = boundForStatement.DeclaredOrInferredLocalOpt Dim controlVariable As BoundExpression = boundForStatement.ControlVariable Return If(localOpt IsNot Nothing, New VariableDeclaratorOperation(localOpt, initializer:=Nothing, ignoredArguments:=ImmutableArray(Of IOperation).Empty, semanticModel:=_semanticModel, syntax:=controlVariable.Syntax, isImplicit:=boundForStatement.WasCompilerGenerated), Create(controlVariable)) End Function Private Function CreateBoundTryStatementOperation(boundTryStatement As BoundTryStatement) As ITryOperation Dim body As IBlockOperation = DirectCast(Create(boundTryStatement.TryBlock), IBlockOperation) Dim catches As ImmutableArray(Of ICatchClauseOperation) = CreateFromArray(Of BoundCatchBlock, ICatchClauseOperation)(boundTryStatement.CatchBlocks) Dim [finally] As IBlockOperation = DirectCast(Create(boundTryStatement.FinallyBlockOpt), IBlockOperation) Dim exitLabel As ILabelSymbol = boundTryStatement.ExitLabelOpt Dim syntax As SyntaxNode = boundTryStatement.Syntax Dim isImplicit As Boolean = boundTryStatement.WasCompilerGenerated Return New TryOperation(body, catches, [finally], exitLabel, _semanticModel, syntax, isImplicit) End Function Friend Function CreateBoundCatchBlockExceptionDeclarationOrExpression(boundCatchBlock As BoundCatchBlock) As IOperation If boundCatchBlock.LocalOpt IsNot Nothing AndAlso If(boundCatchBlock.ExceptionSourceOpt?.Kind = BoundKind.Local, False) AndAlso boundCatchBlock.LocalOpt Is DirectCast(boundCatchBlock.ExceptionSourceOpt, BoundLocal).LocalSymbol Then Return New VariableDeclaratorOperation(boundCatchBlock.LocalOpt, initializer:=Nothing, ignoredArguments:=ImmutableArray(Of IOperation).Empty, semanticModel:=_semanticModel, syntax:=boundCatchBlock.ExceptionSourceOpt.Syntax, isImplicit:=False) Else Return Create(boundCatchBlock.ExceptionSourceOpt) End If End Function Private Function CreateBoundCatchBlockOperation(boundCatchBlock As BoundCatchBlock) As ICatchClauseOperation Dim exceptionDeclarationOrExpression As IOperation = CreateBoundCatchBlockExceptionDeclarationOrExpression(boundCatchBlock) Dim filter As IOperation = Create(boundCatchBlock.ExceptionFilterOpt) Dim handler As IBlockOperation = DirectCast(Create(boundCatchBlock.Body), IBlockOperation) Dim exceptionType As ITypeSymbol = If(boundCatchBlock.ExceptionSourceOpt?.Type, DirectCast(_semanticModel.Compilation, VisualBasicCompilation).GetWellKnownType(WellKnownType.System_Exception)) Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundCatchBlock.LocalOpt IsNot Nothing, ImmutableArray.Create(Of ILocalSymbol)(boundCatchBlock.LocalOpt), ImmutableArray(Of ILocalSymbol).Empty) Dim syntax As SyntaxNode = boundCatchBlock.Syntax Dim isImplicit As Boolean = boundCatchBlock.WasCompilerGenerated Return New CatchClauseOperation(exceptionDeclarationOrExpression, exceptionType, locals, filter, handler, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundBlockOperation(boundBlock As BoundBlock) As IBlockOperation Dim operations As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundStatement, IOperation)(boundBlock.Statements) Dim locals As ImmutableArray(Of ILocalSymbol) = boundBlock.Locals.As(Of ILocalSymbol)() Dim syntax As SyntaxNode = boundBlock.Syntax Dim isImplicit As Boolean = boundBlock.WasCompilerGenerated Return New BlockOperation(operations, locals, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundBadStatementOperation(boundBadStatement As BoundBadStatement) As IInvalidOperation Dim syntax As SyntaxNode = boundBadStatement.Syntax ' if child has syntax node point to same syntax node as bad statement, then this invalid statement is implicit Dim isImplicit = boundBadStatement.WasCompilerGenerated If Not isImplicit Then For Each child In boundBadStatement.ChildBoundNodes If child?.Syntax Is boundBadStatement.Syntax Then isImplicit = True Exit For End If Next End If Dim children = CreateFromArray(Of BoundNode, IOperation)(boundBadStatement.ChildBoundNodes) Return New InvalidOperation(children, _semanticModel, syntax, type:=Nothing, constantValue:=Nothing, isImplicit) End Function Private Function CreateBoundReturnStatementOperation(boundReturnStatement As BoundReturnStatement) As IReturnOperation Dim returnedValue As IOperation = Create(boundReturnStatement.ExpressionOpt) Dim syntax As SyntaxNode = boundReturnStatement.Syntax Dim isImplicit As Boolean = boundReturnStatement.WasCompilerGenerated OrElse IsEndSubOrFunctionStatement(syntax) Return New ReturnOperation(returnedValue, OperationKind.Return, _semanticModel, syntax, isImplicit) End Function Private Shared Function IsEndSubOrFunctionStatement(syntax As SyntaxNode) As Boolean Return TryCast(syntax.Parent, MethodBlockBaseSyntax)?.EndBlockStatement Is syntax OrElse TryCast(syntax.Parent, MultiLineLambdaExpressionSyntax)?.EndSubOrFunctionStatement Is syntax End Function Private Function CreateBoundThrowStatementOperation(boundThrowStatement As BoundThrowStatement) As IThrowOperation Dim thrownObject As IOperation = Create(boundThrowStatement.ExpressionOpt) Dim syntax As SyntaxNode = boundThrowStatement.Syntax Dim expressionType As ITypeSymbol = Nothing Dim isImplicit As Boolean = boundThrowStatement.WasCompilerGenerated Return New ThrowOperation(thrownObject, _semanticModel, syntax, expressionType, isImplicit) End Function Private Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileLoopOperation Dim condition As IOperation = Create(boundWhileStatement.Condition) Dim body As IOperation = Create(boundWhileStatement.Body) Dim ignoredCondition As IOperation = Nothing Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty Dim continueLabel As ILabelSymbol = boundWhileStatement.ContinueLabel Dim exitLabel As ILabelSymbol = boundWhileStatement.ExitLabel Dim conditionIsTop As Boolean = True Dim conditionIsUntil As Boolean = False Dim syntax As SyntaxNode = boundWhileStatement.Syntax Dim isImplicit As Boolean = boundWhileStatement.WasCompilerGenerated Return New WhileLoopOperation(condition, conditionIsTop, conditionIsUntil, ignoredCondition, body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationGroupOperation Dim declarations As ImmutableArray(Of IVariableDeclarationOperation) = GetVariableDeclarationStatementVariables(boundDimStatement.LocalDeclarations) Dim syntax As SyntaxNode = boundDimStatement.Syntax Dim isImplicit As Boolean = boundDimStatement.WasCompilerGenerated Return New VariableDeclarationGroupOperation(declarations, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundLocalDeclarationOperation(boundLocalDeclaration As BoundLocalDeclaration) As IVariableDeclarationGroupOperation Dim declarations As ImmutableArray(Of IVariableDeclarationOperation) = GetVariableDeclarationStatementVariables(ImmutableArray.Create(Of BoundLocalDeclarationBase)(boundLocalDeclaration)) Dim syntax As SyntaxNode = boundLocalDeclaration.Syntax Debug.Assert(boundLocalDeclaration.WasCompilerGenerated) Dim isImplicit As Boolean = True Return New VariableDeclarationGroupOperation(declarations, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundYieldStatementOperation(boundYieldStatement As BoundYieldStatement) As IReturnOperation Dim returnedValue As IOperation = Create(boundYieldStatement.Expression) Dim syntax As SyntaxNode = boundYieldStatement.Syntax Dim isImplicit As Boolean = boundYieldStatement.WasCompilerGenerated Return New ReturnOperation(returnedValue, OperationKind.YieldReturn, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundLabelStatementOperation(boundLabelStatement As BoundLabelStatement) As ILabeledOperation Dim label As ILabelSymbol = boundLabelStatement.Label Dim statement As IOperation = Nothing Dim syntax As SyntaxNode = boundLabelStatement.Syntax Dim isImplicit As Boolean = boundLabelStatement.WasCompilerGenerated OrElse IsEndSubOrFunctionStatement(syntax) Return New LabeledOperation(label, statement, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundGotoStatementOperation(boundGotoStatement As BoundGotoStatement) As IBranchOperation Dim target As ILabelSymbol = boundGotoStatement.Label Dim branchKind As BranchKind = BranchKind.GoTo Dim syntax As SyntaxNode = boundGotoStatement.Syntax Dim isImplicit As Boolean = boundGotoStatement.WasCompilerGenerated Return New BranchOperation(target, branchKind, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundContinueStatementOperation(boundContinueStatement As BoundContinueStatement) As IBranchOperation Dim target As ILabelSymbol = boundContinueStatement.Label Dim branchKind As BranchKind = BranchKind.Continue Dim syntax As SyntaxNode = boundContinueStatement.Syntax Dim isImplicit As Boolean = boundContinueStatement.WasCompilerGenerated Return New BranchOperation(target, branchKind, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundExitStatementOperation(boundExitStatement As BoundExitStatement) As IBranchOperation Dim target As ILabelSymbol = boundExitStatement.Label Dim branchKind As BranchKind = BranchKind.Break Dim syntax As SyntaxNode = boundExitStatement.Syntax Dim isImplicit As Boolean = boundExitStatement.WasCompilerGenerated Return New BranchOperation(target, branchKind, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundSyncLockStatementOperation(boundSyncLockStatement As BoundSyncLockStatement) As ILockOperation Dim legacyMode = _semanticModel.Compilation.CommonGetWellKnownTypeMember(WellKnownMember.System_Threading_Monitor__Enter2) Is Nothing Dim lockTakenSymbol As ILocalSymbol = If(legacyMode, Nothing, New SynthesizedLocal(DirectCast(_semanticModel.GetEnclosingSymbol(boundSyncLockStatement.Syntax.SpanStart), Symbol), DirectCast(_semanticModel.Compilation.GetSpecialType(SpecialType.System_Boolean), TypeSymbol), SynthesizedLocalKind.LockTaken, syntaxOpt:=boundSyncLockStatement.LockExpression.Syntax)) Dim lockedValue As IOperation = Create(boundSyncLockStatement.LockExpression) Dim body As IOperation = Create(boundSyncLockStatement.Body) Dim syntax As SyntaxNode = boundSyncLockStatement.Syntax Dim isImplicit As Boolean = boundSyncLockStatement.WasCompilerGenerated Return New LockOperation(lockedValue, body, lockTakenSymbol, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundNoOpStatementOperation(boundNoOpStatement As BoundNoOpStatement) As IEmptyOperation Dim syntax As SyntaxNode = boundNoOpStatement.Syntax Dim type As ITypeSymbol = Nothing Dim constantValue As ConstantValue = Nothing Dim isImplicit As Boolean = boundNoOpStatement.WasCompilerGenerated Return New EmptyOperation(_semanticModel, syntax, isImplicit) End Function Private Function CreateBoundStopStatementOperation(boundStopStatement As BoundStopStatement) As IStopOperation Dim syntax As SyntaxNode = boundStopStatement.Syntax Dim isImplicit As Boolean = boundStopStatement.WasCompilerGenerated Return New StopOperation(_semanticModel, syntax, isImplicit) End Function Private Function CreateBoundEndStatementOperation(boundEndStatement As BoundEndStatement) As IEndOperation Dim syntax As SyntaxNode = boundEndStatement.Syntax Dim isImplicit As Boolean = boundEndStatement.WasCompilerGenerated Return New EndOperation(_semanticModel, syntax, isImplicit) End Function Private Function CreateBoundWithStatementOperation(boundWithStatement As BoundWithStatement) As IWithStatementOperation Dim value As IOperation = Create(boundWithStatement.OriginalExpression) Dim body As IOperation = Create(boundWithStatement.Body) Dim syntax As SyntaxNode = boundWithStatement.Syntax Dim isImplicit As Boolean = boundWithStatement.WasCompilerGenerated Return New WithStatementOperation(body, value, _semanticModel, syntax, isImplicit) End Function Friend Function CreateBoundUsingStatementResources(boundUsingStatement As BoundUsingStatement) As IOperation If Not boundUsingStatement.ResourceList.IsDefault Then Return GetUsingStatementDeclaration(boundUsingStatement.ResourceList, DirectCast(boundUsingStatement.Syntax, UsingBlockSyntax).UsingStatement) Else Return Create(boundUsingStatement.ResourceExpressionOpt) End If End Function Private Function CreateBoundUsingStatementOperation(boundUsingStatement As BoundUsingStatement) As IUsingOperation Dim resources As IOperation = CreateBoundUsingStatementResources(boundUsingStatement) Dim body As IOperation = Create(boundUsingStatement.Body) Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).CastUp(boundUsingStatement.Locals) Dim syntax As SyntaxNode = boundUsingStatement.Syntax Dim isImplicit As Boolean = boundUsingStatement.WasCompilerGenerated Return New UsingOperation(resources, body, locals, isAsynchronous:=False, disposeInfo:=Nothing, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundExpressionStatementOperation(boundExpressionStatement As BoundExpressionStatement) As IExpressionStatementOperation Dim expression As IOperation = Create(boundExpressionStatement.Expression) Dim syntax As SyntaxNode = boundExpressionStatement.Syntax Dim isImplicit As Boolean = boundExpressionStatement.WasCompilerGenerated Return New ExpressionStatementOperation(expression, _semanticModel, syntax, isImplicit) End Function Friend Function CreateBoundRaiseEventStatementEventReference(boundRaiseEventStatement As BoundRaiseEventStatement) As IEventReferenceOperation Dim eventInvocation = DirectCast(boundRaiseEventStatement.EventInvocation, BoundCall) Dim receiverOpt = eventInvocation.ReceiverOpt Dim eventReferenceSyntax = If(receiverOpt?.Syntax, If(TryCast(boundRaiseEventStatement.Syntax, RaiseEventStatementSyntax)?.Name, boundRaiseEventStatement.Syntax)) Dim eventReferenceType As ITypeSymbol = boundRaiseEventStatement.EventSymbol.Type ' EventReference in a raise event statement is never implicit. However, the way it is implemented, we don't get ' a "BoundEventAccess" for either field backed event or custom event, and the bound nodes we get are marked as ' generated by compiler. As a result, we have to explicitly set IsImplicit to false. Dim eventReferenceIsImplicit As Boolean = False If receiverOpt?.Kind = BoundKind.FieldAccess Then ' For raising a field backed event, we will only get a field access node in bound tree. Dim eventFieldAccess = DirectCast(receiverOpt, BoundFieldAccess) Debug.Assert(eventFieldAccess.FieldSymbol.AssociatedSymbol = boundRaiseEventStatement.EventSymbol) receiverOpt = eventFieldAccess.ReceiverOpt End If Dim instance = CreateReceiverOperation(receiverOpt, boundRaiseEventStatement.EventSymbol) Return New EventReferenceOperation(boundRaiseEventStatement.EventSymbol, constrainedToType:=Nothing, instance, _semanticModel, eventReferenceSyntax, eventReferenceType, eventReferenceIsImplicit) End Function Private Function CreateBoundRaiseEventStatementOperation(boundRaiseEventStatement As BoundRaiseEventStatement) As IOperation Dim syntax As SyntaxNode = boundRaiseEventStatement.Syntax Dim isImplicit As Boolean = boundRaiseEventStatement.WasCompilerGenerated Dim eventSymbol = boundRaiseEventStatement.EventSymbol Dim eventInvocation = TryCast(boundRaiseEventStatement.EventInvocation, BoundCall) ' Return an invalid statement for invalid raise event statement If eventInvocation Is Nothing OrElse (eventInvocation.ReceiverOpt Is Nothing AndAlso Not eventSymbol.IsShared) Then Debug.Assert(boundRaiseEventStatement.HasErrors) Dim children = CreateFromArray(Of BoundNode, IOperation)(DirectCast(boundRaiseEventStatement, IBoundInvalidNode).InvalidNodeChildren) Return New InvalidOperation(children, _semanticModel, syntax, type:=Nothing, constantValue:=Nothing, isImplicit) End If Dim eventReference = CreateBoundRaiseEventStatementEventReference(boundRaiseEventStatement) Dim arguments = DeriveArguments(boundRaiseEventStatement) Return New RaiseEventOperation(eventReference, arguments, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundAddHandlerStatementOperation(boundAddHandlerStatement As BoundAddHandlerStatement) As IExpressionStatementOperation Dim expression As IOperation = GetAddRemoveHandlerStatementExpression(boundAddHandlerStatement) Dim syntax As SyntaxNode = boundAddHandlerStatement.Syntax Dim isImplicit As Boolean = boundAddHandlerStatement.WasCompilerGenerated Return New ExpressionStatementOperation(expression, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundRemoveHandlerStatementOperation(boundRemoveHandlerStatement As BoundRemoveHandlerStatement) As IExpressionStatementOperation Dim expression As IOperation = GetAddRemoveHandlerStatementExpression(boundRemoveHandlerStatement) Dim syntax As SyntaxNode = boundRemoveHandlerStatement.Syntax Dim type As ITypeSymbol = Nothing Dim constantValue As ConstantValue = Nothing Dim isImplicit As Boolean = boundRemoveHandlerStatement.WasCompilerGenerated Return New ExpressionStatementOperation(expression, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundTupleLiteralOperation(boundTupleLiteral As BoundTupleLiteral) As ITupleOperation Return CreateTupleOperation(boundTupleLiteral, boundTupleLiteral.Type) End Function Private Function CreateBoundConvertedTupleLiteralOperation(boundConvertedTupleLiteral As BoundConvertedTupleLiteral) As ITupleOperation Return CreateTupleOperation(boundConvertedTupleLiteral, boundConvertedTupleLiteral.NaturalTypeOpt) End Function Private Function CreateTupleOperation(boundTupleExpression As BoundTupleExpression, naturalType As ITypeSymbol) As ITupleOperation Dim elements As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundTupleExpression.Arguments) Dim syntax As SyntaxNode = boundTupleExpression.Syntax Dim type As ITypeSymbol = boundTupleExpression.Type Dim isImplicit As Boolean = boundTupleExpression.WasCompilerGenerated Return New TupleOperation(elements, naturalType, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundInterpolatedStringExpressionOperation(boundInterpolatedString As BoundInterpolatedStringExpression) As IInterpolatedStringOperation Dim parts As ImmutableArray(Of IInterpolatedStringContentOperation) = CreateBoundInterpolatedStringContentOperation(boundInterpolatedString.Contents) Dim syntax As SyntaxNode = boundInterpolatedString.Syntax Dim type As ITypeSymbol = boundInterpolatedString.Type Dim constantValue As ConstantValue = boundInterpolatedString.ConstantValueOpt Dim isImplicit As Boolean = boundInterpolatedString.WasCompilerGenerated Return New InterpolatedStringOperation(parts, _semanticModel, syntax, type, constantValue, isImplicit) End Function Friend Function CreateBoundInterpolatedStringContentOperation(parts As ImmutableArray(Of BoundNode)) As ImmutableArray(Of IInterpolatedStringContentOperation) Dim builder = ArrayBuilder(Of IInterpolatedStringContentOperation).GetInstance(parts.Length) For Each part In parts If part.Kind = BoundKind.Interpolation Then builder.Add(DirectCast(Create(part), IInterpolatedStringContentOperation)) Else builder.Add(CreateBoundInterpolatedStringTextOperation(DirectCast(part, BoundLiteral))) End If Next Return builder.ToImmutableAndFree() End Function Private Function CreateBoundInterpolationOperation(boundInterpolation As BoundInterpolation) As IInterpolationOperation Dim expression As IOperation = Create(boundInterpolation.Expression) Dim alignment As IOperation = Create(boundInterpolation.AlignmentOpt) Dim formatString As IOperation = Create(boundInterpolation.FormatStringOpt) Dim syntax As SyntaxNode = boundInterpolation.Syntax Dim isImplicit As Boolean = boundInterpolation.WasCompilerGenerated Return New InterpolationOperation(expression, alignment, formatString, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundInterpolatedStringTextOperation(boundLiteral As BoundLiteral) As IInterpolatedStringTextOperation Dim text As IOperation = CreateBoundLiteralOperation(boundLiteral, implicit:=True) Dim syntax As SyntaxNode = boundLiteral.Syntax Dim isImplicit As Boolean = boundLiteral.WasCompilerGenerated Return New InterpolatedStringTextOperation(text, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundAnonymousTypeCreationExpressionOperation(boundAnonymousTypeCreationExpression As BoundAnonymousTypeCreationExpression) As IAnonymousObjectCreationOperation Dim initializers As ImmutableArray(Of IOperation) = GetAnonymousTypeCreationInitializers(boundAnonymousTypeCreationExpression) Dim syntax As SyntaxNode = boundAnonymousTypeCreationExpression.Syntax Dim type As ITypeSymbol = boundAnonymousTypeCreationExpression.Type Dim isImplicit As Boolean = boundAnonymousTypeCreationExpression.WasCompilerGenerated Return New AnonymousObjectCreationOperation(initializers, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess As BoundAnonymousTypePropertyAccess) As IPropertyReferenceOperation Dim [property] As IPropertySymbol = DirectCast(boundAnonymousTypePropertyAccess.ExpressionSymbol, IPropertySymbol) Return CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess, [property]) End Function Private Function CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess As BoundAnonymousTypePropertyAccess, [property] As IPropertySymbol) As IPropertyReferenceOperation Dim instance As IOperation = CreateAnonymousTypePropertyAccessImplicitReceiverOperation([property], boundAnonymousTypePropertyAccess.Syntax.FirstAncestorOrSelf(Of AnonymousObjectCreationExpressionSyntax)) Dim arguments = ImmutableArray(Of IArgumentOperation).Empty Dim syntax As SyntaxNode = boundAnonymousTypePropertyAccess.Syntax Dim type As ITypeSymbol = boundAnonymousTypePropertyAccess.Type Dim isImplicit As Boolean = boundAnonymousTypePropertyAccess.WasCompilerGenerated Return New PropertyReferenceOperation([property], constrainedToType:=Nothing, arguments, instance, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateAnonymousTypePropertyAccessImplicitReceiverOperation(propertySym As IPropertySymbol, syntax As SyntaxNode) As InstanceReferenceOperation Debug.Assert(propertySym IsNot Nothing) Debug.Assert(syntax IsNot Nothing) Return New InstanceReferenceOperation( InstanceReferenceKind.ImplicitReceiver, _semanticModel, syntax, propertySym.ContainingType, isImplicit:=True) End Function Private Function CreateBoundQueryExpressionOperation(boundQueryExpression As BoundQueryExpression) As IOperation Dim operation As IOperation = Create(boundQueryExpression.LastOperator) Dim syntax As SyntaxNode = boundQueryExpression.Syntax Dim type As ITypeSymbol = boundQueryExpression.Type Dim isImplicit As Boolean = boundQueryExpression.WasCompilerGenerated Return New TranslatedQueryOperation(operation, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundAggregateClauseOperation(boundAggregateClause As BoundAggregateClause) As IOperation If boundAggregateClause.CapturedGroupOpt Is Nothing Then ' This Aggregate clause has no special representation in the IOperation tree Return Create(boundAggregateClause.UnderlyingExpression) End If Debug.Assert(boundAggregateClause.GroupPlaceholderOpt IsNot Nothing) RecordParent(boundAggregateClause.GroupPlaceholderOpt, boundAggregateClause) Dim group As IOperation = Create(boundAggregateClause.CapturedGroupOpt) Dim aggregation As IOperation = Create(boundAggregateClause.UnderlyingExpression) Dim syntax As SyntaxNode = boundAggregateClause.Syntax Dim type As ITypeSymbol = boundAggregateClause.Type Dim isImplicit As Boolean = boundAggregateClause.WasCompilerGenerated Return New AggregateQueryOperation(group, aggregation, _semanticModel, syntax, type, isImplicit) End Function Private Function CreateBoundNullableIsTrueOperator(boundNullableIsTrueOperator As BoundNullableIsTrueOperator) As IOperation Dim syntax As SyntaxNode = boundNullableIsTrueOperator.Syntax Dim type As ITypeSymbol = boundNullableIsTrueOperator.Type Dim constantValue As ConstantValue = boundNullableIsTrueOperator.ConstantValueOpt Dim isImplicit As Boolean = boundNullableIsTrueOperator.WasCompilerGenerated Debug.Assert(boundNullableIsTrueOperator.Operand.Type.IsNullableOfBoolean() AndAlso boundNullableIsTrueOperator.Type.IsBooleanType()) Dim method = DirectCast(DirectCast(_semanticModel.Compilation, VisualBasicCompilation). GetSpecialTypeMember(SpecialMember.System_Nullable_T_GetValueOrDefault), MethodSymbol) If method IsNot Nothing Then Dim receiver As IOperation = CreateReceiverOperation(boundNullableIsTrueOperator.Operand, method) Return New InvocationOperation(method.AsMember(DirectCast(boundNullableIsTrueOperator.Operand.Type, NamedTypeSymbol)), constrainedToType:=Nothing, receiver, isVirtual:=False, arguments:=ImmutableArray(Of IArgumentOperation).Empty, _semanticModel, syntax, boundNullableIsTrueOperator.Type, isImplicit) Else Dim children = CreateFromArray(Of BoundNode, IOperation)(DirectCast(boundNullableIsTrueOperator, IBoundInvalidNode).InvalidNodeChildren) Return New InvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit) End If End Function Private Function CreateBoundReDimOperation(boundRedimStatement As BoundRedimStatement) As IReDimOperation Dim clauses As ImmutableArray(Of IReDimClauseOperation) = CreateFromArray(Of BoundRedimClause, IReDimClauseOperation)(boundRedimStatement.Clauses) Dim preserve As Boolean = boundRedimStatement.Syntax.Kind = SyntaxKind.ReDimPreserveStatement #If DEBUG Then For Each clause In boundRedimStatement.Clauses Debug.Assert(preserve = clause.Preserve) Next #End If Dim syntax As SyntaxNode = boundRedimStatement.Syntax Dim isImplicit As Boolean = boundRedimStatement.WasCompilerGenerated Return New ReDimOperation(clauses, preserve, _semanticModel, syntax, isImplicit) End Function Private Function CreateBoundReDimClauseOperation(boundRedimClause As BoundRedimClause) As IReDimClauseOperation Dim operand As IOperation = Create(boundRedimClause.Operand) Dim dimensionSizes As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundRedimClause.Indices) Dim syntax As SyntaxNode = boundRedimClause.Syntax Dim isImplicit As Boolean = boundRedimClause.WasCompilerGenerated Return New ReDimClauseOperation(operand, dimensionSizes, _semanticModel, syntax, isImplicit) End Function End Class End Namespace