// 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.
// < auto-generated />
#nullable enable
using System;
using System.Collections.Generic;
using System.Threading;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.FlowAnalysis;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Operations
{
#region Interfaces
///
/// Represents an invalid operation with one or more child operations.
///
/// Current usage:
///
/// - C# invalid expression or invalid statement
/// - VB invalid expression or invalid statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInvalidOperation : IOperation
{
}
///
/// Represents a block containing a sequence of operations and local declarations.
///
/// Current usage:
///
/// - C# "{ ... }" block statement
/// - VB implicit block statement for method bodies and other block scoped statements
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IBlockOperation : IOperation
{
///
/// Operations contained within the block.
///
ImmutableArray Operations { get; }
///
/// Local declarations contained within the block.
///
ImmutableArray Locals { get; }
}
///
/// Represents a variable declaration statement.
///
/// Current Usage:
///
/// - C# local declaration statement
/// - C# fixed statement
/// - C# using statement
/// - C# using declaration
/// - VB Dim statement
/// - VB Using statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IVariableDeclarationGroupOperation : IOperation
{
///
/// Variable declaration in the statement.
///
///
/// In C#, this will always be a single declaration, with all variables in .
///
ImmutableArray Declarations { get; }
}
///
/// Represents a switch operation with a value to be switched upon and switch cases.
///
/// Current usage:
///
/// - C# switch statement
/// - VB Select Case statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISwitchOperation : IOperation
{
///
/// Locals declared within the switch operation with scope spanning across all .
///
ImmutableArray Locals { get; }
///
/// Value to be switched upon.
///
IOperation Value { get; }
///
/// Cases of the switch.
///
ImmutableArray Cases { get; }
///
/// Exit label for the switch statement.
///
ILabelSymbol ExitLabel { get; }
}
///
/// Represents a loop operation.
///
/// Current usage:
///
/// - C# 'while', 'for', 'foreach' and 'do' loop statements
/// - VB 'While', 'ForTo', 'ForEach', 'Do While' and 'Do Until' loop statements
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ILoopOperation : IOperation
{
///
/// Kind of the loop.
///
LoopKind LoopKind { get; }
///
/// Body of the loop.
///
IOperation Body { get; }
///
/// Declared locals.
///
ImmutableArray Locals { get; }
///
/// Loop continue label.
///
ILabelSymbol ContinueLabel { get; }
///
/// Loop exit/break label.
///
ILabelSymbol ExitLabel { get; }
}
///
/// Represents a for each loop.
///
/// Current usage:
///
/// - C# 'foreach' loop statement
/// - VB 'For Each' loop statement
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IForEachLoopOperation : ILoopOperation
{
///
/// Refers to the operation for declaring a new local variable or reference an existing variable or an expression.
///
IOperation LoopControlVariable { get; }
///
/// Collection value over which the loop iterates.
///
IOperation Collection { get; }
///
/// Optional list of comma separated next variables at loop bottom in VB.
/// This list is always empty for C#.
///
ImmutableArray NextVariables { get; }
///
/// Whether this for each loop is asynchronous.
/// Always false for VB.
///
bool IsAsynchronous { get; }
}
///
/// Represents a for loop.
///
/// Current usage:
///
/// - C# 'for' loop statement
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IForLoopOperation : ILoopOperation
{
///
/// List of operations to execute before entry to the loop. For C#, this comes from the first clause of the for statement.
///
ImmutableArray Before { get; }
///
/// Locals declared within the loop Condition and are in scope throughout the ,
/// and .
/// They are considered to be declared per iteration.
///
ImmutableArray ConditionLocals { get; }
///
/// Condition of the loop. For C#, this comes from the second clause of the for statement.
///
IOperation? Condition { get; }
///
/// List of operations to execute at the bottom of the loop. For C#, this comes from the third clause of the for statement.
///
ImmutableArray AtLoopBottom { get; }
}
///
/// Represents a for to loop with loop control variable and initial, limit and step values for the control variable.
///
/// Current usage:
///
/// - VB 'For ... To ... Step' loop statement
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IForToLoopOperation : ILoopOperation
{
///
/// Refers to the operation for declaring a new local variable or reference an existing variable or an expression.
///
IOperation LoopControlVariable { get; }
///
/// Operation for setting the initial value of the loop control variable. This comes from the expression between the 'For' and 'To' keywords.
///
IOperation InitialValue { get; }
///
/// Operation for the limit value of the loop control variable. This comes from the expression after the 'To' keyword.
///
IOperation LimitValue { get; }
///
/// Operation for the step value of the loop control variable. This comes from the expression after the 'Step' keyword,
/// or inferred by the compiler if 'Step' clause is omitted.
///
IOperation StepValue { get; }
///
/// if arithmetic operations behind this loop are 'checked'.
///
bool IsChecked { get; }
///
/// Optional list of comma separated next variables at loop bottom.
///
ImmutableArray NextVariables { get; }
}
///
/// Represents a while or do while loop.
///
/// Current usage:
///
/// - C# 'while' and 'do while' loop statements
/// - VB 'While', 'Do While' and 'Do Until' loop statements
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IWhileLoopOperation : ILoopOperation
{
///
/// Condition of the loop. This can only be null in error scenarios.
///
IOperation? Condition { get; }
///
/// True if the is evaluated at start of each loop iteration.
/// False if it is evaluated at the end of each loop iteration.
///
bool ConditionIsTop { get; }
///
/// True if the loop has 'Until' loop semantics and the loop is executed while is false.
///
bool ConditionIsUntil { get; }
///
/// Additional conditional supplied for loop in error cases, which is ignored by the compiler.
/// For example, for VB 'Do While' or 'Do Until' loop with syntax errors where both the top and bottom conditions are provided.
/// The top condition is preferred and exposed as and the bottom condition is ignored and exposed by this property.
/// This property should be null for all non-error cases.
///
IOperation? IgnoredCondition { get; }
}
///
/// Represents an operation with a label.
///
/// Current usage:
///
/// - C# labeled statement
/// - VB label statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ILabeledOperation : IOperation
{
///
/// Label that can be the target of branches.
///
ILabelSymbol Label { get; }
///
/// Operation that has been labeled. In VB, this is always null.
///
IOperation? Operation { get; }
}
///
/// Represents a branch operation.
///
/// Current usage:
///
/// - C# goto, break, or continue statement
/// - VB GoTo, Exit ***, or Continue *** statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IBranchOperation : IOperation
{
///
/// Label that is the target of the branch.
///
ILabelSymbol Target { get; }
///
/// Kind of the branch.
///
BranchKind BranchKind { get; }
}
///
/// Represents an empty or no-op operation.
///
/// Current usage:
///
/// - C# empty statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IEmptyOperation : IOperation
{
}
///
/// Represents a return from the method with an optional return value.
///
/// Current usage:
///
/// - C# return statement and yield statement
/// - VB Return statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IReturnOperation : IOperation
{
///
/// Value to be returned.
///
IOperation? ReturnedValue { get; }
}
///
/// Represents a of operations that are executed while holding a lock onto the .
///
/// Current usage:
///
/// - C# lock statement
/// - VB SyncLock statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ILockOperation : IOperation
{
///
/// Operation producing a value to be locked.
///
IOperation LockedValue { get; }
///
/// Body of the lock, to be executed while holding the lock.
///
IOperation Body { get; }
}
///
/// Represents a try operation for exception handling code with a body, catch clauses and a finally handler.
///
/// Current usage:
///
/// - C# try statement
/// - VB Try statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITryOperation : IOperation
{
///
/// Body of the try, over which the handlers are active.
///
IBlockOperation Body { get; }
///
/// Catch clauses of the try.
///
ImmutableArray Catches { get; }
///
/// Finally handler of the try.
///
IBlockOperation? Finally { get; }
///
/// Exit label for the try. This will always be null for C#.
///
ILabelSymbol? ExitLabel { get; }
}
///
/// Represents a of operations that are executed while using disposable .
///
/// Current usage:
///
/// - C# using statement
/// - VB Using statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IUsingOperation : IOperation
{
///
/// Declaration introduced or resource held by the using.
///
IOperation Resources { get; }
///
/// Body of the using, over which the resources of the using are maintained.
///
IOperation Body { get; }
///
/// Locals declared within the with scope spanning across this entire .
///
ImmutableArray Locals { get; }
///
/// Whether this using is asynchronous.
/// Always false for VB.
///
bool IsAsynchronous { get; }
}
///
/// Represents an operation that drops the resulting value and the type of the underlying wrapped .
///
/// Current usage:
///
/// - C# expression statement
/// - VB expression statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IExpressionStatementOperation : IOperation
{
///
/// Underlying operation with a value and type.
///
IOperation Operation { get; }
}
///
/// Represents a local function defined within a method.
///
/// Current usage:
///
/// - C# local function statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ILocalFunctionOperation : IOperation
{
///
/// Local function symbol.
///
IMethodSymbol Symbol { get; }
///
/// Body of the local function.
///
///
/// This can be null in error scenarios, or when the method is an extern method.
///
IBlockOperation? Body { get; }
///
/// An extra body for the local function, if both a block body and expression body are specified in source.
///
///
/// This is only ever non-null in error situations.
///
IBlockOperation? IgnoredBody { get; }
}
///
/// Represents an operation to stop or suspend execution of code.
///
/// Current usage:
///
/// - VB Stop statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IStopOperation : IOperation
{
}
///
/// Represents an operation that stops the execution of code abruptly.
///
/// Current usage:
///
/// - VB End Statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IEndOperation : IOperation
{
}
///
/// Represents an operation for raising an event.
///
/// Current usage:
///
/// - VB raise event statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IRaiseEventOperation : IOperation
{
///
/// Reference to the event to be raised.
///
IEventReferenceOperation EventReference { get; }
///
/// Arguments of the invocation, excluding the instance argument. Arguments are in evaluation order.
///
///
/// If the invocation is in its expanded form, then params/ParamArray arguments would be collected into arrays.
/// Default values are supplied for optional arguments missing in source.
///
ImmutableArray Arguments { get; }
}
///
/// Represents a textual literal numeric, string, etc.
///
/// Current usage:
///
/// - C# literal expression
/// - VB literal expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ILiteralOperation : IOperation
{
}
///
/// Represents a type conversion.
///
/// Current usage:
///
/// - C# conversion expression
/// - VB conversion expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IConversionOperation : IOperation
{
///
/// Value to be converted.
///
IOperation Operand { get; }
///
/// Operator method used by the operation, null if the operation does not use an operator method.
///
IMethodSymbol? OperatorMethod { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the , if any.
/// Null if is resolved statically, or is null.
///
ITypeSymbol? ConstrainedToType { get; }
///
/// Gets the underlying common conversion information.
///
///
/// If you need conversion information that is language specific, use either
/// or
/// .
///
CommonConversion Conversion { get; }
///
/// False if the conversion will fail with a at runtime if the cast fails. This is true for C#'s
/// as operator and for VB's TryCast operator.
///
bool IsTryCast { get; }
///
/// True if the conversion can fail at runtime with an overflow exception. This corresponds to C# checked and unchecked blocks.
///
bool IsChecked { get; }
}
///
/// Represents an invocation of a method.
///
/// Current usage:
///
/// - C# method invocation expression
/// -
///
/// C# collection element initializer.
/// For example, in the following collection initializer: new C() { 1, 2, 3 }, we will have
/// 3 nodes, each of which will be a call to the corresponding Add method
/// with either 1, 2, 3 as the argument
///
///
/// - VB method invocation expression
/// -
///
/// VB collection element initializer.
/// Similar to the C# example, New C() From {1, 2, 3} will have 3
/// nodes with 1, 2, and 3 as their arguments, respectively
///
///
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInvocationOperation : IOperation
{
///
/// Method to be invoked.
///
IMethodSymbol TargetMethod { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the .
/// Null if is resolved statically, or is an instance method.
///
ITypeSymbol? ConstrainedToType { get; }
///
/// 'This' or 'Me' instance to be supplied to the method, or null if the method is static.
///
IOperation? Instance { get; }
///
/// True if the invocation uses a virtual mechanism, and false otherwise.
///
bool IsVirtual { get; }
///
/// Arguments of the invocation, excluding the instance argument. Arguments are in evaluation order.
///
///
/// If the invocation is in its expanded form, then params/ParamArray arguments would be collected into arrays.
/// Default values are supplied for optional arguments missing in source.
///
ImmutableArray Arguments { get; }
}
///
/// Represents a reference to an array element.
///
/// Current usage:
///
/// - C# array element reference expression
/// - VB array element reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IArrayElementReferenceOperation : IOperation
{
///
/// Array to be indexed.
///
IOperation ArrayReference { get; }
///
/// Indices that specify an individual element.
///
ImmutableArray Indices { get; }
}
///
/// Represents a reference to a declared local variable.
///
/// Current usage:
///
/// - C# local reference expression
/// - VB local reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ILocalReferenceOperation : IOperation
{
///
/// Referenced local variable.
///
ILocalSymbol Local { get; }
///
/// True if this reference is also the declaration site of this variable. This is true in out variable declarations
/// and in deconstruction operations where a new variable is being declared.
///
bool IsDeclaration { get; }
}
///
/// Represents a reference to a parameter.
///
/// Current usage:
///
/// - C# parameter reference expression
/// - VB parameter reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IParameterReferenceOperation : IOperation
{
///
/// Referenced parameter.
///
IParameterSymbol Parameter { get; }
}
///
/// Represents a reference to a member of a class, struct, or interface.
///
/// Current usage:
///
/// - C# member reference expression
/// - VB member reference expression
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IMemberReferenceOperation : IOperation
{
///
/// Instance of the type. Null if the reference is to a static/shared member.
///
IOperation? Instance { get; }
///
/// Referenced member.
///
ISymbol Member { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the .
/// Null if is resolved statically, or is an instance member.
///
ITypeSymbol? ConstrainedToType { get; }
}
///
/// Represents a reference to a field.
///
/// Current usage:
///
/// - C# field reference expression
/// - VB field reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IFieldReferenceOperation : IMemberReferenceOperation
{
///
/// Referenced field.
///
IFieldSymbol Field { get; }
///
/// If the field reference is also where the field was declared.
///
///
/// This is only ever true in CSharp scripts, where a top-level statement creates a new variable
/// in a reference, such as an out variable declaration or a deconstruction declaration.
///
bool IsDeclaration { get; }
}
///
/// Represents a reference to a method other than as the target of an invocation.
///
/// Current usage:
///
/// - C# method reference expression
/// - VB method reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IMethodReferenceOperation : IMemberReferenceOperation
{
///
/// Referenced method.
///
IMethodSymbol Method { get; }
///
/// Indicates whether the reference uses virtual semantics.
///
bool IsVirtual { get; }
}
///
/// Represents a reference to a property.
///
/// Current usage:
///
/// - C# property reference expression
/// - VB property reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IPropertyReferenceOperation : IMemberReferenceOperation
{
///
/// Referenced property.
///
IPropertySymbol Property { get; }
///
/// Arguments of the indexer property reference, excluding the instance argument. Arguments are in evaluation order.
///
///
/// If the invocation is in its expanded form, then params/ParamArray arguments would be collected into arrays.
/// Default values are supplied for optional arguments missing in source.
///
ImmutableArray Arguments { get; }
}
///
/// Represents a reference to an event.
///
/// Current usage:
///
/// - C# event reference expression
/// - VB event reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IEventReferenceOperation : IMemberReferenceOperation
{
///
/// Referenced event.
///
IEventSymbol Event { get; }
}
///
/// Represents an operation with one operand and a unary operator.
///
/// Current usage:
///
/// - C# unary operation expression
/// - VB unary operation expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IUnaryOperation : IOperation
{
///
/// Kind of unary operation.
///
UnaryOperatorKind OperatorKind { get; }
///
/// Operand.
///
IOperation Operand { get; }
///
/// if this is a 'lifted' unary operator. When there is an
/// operator that is defined to work on a value type, 'lifted' operators are
/// created to work on the versions of those
/// value types.
///
bool IsLifted { get; }
///
/// if overflow checking is performed for the arithmetic operation.
///
bool IsChecked { get; }
///
/// Operator method used by the operation, null if the operation does not use an operator method.
///
IMethodSymbol? OperatorMethod { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the , if any.
/// Null if is resolved statically, or is null.
///
ITypeSymbol? ConstrainedToType { get; }
}
///
/// Represents an operation with two operands and a binary operator that produces a result with a non-null type.
///
/// Current usage:
///
/// - C# binary operator expression
/// - VB binary operator expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IBinaryOperation : IOperation
{
///
/// Kind of binary operation.
///
BinaryOperatorKind OperatorKind { get; }
///
/// Left operand.
///
IOperation LeftOperand { get; }
///
/// Right operand.
///
IOperation RightOperand { get; }
///
/// if this is a 'lifted' binary operator. When there is an
/// operator that is defined to work on a value type, 'lifted' operators are
/// created to work on the versions of those
/// value types.
///
bool IsLifted { get; }
///
/// if this is a 'checked' binary operator.
///
bool IsChecked { get; }
///
/// if the comparison is text based for string or object comparison in VB.
///
bool IsCompareText { get; }
///
/// Operator method used by the operation, null if the operation does not use an operator method.
///
IMethodSymbol? OperatorMethod { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the
/// or corresponding true/false operator, if any.
/// Null if operators are resolved statically, or are not used.
///
ITypeSymbol? ConstrainedToType { get; }
}
///
/// Represents a conditional operation with:
///
/// - to be tested
/// - operation to be executed when is true and
/// - operation to be executed when the is false
///
///
/// Current usage:
///
/// - C# ternary expression a ? b : c and if statement
/// - VB ternary expression If(a, b, c) and If Else statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IConditionalOperation : IOperation
{
///
/// Condition to be tested.
///
IOperation Condition { get; }
///
/// Operation to be executed if the is true.
///
IOperation WhenTrue { get; }
///
/// Operation to be executed if the is false.
///
IOperation? WhenFalse { get; }
///
/// if the result is by-reference.
///
///
/// This occurs in C# for ternaries whose branches use .
///
bool IsRef { get; }
}
///
/// Represents a coalesce operation with two operands:
///
/// - , which is the first operand that is unconditionally evaluated and is the result of the operation if non null
/// - , which is the second operand that is conditionally evaluated and is the result of the operation if is null
///
///
/// Current usage:
///
/// - C# null-coalescing expression Value ?? WhenNull
/// - VB binary conditional expression If(Value, WhenNull)
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ICoalesceOperation : IOperation
{
///
/// Operation to be unconditionally evaluated.
///
IOperation Value { get; }
///
/// Operation to be conditionally evaluated if evaluates to null/Nothing.
///
IOperation WhenNull { get; }
///
/// Conversion associated with when it is not null/Nothing.
/// Identity if result type of the operation is the same as type of .
/// Otherwise, if type of is nullable, then conversion is applied to an
/// unwrapped , otherwise to the itself.
///
CommonConversion ValueConversion { get; }
}
///
/// Represents an anonymous function operation.
///
/// Current usage:
///
/// - C# lambda expression
/// - VB anonymous delegate expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IAnonymousFunctionOperation : IOperation
{
///
/// Symbol of the anonymous function.
///
IMethodSymbol Symbol { get; }
///
/// Body of the anonymous function.
///
IBlockOperation Body { get; }
}
///
/// Represents creation of an object instance.
///
/// Current usage:
///
/// - C# new expression
/// - VB New expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IObjectCreationOperation : IOperation
{
///
/// Constructor to be invoked on the created instance.
///
IMethodSymbol? Constructor { get; }
///
/// Object or collection initializer, if any.
///
IObjectOrCollectionInitializerOperation? Initializer { get; }
///
/// Arguments of the object creation, excluding the instance argument. Arguments are in evaluation order.
///
///
/// If the invocation is in its expanded form, then params/ParamArray arguments would be collected into arrays.
/// Default values are supplied for optional arguments missing in source.
///
ImmutableArray Arguments { get; }
}
///
/// Represents a creation of a type parameter object, i.e. new T(), where T is a type parameter with new constraint.
///
/// Current usage:
///
/// - C# type parameter object creation expression
/// - VB type parameter object creation expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITypeParameterObjectCreationOperation : IOperation
{
///
/// Object or collection initializer, if any.
///
IObjectOrCollectionInitializerOperation? Initializer { get; }
}
///
/// Represents the creation of an array instance.
///
/// Current usage:
///
/// - C# array creation expression
/// - VB array creation expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IArrayCreationOperation : IOperation
{
///
/// Sizes of the dimensions of the created array instance.
///
ImmutableArray DimensionSizes { get; }
///
/// Values of elements of the created array instance.
///
IArrayInitializerOperation? Initializer { get; }
}
///
/// Represents an implicit/explicit reference to an instance.
///
/// Current usage:
///
/// - C# this or base expression
/// - VB Me, MyClass, or MyBase expression
/// - C# object or collection or 'with' expression initializers
/// - VB With statements, object or collection initializers
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInstanceReferenceOperation : IOperation
{
///
/// The kind of reference that is being made.
///
InstanceReferenceKind ReferenceKind { get; }
}
///
/// Represents an operation that tests if a value is of a specific type.
///
/// Current usage:
///
/// - C# "is" operator expression
/// - VB "TypeOf" and "TypeOf IsNot" expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IIsTypeOperation : IOperation
{
///
/// Value to test.
///
IOperation ValueOperand { get; }
///
/// Type for which to test.
///
ITypeSymbol TypeOperand { get; }
///
/// Flag indicating if this is an "is not" type expression.
/// True for VB "TypeOf ... IsNot ..." expression.
/// False, otherwise.
///
bool IsNegated { get; }
}
///
/// Represents an await operation.
///
/// Current usage:
///
/// - C# await expression
/// - VB await expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IAwaitOperation : IOperation
{
///
/// Awaited operation.
///
IOperation Operation { get; }
}
///
/// Represents a base interface for assignments.
///
/// Current usage:
///
/// - C# simple, compound and deconstruction assignment expressions
/// - VB simple and compound assignment expressions
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IAssignmentOperation : IOperation
{
///
/// Target of the assignment.
///
IOperation Target { get; }
///
/// Value to be assigned to the target of the assignment.
///
IOperation Value { get; }
}
///
/// Represents a simple assignment operation.
///
/// Current usage:
///
/// - C# simple assignment expression
/// - VB simple assignment expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISimpleAssignmentOperation : IAssignmentOperation
{
///
/// Is this a ref assignment
///
bool IsRef { get; }
}
///
/// Represents a compound assignment that mutates the target with the result of a binary operation.
///
/// Current usage:
///
/// - C# compound assignment expression
/// - VB compound assignment expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ICompoundAssignmentOperation : IAssignmentOperation
{
///
/// Conversion applied to before the operation occurs.
///
CommonConversion InConversion { get; }
///
/// Conversion applied to the result of the binary operation, before it is assigned back to
/// .
///
CommonConversion OutConversion { get; }
///
/// Kind of binary operation.
///
BinaryOperatorKind OperatorKind { get; }
///
/// if this assignment contains a 'lifted' binary operation.
///
bool IsLifted { get; }
///
/// if overflow checking is performed for the arithmetic operation.
///
bool IsChecked { get; }
///
/// Operator method used by the operation, null if the operation does not use an operator method.
///
IMethodSymbol? OperatorMethod { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the , if any.
/// Null if is resolved statically, or is null.
///
ITypeSymbol? ConstrainedToType { get; }
}
///
/// Represents a parenthesized operation.
///
/// Current usage:
///
/// - VB parenthesized expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IParenthesizedOperation : IOperation
{
///
/// Operand enclosed in parentheses.
///
IOperation Operand { get; }
}
///
/// Represents a binding of an event.
///
/// Current usage:
///
/// - C# event assignment expression
/// - VB Add/Remove handler statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IEventAssignmentOperation : IOperation
{
///
/// Reference to the event being bound.
///
IOperation EventReference { get; }
///
/// Handler supplied for the event.
///
IOperation HandlerValue { get; }
///
/// True for adding a binding, false for removing one.
///
bool Adds { get; }
}
///
/// Represents a conditionally accessed operation. Note that is used to refer to the value
/// of within .
///
/// Current usage:
///
/// - C# conditional access expression (? or ?. operator)
/// - VB conditional access expression (? or ?. operator)
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IConditionalAccessOperation : IOperation
{
///
/// Operation that will be evaluated and accessed if non null.
///
IOperation Operation { get; }
///
/// Operation to be evaluated if is non null.
///
IOperation WhenNotNull { get; }
}
///
/// Represents the value of a conditionally-accessed operation within .
/// For a conditional access operation of the form someExpr?.Member, this operation is used as the InstanceReceiver for the right operation Member.
/// See https://github.com/dotnet/roslyn/issues/21279#issuecomment-323153041 for more details.
///
/// Current usage:
///
/// - C# conditional access instance expression
/// - VB conditional access instance expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IConditionalAccessInstanceOperation : IOperation
{
}
///
/// Represents an interpolated string.
///
/// Current usage:
/// (1) C# interpolated string expression.
/// (2) VB interpolated string expression.
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringOperation : IOperation
{
///
/// Constituent parts of interpolated string, each of which is an .
///
ImmutableArray Parts { get; }
}
///
/// Represents a creation of anonymous object.
///
/// Current usage:
///
/// - C# new { ... } expression
/// - VB New With { ... } expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IAnonymousObjectCreationOperation : IOperation
{
///
/// Property initializers.
/// Each initializer is an , with an
/// as the target whose Instance is an with kind.
///
ImmutableArray Initializers { get; }
}
///
/// Represents an initialization for an object or collection creation.
///
/// Current usage:
///
/// -
///
/// C# object or collection initializer expression.
/// For example, object initializer { X = x } within object creation new Class() { X = x } and
/// collection initializer { x, y, 3 } within collection creation new MyList() { x, y, 3 }
///
///
/// - VB object or collection initializer expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IObjectOrCollectionInitializerOperation : IOperation
{
///
/// Object member or collection initializers.
///
ImmutableArray Initializers { get; }
}
///
/// Represents an initialization of member within an object initializer with a nested object or collection initializer.
///
/// Current usage:
///
/// -
///
/// C# nested member initializer expression.
/// For example, given an object creation with initializer new Class() { X = x, Y = { x, y, 3 }, Z = { X = z } },
/// member initializers for Y and Z, i.e. Y = { x, y, 3 }, and Z = { X = z } are nested member initializers represented by this operation
///
///
/// - VB object or collection initializer expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IMemberInitializerOperation : IOperation
{
///
/// Initialized member reference or an invalid operation for error cases.
///
IOperation InitializedMember { get; }
///
/// Member initializer.
///
IObjectOrCollectionInitializerOperation Initializer { get; }
}
///
/// Obsolete interface that used to represent a collection element initializer. It has been replaced by
/// and , as appropriate.
///
/// Current usage:
/// None. This API has been obsoleted in favor of and .
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
[Obsolete("ICollectionElementInitializerOperation has been replaced with " + nameof(IInvocationOperation) + " and " + nameof(IDynamicInvocationOperation), error: true)]
public interface ICollectionElementInitializerOperation : IOperation
{
IMethodSymbol AddMethod { get; }
ImmutableArray Arguments { get; }
bool IsDynamic { get; }
}
///
/// Represents an operation that gets a string value for the name.
///
/// Current usage:
///
/// - C# nameof expression
/// - VB NameOf expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface INameOfOperation : IOperation
{
///
/// Argument to the name of operation.
///
IOperation Argument { get; }
}
///
/// Represents a tuple with one or more elements.
///
/// Current usage:
///
/// - C# tuple expression
/// - VB tuple expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITupleOperation : IOperation
{
///
/// Tuple elements.
///
ImmutableArray Elements { get; }
///
/// Natural type of the tuple, or null if tuple doesn't have a natural type.
/// Natural type can be different from depending on the
/// conversion context, in which the tuple is used.
///
ITypeSymbol? NaturalType { get; }
}
///
/// Represents an object creation with a dynamically bound constructor.
///
/// Current usage:
///
/// - C# new expression with dynamic argument(s)
/// - VB late bound New expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDynamicObjectCreationOperation : IOperation
{
///
/// Object or collection initializer, if any.
///
IObjectOrCollectionInitializerOperation? Initializer { get; }
///
/// Dynamically bound arguments, excluding the instance argument.
///
ImmutableArray Arguments { get; }
}
///
/// Represents a reference to a member of a class, struct, or module that is dynamically bound.
///
/// Current usage:
///
/// - C# dynamic member reference expression
/// - VB late bound member reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDynamicMemberReferenceOperation : IOperation
{
///
/// Instance receiver, if it exists.
///
IOperation? Instance { get; }
///
/// Referenced member.
///
string MemberName { get; }
///
/// Type arguments.
///
ImmutableArray TypeArguments { get; }
///
/// The containing type of the referenced member, if different from type of the .
///
ITypeSymbol? ContainingType { get; }
}
///
/// Represents a invocation that is dynamically bound.
///
/// Current usage:
///
/// - C# dynamic invocation expression
/// -
///
/// C# dynamic collection element initializer.
/// For example, in the following collection initializer: new C() { do1, do2, do3 } where
/// the doX objects are of type dynamic, we'll have 3 with do1, do2, and
/// do3 as their arguments
///
///
/// - VB late bound invocation expression
/// -
///
/// VB dynamic collection element initializer.
/// Similar to the C# example, New C() From {do1, do2, do3} will generate 3
/// nodes with do1, do2, and do3 as their arguments, respectively
///
///
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDynamicInvocationOperation : IOperation
{
///
/// Dynamically or late bound operation.
///
IOperation Operation { get; }
///
/// Dynamically bound arguments, excluding the instance argument.
///
ImmutableArray Arguments { get; }
}
///
/// Represents an indexer access that is dynamically bound.
///
/// Current usage:
///
/// - C# dynamic indexer access expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDynamicIndexerAccessOperation : IOperation
{
///
/// Dynamically indexed operation.
///
IOperation Operation { get; }
///
/// Dynamically bound arguments, excluding the instance argument.
///
ImmutableArray Arguments { get; }
}
///
/// Represents an unrolled/lowered query operation.
/// For example, for a C# query expression "from x in set where x.Name != null select x.Name", the Operation tree has the following shape:
/// ITranslatedQueryExpression
/// IInvocationExpression ('Select' invocation for "select x.Name")
/// IInvocationExpression ('Where' invocation for "where x.Name != null")
/// IInvocationExpression ('From' invocation for "from x in set")
///
/// Current usage:
///
/// - C# query expression
/// - VB query expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITranslatedQueryOperation : IOperation
{
///
/// Underlying unrolled operation.
///
IOperation Operation { get; }
}
///
/// Represents a delegate creation. This is created whenever a new delegate is created.
///
/// Current usage:
///
/// - C# delegate creation expression
/// - VB delegate creation expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDelegateCreationOperation : IOperation
{
///
/// The lambda or method binding that this delegate is created from.
///
IOperation Target { get; }
}
///
/// Represents a default value operation.
///
/// Current usage:
///
/// - C# default value expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDefaultValueOperation : IOperation
{
}
///
/// Represents an operation that gets for the given .
///
/// Current usage:
///
/// - C# typeof expression
/// - VB GetType expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITypeOfOperation : IOperation
{
///
/// Type operand.
///
ITypeSymbol TypeOperand { get; }
}
///
/// Represents an operation to compute the size of a given type.
///
/// Current usage:
///
/// - C# sizeof expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISizeOfOperation : IOperation
{
///
/// Type operand.
///
ITypeSymbol TypeOperand { get; }
}
///
/// Represents an operation that creates a pointer value by taking the address of a reference.
///
/// Current usage:
///
/// - C# address of expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IAddressOfOperation : IOperation
{
///
/// Addressed reference.
///
IOperation Reference { get; }
}
///
/// Represents an operation that tests if a value matches a specific pattern.
///
/// Current usage:
///
/// - C# is pattern expression. For example, x is int i
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IIsPatternOperation : IOperation
{
///
/// Underlying operation to test.
///
IOperation Value { get; }
///
/// Pattern.
///
IPatternOperation Pattern { get; }
}
///
/// Represents an or operation.
/// Note that this operation is different from an as it mutates the ,
/// while unary operator expression does not mutate it's operand.
///
/// Current usage:
///
/// - C# increment expression or decrement expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IIncrementOrDecrementOperation : IOperation
{
///
/// if this is a postfix expression. if this is a prefix expression.
///
bool IsPostfix { get; }
///
/// if this is a 'lifted' increment operator. When there
/// is an operator that is defined to work on a value type, 'lifted' operators are
/// created to work on the versions of those
/// value types.
///
bool IsLifted { get; }
///
/// if overflow checking is performed for the arithmetic operation.
///
bool IsChecked { get; }
///
/// Target of the assignment.
///
IOperation Target { get; }
///
/// Operator method used by the operation, null if the operation does not use an operator method.
///
IMethodSymbol? OperatorMethod { get; }
///
/// Type parameter which runtime type will be used to resolve virtual invocation of the , if any.
/// Null if is resolved statically, or is null.
///
ITypeSymbol? ConstrainedToType { get; }
}
///
/// Represents an operation to throw an exception.
///
/// Current usage:
///
/// - C# throw expression
/// - C# throw statement
/// - VB Throw statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IThrowOperation : IOperation
{
///
/// Instance of an exception being thrown.
///
IOperation? Exception { get; }
}
///
/// Represents a assignment with a deconstruction.
///
/// Current usage:
///
/// - C# deconstruction assignment expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDeconstructionAssignmentOperation : IAssignmentOperation
{
}
///
/// Represents a declaration expression operation. Unlike a regular variable declaration and , this operation represents an "expression" declaring a variable.
///
/// Current usage:
///
/// -
///
/// C# deconstruction assignment expression. For example:
///
/// - var (x, y) is a deconstruction declaration expression with variables x and y
/// - (var x, var y) is a tuple expression with two declaration expressions
/// - M(out var x); is an invocation expression with an out var x declaration expression
///
///
///
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDeclarationExpressionOperation : IOperation
{
///
/// Underlying expression.
///
IOperation Expression { get; }
}
///
/// Represents an argument value that has been omitted in an invocation.
///
/// Current usage:
///
/// - VB omitted argument in an invocation expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IOmittedArgumentOperation : IOperation
{
}
///
/// Represents an initializer for a field, property, parameter or a local variable declaration.
///
/// Current usage:
///
/// - C# field, property, parameter or local variable initializer
/// - VB field(s), property, parameter or local variable initializer
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISymbolInitializerOperation : IOperation
{
///
/// Local declared in and scoped to the .
///
ImmutableArray Locals { get; }
///
/// Underlying initializer value.
///
IOperation Value { get; }
}
///
/// Represents an initialization of a field.
///
/// Current usage:
///
/// - C# field initializer with equals value clause
/// - VB field(s) initializer with equals value clause or AsNew clause. Multiple fields can be initialized with AsNew clause in VB
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IFieldInitializerOperation : ISymbolInitializerOperation
{
///
/// Initialized fields. There can be multiple fields for Visual Basic fields declared with AsNew clause.
///
ImmutableArray InitializedFields { get; }
}
///
/// Represents an initialization of a local variable.
///
/// Current usage:
///
/// - C# local variable initializer with equals value clause
/// - VB local variable initializer with equals value clause or AsNew clause
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IVariableInitializerOperation : ISymbolInitializerOperation
{
}
///
/// Represents an initialization of a property.
///
/// Current usage:
///
/// - C# property initializer with equals value clause
/// - VB property initializer with equals value clause or AsNew clause. Multiple properties can be initialized with 'WithEvents' declaration with AsNew clause in VB
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IPropertyInitializerOperation : ISymbolInitializerOperation
{
///
/// Initialized properties. There can be multiple properties for Visual Basic 'WithEvents' declaration with AsNew clause.
///
ImmutableArray InitializedProperties { get; }
}
///
/// Represents an initialization of a parameter at the point of declaration.
///
/// Current usage:
///
/// - C# parameter initializer with equals value clause
/// - VB parameter initializer with equals value clause
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IParameterInitializerOperation : ISymbolInitializerOperation
{
///
/// Initialized parameter.
///
IParameterSymbol Parameter { get; }
}
///
/// Represents the initialization of an array instance.
///
/// Current usage:
///
/// - C# array initializer
/// - VB array initializer
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IArrayInitializerOperation : IOperation
{
///
/// Values to initialize array elements.
///
ImmutableArray ElementValues { get; }
}
///
/// Represents a single variable declarator and initializer.
///
/// Current Usage:
///
/// - C# variable declarator
/// - C# catch variable declaration
/// - VB single variable declaration
/// - VB catch variable declaration
///
///
///
///
/// In VB, the initializer for this node is only ever used for explicit array bounds initializers. This node corresponds to
/// the VariableDeclaratorSyntax in C# and the ModifiedIdentifierSyntax in VB.
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IVariableDeclaratorOperation : IOperation
{
///
/// Symbol declared by this variable declaration
///
ILocalSymbol Symbol { get; }
///
/// Optional initializer of the variable.
///
///
/// If this variable is in an , the initializer may be located
/// in the parent operation. Call
/// to check in all locations. It is only possible to have initializers in both locations in VB invalid code scenarios.
///
IVariableInitializerOperation? Initializer { get; }
///
/// Additional arguments supplied to the declarator in error cases, ignored by the compiler. This only used for the C# case of
/// DeclaredArgumentSyntax nodes on a VariableDeclaratorSyntax.
///
ImmutableArray IgnoredArguments { get; }
}
///
/// Represents a declarator that declares multiple individual variables.
///
/// Current Usage:
///
/// - C# VariableDeclaration
/// - C# fixed declarations
/// - VB Dim statement declaration groups
/// - VB Using statement variable declarations
///
///
///
///
/// The initializer of this node is applied to all individual declarations in . There cannot
/// be initializers in both locations except in invalid code scenarios.
/// In C#, this node will never have an initializer.
/// This corresponds to the VariableDeclarationSyntax in C#, and the VariableDeclaratorSyntax in Visual Basic.
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IVariableDeclarationOperation : IOperation
{
///
/// Individual variable declarations declared by this multiple declaration.
///
///
/// All will have at least 1 ,
/// even if the declaration group only declares 1 variable.
///
ImmutableArray Declarators { get; }
///
/// Optional initializer of the variable.
///
///
/// In C#, this will always be null.
///
IVariableInitializerOperation? Initializer { get; }
///
/// Array dimensions supplied to an array declaration in error cases, ignored by the compiler. This is only used for the C# case of
/// RankSpecifierSyntax nodes on an ArrayTypeSyntax.
///
ImmutableArray IgnoredDimensions { get; }
}
///
/// Represents an argument to a method invocation.
///
/// Current usage:
///
/// - C# argument to an invocation expression, object creation expression, etc.
/// - VB argument to an invocation expression, object creation expression, etc.
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IArgumentOperation : IOperation
{
///
/// Kind of argument.
///
ArgumentKind ArgumentKind { get; }
///
/// Parameter the argument matches. This can be null for __arglist parameters.
///
IParameterSymbol? Parameter { get; }
///
/// Value supplied for the argument.
///
IOperation Value { get; }
///
/// Information of the conversion applied to the argument value passing it into the target method. Applicable only to VB Reference arguments.
///
CommonConversion InConversion { get; }
///
/// Information of the conversion applied to the argument value after the invocation. Applicable only to VB Reference arguments.
///
CommonConversion OutConversion { get; }
}
///
/// Represents a catch clause.
///
/// Current usage:
///
/// - C# catch clause
/// - VB Catch clause
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ICatchClauseOperation : IOperation
{
///
/// Optional source for exception. This could be any of the following operation:
/// 1. Declaration for the local catch variable bound to the caught exception (C# and VB) OR
/// 2. Null, indicating no declaration or expression (C# and VB)
/// 3. Reference to an existing local or parameter (VB) OR
/// 4. Other expression for error scenarios (VB)
///
IOperation? ExceptionDeclarationOrExpression { get; }
///
/// Type of the exception handled by the catch clause.
///
ITypeSymbol ExceptionType { get; }
///
/// Locals declared by the and/or clause.
///
ImmutableArray Locals { get; }
///
/// Filter operation to be executed to determine whether to handle the exception.
///
IOperation? Filter { get; }
///
/// Body of the exception handler.
///
IBlockOperation Handler { get; }
}
///
/// Represents a switch case section with one or more case clauses to match and one or more operations to execute within the section.
///
/// Current usage:
///
/// - C# switch section for one or more case clause and set of statements to execute
/// - VB case block with a case statement for one or more case clause and set of statements to execute
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISwitchCaseOperation : IOperation
{
///
/// Clauses of the case.
///
ImmutableArray Clauses { get; }
///
/// One or more operations to execute within the switch section.
///
ImmutableArray Body { get; }
///
/// Locals declared within the switch case section scoped to the section.
///
ImmutableArray Locals { get; }
}
///
/// Represents a case clause.
///
/// Current usage:
///
/// - C# case clause
/// - VB Case clause
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ICaseClauseOperation : IOperation
{
///
/// Kind of the clause.
///
CaseKind CaseKind { get; }
///
/// Label associated with the case clause, if any.
///
ILabelSymbol? Label { get; }
}
///
/// Represents a default case clause.
///
/// Current usage:
///
/// - C# default clause
/// - VB Case Else clause
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDefaultCaseClauseOperation : ICaseClauseOperation
{
}
///
/// Represents a case clause with a pattern and an optional guard operation.
///
/// Current usage:
/// (1) C# pattern case clause.
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IPatternCaseClauseOperation : ICaseClauseOperation
{
///
/// Label associated with the case clause.
///
new ILabelSymbol Label { get; }
///
/// Pattern associated with case clause.
///
IPatternOperation Pattern { get; }
///
/// Guard associated with the pattern case clause.
///
IOperation? Guard { get; }
}
///
/// Represents a case clause with range of values for comparison.
///
/// Current usage:
///
/// - VB range case clause of the form Case x To y
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IRangeCaseClauseOperation : ICaseClauseOperation
{
///
/// Minimum value of the case range.
///
IOperation MinimumValue { get; }
///
/// Maximum value of the case range.
///
IOperation MaximumValue { get; }
}
///
/// Represents a case clause with custom relational operator for comparison.
///
/// Current usage:
///
/// - VB relational case clause of the form Case Is op x
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IRelationalCaseClauseOperation : ICaseClauseOperation
{
///
/// Case value.
///
IOperation Value { get; }
///
/// Relational operator used to compare the switch value with the case value.
///
BinaryOperatorKind Relation { get; }
}
///
/// Represents a case clause with a single value for comparison.
///
/// Current usage:
///
/// - C# case clause of the form case x
/// - VB case clause of the form Case x
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISingleValueCaseClauseOperation : ICaseClauseOperation
{
///
/// Case value.
///
IOperation Value { get; }
}
///
/// Represents a constituent part of an interpolated string.
///
/// Current usage:
///
/// - C# interpolated string content
/// - VB interpolated string content
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringContentOperation : IOperation
{
}
///
/// Represents a constituent string literal part of an interpolated string operation.
///
/// Current usage:
///
/// - C# interpolated string text
/// - VB interpolated string text
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringTextOperation : IInterpolatedStringContentOperation
{
///
/// Text content.
///
IOperation Text { get; }
}
///
/// Represents a constituent interpolation part of an interpolated string operation.
///
/// Current usage:
///
/// - C# interpolation part
/// - VB interpolation part
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolationOperation : IInterpolatedStringContentOperation
{
///
/// Expression of the interpolation.
///
IOperation Expression { get; }
///
/// Optional alignment of the interpolation.
///
IOperation? Alignment { get; }
///
/// Optional format string of the interpolation.
///
IOperation? FormatString { get; }
}
///
/// Represents a pattern matching operation.
///
/// Current usage:
///
/// - C# pattern
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IPatternOperation : IOperation
{
///
/// The input type to the pattern-matching operation.
///
ITypeSymbol InputType { get; }
///
/// The narrowed type of the pattern-matching operation.
///
ITypeSymbol NarrowedType { get; }
}
///
/// Represents a pattern with a constant value.
///
/// Current usage:
///
/// - C# constant pattern
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IConstantPatternOperation : IPatternOperation
{
///
/// Constant value of the pattern operation.
///
IOperation Value { get; }
}
///
/// Represents a pattern that declares a symbol.
///
/// Current usage:
///
/// - C# declaration pattern
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDeclarationPatternOperation : IPatternOperation
{
///
/// The type explicitly specified, or null if it was inferred (e.g. using in C#).
///
ITypeSymbol? MatchedType { get; }
///
/// True if the pattern is of a form that accepts null.
/// For example, in C# the pattern `var x` will match a null input,
/// while the pattern `string x` will not.
///
bool MatchesNull { get; }
///
/// Symbol declared by the pattern, if any.
///
ISymbol? DeclaredSymbol { get; }
}
///
/// Represents a comparison of two operands that returns a bool type.
///
/// Current usage:
///
/// - C# tuple binary operator expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITupleBinaryOperation : IOperation
{
///
/// Kind of binary operation.
///
BinaryOperatorKind OperatorKind { get; }
///
/// Left operand.
///
IOperation LeftOperand { get; }
///
/// Right operand.
///
IOperation RightOperand { get; }
}
///
/// Represents a method body operation.
///
/// Current usage:
///
/// - C# method body
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IMethodBodyBaseOperation : IOperation
{
///
/// Method body corresponding to BaseMethodDeclarationSyntax.Body or AccessorDeclarationSyntax.Body
///
IBlockOperation? BlockBody { get; }
///
/// Method body corresponding to BaseMethodDeclarationSyntax.ExpressionBody or AccessorDeclarationSyntax.ExpressionBody
///
IBlockOperation? ExpressionBody { get; }
}
///
/// Represents a method body operation.
///
/// Current usage:
///
/// - C# method body for non-constructor
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IMethodBodyOperation : IMethodBodyBaseOperation
{
}
///
/// Represents a constructor method body operation.
///
/// Current usage:
///
/// - C# method body for constructor declaration
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IConstructorBodyOperation : IMethodBodyBaseOperation
{
///
/// Local declarations contained within the .
///
ImmutableArray Locals { get; }
///
/// Constructor initializer, if any.
///
IOperation? Initializer { get; }
}
///
/// Represents a discard operation.
///
/// Current usage:
///
/// - C# discard expressions
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDiscardOperation : IOperation
{
///
/// The symbol of the discard operation.
///
IDiscardSymbol DiscardSymbol { get; }
}
///
/// Represents a coalesce assignment operation with a target and a conditionally-evaluated value:
///
/// - is evaluated for null. If it is null, is evaluated and assigned to target
/// - is conditionally evaluated if is null, and the result is assigned into
///
/// The result of the entire expression is , which is only evaluated once.
///
/// Current usage:
///
/// - C# null-coalescing assignment operation Target ??= Value
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ICoalesceAssignmentOperation : IAssignmentOperation
{
}
///
/// Represents a range operation.
///
/// Current usage:
///
/// - C# range expressions
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IRangeOperation : IOperation
{
///
/// Left operand.
///
IOperation? LeftOperand { get; }
///
/// Right operand.
///
IOperation? RightOperand { get; }
///
/// if this is a 'lifted' range operation. When there is an
/// operator that is defined to work on a value type, 'lifted' operators are
/// created to work on the versions of those
/// value types.
///
bool IsLifted { get; }
///
/// Factory method used to create this Range value. Can be null if appropriate
/// symbol was not found.
///
IMethodSymbol? Method { get; }
}
///
/// Represents the ReDim operation to re-allocate storage space for array variables.
///
/// Current usage:
///
/// - VB ReDim statement
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IReDimOperation : IOperation
{
///
/// Individual clauses of the ReDim operation.
///
ImmutableArray Clauses { get; }
///
/// Modifier used to preserve the data in the existing array when you change the size of only the last dimension.
///
bool Preserve { get; }
}
///
/// Represents an individual clause of an to re-allocate storage space for a single array variable.
///
/// Current usage:
///
/// - VB ReDim clause
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IReDimClauseOperation : IOperation
{
///
/// Operand whose storage space needs to be re-allocated.
///
IOperation Operand { get; }
///
/// Sizes of the dimensions of the created array instance.
///
ImmutableArray DimensionSizes { get; }
}
///
/// Represents a C# recursive pattern.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IRecursivePatternOperation : IPatternOperation
{
///
/// The type accepted for the recursive pattern.
///
ITypeSymbol MatchedType { get; }
///
/// The symbol, if any, used for the fetching values for subpatterns. This is either a Deconstruct
/// method, the type System.Runtime.CompilerServices.ITuple, or null (for example, in
/// error cases or when matching a tuple type).
///
ISymbol? DeconstructSymbol { get; }
///
/// This contains the patterns contained within a deconstruction or positional subpattern.
///
ImmutableArray DeconstructionSubpatterns { get; }
///
/// This contains the (symbol, property) pairs within a property subpattern.
///
ImmutableArray PropertySubpatterns { get; }
///
/// Symbol declared by the pattern.
///
ISymbol? DeclaredSymbol { get; }
}
///
/// Represents a discard pattern.
///
/// Current usage:
///
/// - C# discard pattern
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IDiscardPatternOperation : IPatternOperation
{
}
///
/// Represents a switch expression.
///
/// Current usage:
///
/// - C# switch expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISwitchExpressionOperation : IOperation
{
///
/// Value to be switched upon.
///
IOperation Value { get; }
///
/// Arms of the switch expression.
///
ImmutableArray Arms { get; }
///
/// True if the switch expressions arms cover every possible input value.
///
bool IsExhaustive { get; }
}
///
/// Represents one arm of a switch expression.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISwitchExpressionArmOperation : IOperation
{
///
/// The pattern to match.
///
IPatternOperation Pattern { get; }
///
/// Guard (when clause expression) associated with the switch arm, if any.
///
IOperation? Guard { get; }
///
/// Result value of the enclosing switch expression when this arm matches.
///
IOperation Value { get; }
///
/// Locals declared within the switch arm (e.g. pattern locals and locals declared in the guard) scoped to the arm.
///
ImmutableArray Locals { get; }
}
///
/// Represents an element of a property subpattern, which identifies a member to be matched and the
/// pattern to match it against.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IPropertySubpatternOperation : IOperation
{
///
/// The member being matched in a property subpattern. This can be a
/// in non-error cases, or an in error cases.
///
IOperation Member { get; }
///
/// The pattern to which the member is matched in a property subpattern.
///
IPatternOperation Pattern { get; }
}
///
/// Represents a standalone VB query Aggregate operation with more than one item in Into clause.
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
internal interface IAggregateQueryOperation : IOperation
{
IOperation Group { get; }
IOperation Aggregation { get; }
}
///
/// Represents a C# fixed statement.
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
internal interface IFixedOperation : IOperation
{
///
/// Locals declared.
///
ImmutableArray Locals { get; }
///
/// Variables to be fixed.
///
IVariableDeclarationGroupOperation Variables { get; }
///
/// Body of the fixed, over which the variables are fixed.
///
IOperation Body { get; }
}
///
/// Represents a creation of an instance of a NoPia interface, i.e. new I(), where I is an embedded NoPia interface.
///
/// Current usage:
///
/// - C# NoPia interface instance creation expression
/// - VB NoPia interface instance creation expression
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
internal interface INoPiaObjectCreationOperation : IOperation
{
///
/// Object or collection initializer, if any.
///
IObjectOrCollectionInitializerOperation? Initializer { get; }
}
///
/// Represents a general placeholder when no more specific kind of placeholder is available.
/// A placeholder is an expression whose meaning is inferred from context.
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
internal interface IPlaceholderOperation : IOperation
{
PlaceholderKind PlaceholderKind { get; }
}
///
/// Represents a reference through a pointer.
///
/// Current usage:
///
/// - C# pointer indirection reference expression
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
internal interface IPointerIndirectionReferenceOperation : IOperation
{
///
/// Pointer to be dereferenced.
///
IOperation Pointer { get; }
}
///
/// Represents a of operations that are executed with implicit reference to the for member references.
///
/// Current usage:
///
/// - VB With statement
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
internal interface IWithStatementOperation : IOperation
{
///
/// Body of the with.
///
IOperation Body { get; }
///
/// Value to whose members leading-dot-qualified references within the with body bind.
///
IOperation Value { get; }
}
///
/// Represents using variable declaration, with scope spanning across the parent .
///
/// Current Usage:
///
/// - C# using declaration
/// - C# asynchronous using declaration
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IUsingDeclarationOperation : IOperation
{
///
/// The variables declared by this using declaration.
///
IVariableDeclarationGroupOperation DeclarationGroup { get; }
///
/// True if this is an asynchronous using declaration.
///
bool IsAsynchronous { get; }
}
///
/// Represents a negated pattern.
///
/// Current usage:
///
/// - C# negated pattern
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface INegatedPatternOperation : IPatternOperation
{
///
/// The negated pattern.
///
IPatternOperation Pattern { get; }
}
///
/// Represents a binary ("and" or "or") pattern.
///
/// Current usage:
///
/// - C# "and" and "or" patterns
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IBinaryPatternOperation : IPatternOperation
{
///
/// Kind of binary pattern; either or .
///
BinaryOperatorKind OperatorKind { get; }
///
/// The pattern on the left.
///
IPatternOperation LeftPattern { get; }
///
/// The pattern on the right.
///
IPatternOperation RightPattern { get; }
}
///
/// Represents a pattern comparing the input with a given type.
///
/// Current usage:
///
/// - C# type pattern
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ITypePatternOperation : IPatternOperation
{
///
/// The type explicitly specified, or null if it was inferred (e.g. using in C#).
///
ITypeSymbol MatchedType { get; }
}
///
/// Represents a pattern comparing the input with a constant value using a relational operator.
///
/// Current usage:
///
/// - C# relational pattern
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IRelationalPatternOperation : IPatternOperation
{
///
/// The kind of the relational operator.
///
BinaryOperatorKind OperatorKind { get; }
///
/// Constant value of the pattern operation.
///
IOperation Value { get; }
}
///
/// Represents cloning of an object instance.
///
/// Current usage:
///
/// - C# with expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IWithOperation : IOperation
{
///
/// Operand to be cloned.
///
IOperation Operand { get; }
///
/// Clone method to be invoked on the value. This can be null in error scenarios.
///
IMethodSymbol? CloneMethod { get; }
///
/// With collection initializer.
///
IObjectOrCollectionInitializerOperation Initializer { get; }
}
///
/// Represents an interpolated string converted to a custom interpolated string handler type.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringHandlerCreationOperation : IOperation
{
///
/// The construction of the interpolated string handler instance. This can be an for valid code, and
/// or for invalid code.
///
IOperation HandlerCreation { get; }
///
/// True if the last parameter of is an out parameter that will be checked before executing the code in
/// . False otherwise.
///
bool HandlerCreationHasSuccessParameter { get; }
///
/// True if the AppendLiteral or AppendFormatted calls in nested return . When that is true, each part
/// will be conditional on the return of the part before it, only being executed when the Append call returns true. False otherwise.
///
///
/// when this is true and is true, then the first part in nested is conditionally
/// run. If this is true and is false, then the first part is unconditionally run.
///
/// Just because this is true or false does not guarantee that all Append calls actually do return boolean values, as there could be dynamic calls or errors.
/// It only governs what the compiler was expecting, based on the first calls it did see.
///
bool HandlerAppendCallsReturnBool { get; }
///
/// The interpolated string expression or addition operation that makes up the content of this string. This is either an
/// or an operation.
///
IOperation Content { get; }
}
///
/// Represents an addition of multiple interpolated string literals being converted to an interpolated string handler type.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringAdditionOperation : IOperation
{
///
/// The interpolated string expression or addition operation on the left side of the operator. This is either an
/// or an operation.
///
IOperation Left { get; }
///
/// The interpolated string expression or addition operation on the right side of the operator. This is either an
/// or an operation.
///
IOperation Right { get; }
}
///
/// Represents a call to either AppendLiteral or AppendFormatted as part of an interpolated string handler conversion.
///
///
/// This node is associated with the following operation kinds:
///
///
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringAppendOperation : IInterpolatedStringContentOperation
{
///
/// If this interpolated string is subject to an interpolated string handler conversion, the construction of the interpolated string handler instance.
/// This can be an or for valid code, and for invalid code.
///
IOperation AppendCall { get; }
}
///
/// Represents an argument from the method call, indexer access, or constructor invocation that is creating the containing
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInterpolatedStringHandlerArgumentPlaceholderOperation : IOperation
{
///
/// The index of the argument of the method call, indexer, or object creation containing the interpolated string handler conversion this placeholder is referencing.
/// -1 if is anything other than .
///
int ArgumentIndex { get; }
///
/// The component this placeholder represents.
///
InterpolatedStringArgumentPlaceholderKind PlaceholderKind { get; }
}
///
/// Represents an invocation of a function pointer.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IFunctionPointerInvocationOperation : IOperation
{
///
/// Invoked pointer.
///
IOperation Target { get; }
///
/// Arguments of the invocation. Arguments are in evaluation order.
///
ImmutableArray Arguments { get; }
}
///
/// Represents a C# list pattern.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IListPatternOperation : IPatternOperation
{
///
/// The Length or Count property that is used to fetch the length value.
/// Returns null if no such property is found.
///
ISymbol? LengthSymbol { get; }
///
/// The indexer that is used to fetch elements.
/// Returns null for an array input.
///
ISymbol? IndexerSymbol { get; }
///
/// Returns subpatterns contained within the list pattern.
///
ImmutableArray Patterns { get; }
///
/// Symbol declared by the pattern, if any.
///
ISymbol? DeclaredSymbol { get; }
}
///
/// Represents a C# slice pattern.
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISlicePatternOperation : IPatternOperation
{
///
/// The range indexer or the Slice method used to fetch the slice value.
///
ISymbol? SliceSymbol { get; }
///
/// The pattern that the slice value is matched with, if any.
///
IPatternOperation? Pattern { get; }
}
///
/// Represents a reference to an implicit System.Index or System.Range indexer over a non-array type.
///
/// Current usage:
///
/// - C# implicit System.Index or System.Range indexer reference expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IImplicitIndexerReferenceOperation : IOperation
{
///
/// Instance of the type to be indexed.
///
IOperation Instance { get; }
///
/// System.Index or System.Range value.
///
IOperation Argument { get; }
///
/// The Length or Count property that might be used to fetch the length value.
///
ISymbol LengthSymbol { get; }
///
/// Symbol for the underlying indexer or a slice method that is used to implement the implicit indexer.
///
ISymbol IndexerSymbol { get; }
}
///
/// Represents a UTF-8 encoded byte representation of a string.
///
/// Current usage:
///
/// - C# UTF-8 string literal expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IUtf8StringOperation : IOperation
{
///
/// The underlying string value.
///
string Value { get; }
}
///
/// Represents the application of an attribute.
///
/// Current usage:
///
/// - C# attribute application
/// - VB attribute application
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IAttributeOperation : IOperation
{
///
/// The operation representing the attribute. This can be a in non-error cases, or an in error cases.
///
IOperation Operation { get; }
}
///
/// Represents an element reference or a slice operation over an inline array type.
///
/// Current usage:
///
/// - C# inline array access
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface IInlineArrayAccessOperation : IOperation
{
///
/// Instance of the inline array type to be accessed.
///
IOperation Instance { get; }
///
/// System.Int32, System.Index or System.Range value.
///
IOperation Argument { get; }
}
///
/// Represents a collection expression.
///
/// Current usage:
///
/// - C# collection expression
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ICollectionExpressionOperation : IOperation
{
///
/// Method used to construct the collection.
///
/// If the collection type is an array, span, array interface, or type parameter, the method is null;
/// if the collection type has a [CollectionBuilder] attribute, the method is the builder method;
/// otherwise, the method is the collection type constructor.
///
///
IMethodSymbol? ConstructMethod { get; }
///
/// Collection expression elements.
///
/// If the element is an expression, the entry is the expression, with a conversion to
/// the target element type if necessary;
/// otherwise, the entry is an ISpreadOperation.
///
///
ImmutableArray Elements { get; }
}
///
/// Represents a collection expression spread element.
///
/// Current usage:
///
/// - C# spread element
///
///
///
///
/// This node is associated with the following operation kinds:
///
///
///
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
///
public interface ISpreadOperation : IOperation
{
///
/// Collection being spread.
///
IOperation Operand { get; }
///
/// Type of the elements in the collection.
///
ITypeSymbol? ElementType { get; }
///
/// Conversion from the type of the collection element to the target element type
/// of the containing collection expression.
///
CommonConversion ElementConversion { get; }
}
#endregion
#region Implementations
internal sealed partial class BlockOperation : Operation, IBlockOperation
{
internal BlockOperation(ImmutableArray operations, ImmutableArray locals, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operations = SetParentOperation(operations, this);
Locals = locals;
}
public ImmutableArray Operations { get; }
public ImmutableArray Locals { get; }
internal override int ChildOperationsCount =>
Operations.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Operations.Length
=> Operations[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Operations.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Operations.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Operations.IsEmpty) return (true, 0, Operations.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Block;
public override void Accept(OperationVisitor visitor) => visitor.VisitBlock(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitBlock(this, argument);
}
internal sealed partial class VariableDeclarationGroupOperation : Operation, IVariableDeclarationGroupOperation
{
internal VariableDeclarationGroupOperation(ImmutableArray declarations, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Declarations = SetParentOperation(declarations, this);
}
public ImmutableArray Declarations { get; }
internal override int ChildOperationsCount =>
Declarations.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Declarations.Length
=> Declarations[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Declarations.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Declarations.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Declarations.IsEmpty) return (true, 0, Declarations.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.VariableDeclarationGroup;
public override void Accept(OperationVisitor visitor) => visitor.VisitVariableDeclarationGroup(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitVariableDeclarationGroup(this, argument);
}
internal sealed partial class SwitchOperation : Operation, ISwitchOperation
{
internal SwitchOperation(ImmutableArray locals, IOperation value, ImmutableArray cases, ILabelSymbol exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Locals = locals;
Value = SetParentOperation(value, this);
Cases = SetParentOperation(cases, this);
ExitLabel = exitLabel;
}
public ImmutableArray Locals { get; }
public IOperation Value { get; }
public ImmutableArray Cases { get; }
public ILabelSymbol ExitLabel { get; }
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1) +
Cases.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
1 when index < Cases.Length
=> Cases[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
if (!Cases.IsEmpty) return (true, 1, 0);
else goto case 1;
case 1 when previousIndex + 1 < Cases.Length:
return (true, 1, previousIndex + 1);
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Cases.IsEmpty) return (true, 1, Cases.Length - 1);
else goto case 1;
case 1 when previousIndex > 0:
return (true, 1, previousIndex - 1);
case 1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Switch;
public override void Accept(OperationVisitor visitor) => visitor.VisitSwitch(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitSwitch(this, argument);
}
internal abstract partial class BaseLoopOperation : Operation, ILoopOperation
{
protected BaseLoopOperation(IOperation body, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Body = SetParentOperation(body, this);
Locals = locals;
ContinueLabel = continueLabel;
ExitLabel = exitLabel;
}
public abstract LoopKind LoopKind { get; }
public IOperation Body { get; }
public ImmutableArray Locals { get; }
public ILabelSymbol ContinueLabel { get; }
public ILabelSymbol ExitLabel { get; }
}
internal sealed partial class ForEachLoopOperation : BaseLoopOperation, IForEachLoopOperation
{
internal ForEachLoopOperation(IOperation loopControlVariable, IOperation collection, ImmutableArray nextVariables, ForEachLoopOperationInfo? info, bool isAsynchronous, IOperation body, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(body, locals, continueLabel, exitLabel, semanticModel, syntax, isImplicit)
{
LoopControlVariable = SetParentOperation(loopControlVariable, this);
Collection = SetParentOperation(collection, this);
NextVariables = SetParentOperation(nextVariables, this);
Info = info;
IsAsynchronous = isAsynchronous;
}
public IOperation LoopControlVariable { get; }
public IOperation Collection { get; }
public ImmutableArray NextVariables { get; }
public ForEachLoopOperationInfo? Info { get; }
public bool IsAsynchronous { get; }
internal override int ChildOperationsCount =>
(LoopControlVariable is null ? 0 : 1) +
(Collection is null ? 0 : 1) +
NextVariables.Length +
(Body is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Collection != null
=> Collection,
1 when LoopControlVariable != null
=> LoopControlVariable,
2 when Body != null
=> Body,
3 when index < NextVariables.Length
=> NextVariables[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Collection != null) return (true, 0, 0);
else goto case 0;
case 0:
if (LoopControlVariable != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Body != null) return (true, 2, 0);
else goto case 2;
case 2:
if (!NextVariables.IsEmpty) return (true, 3, 0);
else goto case 3;
case 3 when previousIndex + 1 < NextVariables.Length:
return (true, 3, previousIndex + 1);
case 3:
case 4:
return (false, 4, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!NextVariables.IsEmpty) return (true, 3, NextVariables.Length - 1);
else goto case 3;
case 3 when previousIndex > 0:
return (true, 3, previousIndex - 1);
case 3:
if (Body != null) return (true, 2, 0);
else goto case 2;
case 2:
if (LoopControlVariable != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Collection != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Loop;
public override void Accept(OperationVisitor visitor) => visitor.VisitForEachLoop(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitForEachLoop(this, argument);
}
internal sealed partial class ForLoopOperation : BaseLoopOperation, IForLoopOperation
{
internal ForLoopOperation(ImmutableArray before, ImmutableArray conditionLocals, IOperation? condition, ImmutableArray atLoopBottom, IOperation body, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(body, locals, continueLabel, exitLabel, semanticModel, syntax, isImplicit)
{
Before = SetParentOperation(before, this);
ConditionLocals = conditionLocals;
Condition = SetParentOperation(condition, this);
AtLoopBottom = SetParentOperation(atLoopBottom, this);
}
public ImmutableArray Before { get; }
public ImmutableArray ConditionLocals { get; }
public IOperation? Condition { get; }
public ImmutableArray AtLoopBottom { get; }
internal override int ChildOperationsCount =>
Before.Length +
(Condition is null ? 0 : 1) +
AtLoopBottom.Length +
(Body is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Before.Length
=> Before[index],
1 when Condition != null
=> Condition,
2 when Body != null
=> Body,
3 when index < AtLoopBottom.Length
=> AtLoopBottom[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Before.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Before.Length:
return (true, 0, previousIndex + 1);
case 0:
if (Condition != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Body != null) return (true, 2, 0);
else goto case 2;
case 2:
if (!AtLoopBottom.IsEmpty) return (true, 3, 0);
else goto case 3;
case 3 when previousIndex + 1 < AtLoopBottom.Length:
return (true, 3, previousIndex + 1);
case 3:
case 4:
return (false, 4, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!AtLoopBottom.IsEmpty) return (true, 3, AtLoopBottom.Length - 1);
else goto case 3;
case 3 when previousIndex > 0:
return (true, 3, previousIndex - 1);
case 3:
if (Body != null) return (true, 2, 0);
else goto case 2;
case 2:
if (Condition != null) return (true, 1, 0);
else goto case 1;
case 1:
if (!Before.IsEmpty) return (true, 0, Before.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Loop;
public override void Accept(OperationVisitor visitor) => visitor.VisitForLoop(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitForLoop(this, argument);
}
internal sealed partial class ForToLoopOperation : BaseLoopOperation, IForToLoopOperation
{
internal ForToLoopOperation(IOperation loopControlVariable, IOperation initialValue, IOperation limitValue, IOperation stepValue, bool isChecked, ImmutableArray nextVariables, (ILocalSymbol LoopObject, ForToLoopOperationUserDefinedInfo UserDefinedInfo) info, IOperation body, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(body, locals, continueLabel, exitLabel, semanticModel, syntax, isImplicit)
{
LoopControlVariable = SetParentOperation(loopControlVariable, this);
InitialValue = SetParentOperation(initialValue, this);
LimitValue = SetParentOperation(limitValue, this);
StepValue = SetParentOperation(stepValue, this);
IsChecked = isChecked;
NextVariables = SetParentOperation(nextVariables, this);
Info = info;
}
public IOperation LoopControlVariable { get; }
public IOperation InitialValue { get; }
public IOperation LimitValue { get; }
public IOperation StepValue { get; }
public bool IsChecked { get; }
public ImmutableArray NextVariables { get; }
public (ILocalSymbol LoopObject, ForToLoopOperationUserDefinedInfo UserDefinedInfo) Info { get; }
internal override int ChildOperationsCount =>
(LoopControlVariable is null ? 0 : 1) +
(InitialValue is null ? 0 : 1) +
(LimitValue is null ? 0 : 1) +
(StepValue is null ? 0 : 1) +
NextVariables.Length +
(Body is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when LoopControlVariable != null
=> LoopControlVariable,
1 when InitialValue != null
=> InitialValue,
2 when LimitValue != null
=> LimitValue,
3 when StepValue != null
=> StepValue,
4 when Body != null
=> Body,
5 when index < NextVariables.Length
=> NextVariables[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (LoopControlVariable != null) return (true, 0, 0);
else goto case 0;
case 0:
if (InitialValue != null) return (true, 1, 0);
else goto case 1;
case 1:
if (LimitValue != null) return (true, 2, 0);
else goto case 2;
case 2:
if (StepValue != null) return (true, 3, 0);
else goto case 3;
case 3:
if (Body != null) return (true, 4, 0);
else goto case 4;
case 4:
if (!NextVariables.IsEmpty) return (true, 5, 0);
else goto case 5;
case 5 when previousIndex + 1 < NextVariables.Length:
return (true, 5, previousIndex + 1);
case 5:
case 6:
return (false, 6, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!NextVariables.IsEmpty) return (true, 5, NextVariables.Length - 1);
else goto case 5;
case 5 when previousIndex > 0:
return (true, 5, previousIndex - 1);
case 5:
if (Body != null) return (true, 4, 0);
else goto case 4;
case 4:
if (StepValue != null) return (true, 3, 0);
else goto case 3;
case 3:
if (LimitValue != null) return (true, 2, 0);
else goto case 2;
case 2:
if (InitialValue != null) return (true, 1, 0);
else goto case 1;
case 1:
if (LoopControlVariable != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Loop;
public override void Accept(OperationVisitor visitor) => visitor.VisitForToLoop(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitForToLoop(this, argument);
}
internal sealed partial class WhileLoopOperation : BaseLoopOperation, IWhileLoopOperation
{
internal WhileLoopOperation(IOperation? condition, bool conditionIsTop, bool conditionIsUntil, IOperation? ignoredCondition, IOperation body, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(body, locals, continueLabel, exitLabel, semanticModel, syntax, isImplicit)
{
Condition = SetParentOperation(condition, this);
ConditionIsTop = conditionIsTop;
ConditionIsUntil = conditionIsUntil;
IgnoredCondition = SetParentOperation(ignoredCondition, this);
}
public IOperation? Condition { get; }
public bool ConditionIsTop { get; }
public bool ConditionIsUntil { get; }
public IOperation? IgnoredCondition { get; }
internal override int ChildOperationsCount =>
(Condition is null ? 0 : 1) +
(IgnoredCondition is null ? 0 : 1) +
(Body is null ? 0 : 1);
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Loop;
public override void Accept(OperationVisitor visitor) => visitor.VisitWhileLoop(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitWhileLoop(this, argument);
}
internal sealed partial class LabeledOperation : Operation, ILabeledOperation
{
internal LabeledOperation(ILabelSymbol label, IOperation? operation, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Label = label;
Operation = SetParentOperation(operation, this);
}
public ILabelSymbol Label { get; }
public IOperation? Operation { get; }
internal override int ChildOperationsCount =>
(Operation is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operation != null
=> Operation,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Labeled;
public override void Accept(OperationVisitor visitor) => visitor.VisitLabeled(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitLabeled(this, argument);
}
internal sealed partial class BranchOperation : Operation, IBranchOperation
{
internal BranchOperation(ILabelSymbol target, BranchKind branchKind, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Target = target;
BranchKind = branchKind;
}
public ILabelSymbol Target { get; }
public BranchKind BranchKind { get; }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Branch;
public override void Accept(OperationVisitor visitor) => visitor.VisitBranch(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitBranch(this, argument);
}
internal sealed partial class EmptyOperation : Operation, IEmptyOperation
{
internal EmptyOperation(SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit) { }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Empty;
public override void Accept(OperationVisitor visitor) => visitor.VisitEmpty(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitEmpty(this, argument);
}
internal sealed partial class ReturnOperation : Operation, IReturnOperation
{
internal ReturnOperation(IOperation? returnedValue, OperationKind kind, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
ReturnedValue = SetParentOperation(returnedValue, this);
Kind = kind;
}
public IOperation? ReturnedValue { get; }
internal override int ChildOperationsCount =>
(ReturnedValue is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when ReturnedValue != null
=> ReturnedValue,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (ReturnedValue != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (ReturnedValue != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind { get; }
public override void Accept(OperationVisitor visitor) => visitor.VisitReturn(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitReturn(this, argument);
}
internal sealed partial class LockOperation : Operation, ILockOperation
{
internal LockOperation(IOperation lockedValue, IOperation body, ILocalSymbol? lockTakenSymbol, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
LockedValue = SetParentOperation(lockedValue, this);
Body = SetParentOperation(body, this);
LockTakenSymbol = lockTakenSymbol;
}
public IOperation LockedValue { get; }
public IOperation Body { get; }
public ILocalSymbol? LockTakenSymbol { get; }
internal override int ChildOperationsCount =>
(LockedValue is null ? 0 : 1) +
(Body is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when LockedValue != null
=> LockedValue,
1 when Body != null
=> Body,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (LockedValue != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Body != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Body != null) return (true, 1, 0);
else goto case 1;
case 1:
if (LockedValue != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Lock;
public override void Accept(OperationVisitor visitor) => visitor.VisitLock(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitLock(this, argument);
}
internal sealed partial class TryOperation : Operation, ITryOperation
{
internal TryOperation(IBlockOperation body, ImmutableArray catches, IBlockOperation? @finally, ILabelSymbol? exitLabel, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Body = SetParentOperation(body, this);
Catches = SetParentOperation(catches, this);
Finally = SetParentOperation(@finally, this);
ExitLabel = exitLabel;
}
public IBlockOperation Body { get; }
public ImmutableArray Catches { get; }
public IBlockOperation? Finally { get; }
public ILabelSymbol? ExitLabel { get; }
internal override int ChildOperationsCount =>
(Body is null ? 0 : 1) +
Catches.Length +
(Finally is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Body != null
=> Body,
1 when index < Catches.Length
=> Catches[index],
2 when Finally != null
=> Finally,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Body != null) return (true, 0, 0);
else goto case 0;
case 0:
if (!Catches.IsEmpty) return (true, 1, 0);
else goto case 1;
case 1 when previousIndex + 1 < Catches.Length:
return (true, 1, previousIndex + 1);
case 1:
if (Finally != null) return (true, 2, 0);
else goto case 2;
case 2:
case 3:
return (false, 3, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Finally != null) return (true, 2, 0);
else goto case 2;
case 2:
if (!Catches.IsEmpty) return (true, 1, Catches.Length - 1);
else goto case 1;
case 1 when previousIndex > 0:
return (true, 1, previousIndex - 1);
case 1:
if (Body != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Try;
public override void Accept(OperationVisitor visitor) => visitor.VisitTry(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitTry(this, argument);
}
internal sealed partial class UsingOperation : Operation, IUsingOperation
{
internal UsingOperation(IOperation resources, IOperation body, ImmutableArray locals, bool isAsynchronous, DisposeOperationInfo disposeInfo, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Resources = SetParentOperation(resources, this);
Body = SetParentOperation(body, this);
Locals = locals;
IsAsynchronous = isAsynchronous;
DisposeInfo = disposeInfo;
}
public IOperation Resources { get; }
public IOperation Body { get; }
public ImmutableArray Locals { get; }
public bool IsAsynchronous { get; }
public DisposeOperationInfo DisposeInfo { get; }
internal override int ChildOperationsCount =>
(Resources is null ? 0 : 1) +
(Body is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Resources != null
=> Resources,
1 when Body != null
=> Body,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Resources != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Body != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Body != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Resources != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Using;
public override void Accept(OperationVisitor visitor) => visitor.VisitUsing(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitUsing(this, argument);
}
internal sealed partial class ExpressionStatementOperation : Operation, IExpressionStatementOperation
{
internal ExpressionStatementOperation(IOperation operation, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operation = SetParentOperation(operation, this);
}
public IOperation Operation { get; }
internal override int ChildOperationsCount =>
(Operation is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operation != null
=> Operation,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ExpressionStatement;
public override void Accept(OperationVisitor visitor) => visitor.VisitExpressionStatement(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitExpressionStatement(this, argument);
}
internal sealed partial class LocalFunctionOperation : Operation, ILocalFunctionOperation
{
internal LocalFunctionOperation(IMethodSymbol symbol, IBlockOperation? body, IBlockOperation? ignoredBody, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Symbol = symbol;
Body = SetParentOperation(body, this);
IgnoredBody = SetParentOperation(ignoredBody, this);
}
public IMethodSymbol Symbol { get; }
public IBlockOperation? Body { get; }
public IBlockOperation? IgnoredBody { get; }
internal override int ChildOperationsCount =>
(Body is null ? 0 : 1) +
(IgnoredBody is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Body != null
=> Body,
1 when IgnoredBody != null
=> IgnoredBody,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Body != null) return (true, 0, 0);
else goto case 0;
case 0:
if (IgnoredBody != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (IgnoredBody != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Body != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.LocalFunction;
public override void Accept(OperationVisitor visitor) => visitor.VisitLocalFunction(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitLocalFunction(this, argument);
}
internal sealed partial class StopOperation : Operation, IStopOperation
{
internal StopOperation(SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit) { }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Stop;
public override void Accept(OperationVisitor visitor) => visitor.VisitStop(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitStop(this, argument);
}
internal sealed partial class EndOperation : Operation, IEndOperation
{
internal EndOperation(SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit) { }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.End;
public override void Accept(OperationVisitor visitor) => visitor.VisitEnd(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitEnd(this, argument);
}
internal sealed partial class RaiseEventOperation : Operation, IRaiseEventOperation
{
internal RaiseEventOperation(IEventReferenceOperation eventReference, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
EventReference = SetParentOperation(eventReference, this);
Arguments = SetParentOperation(arguments, this);
}
public IEventReferenceOperation EventReference { get; }
public ImmutableArray Arguments { get; }
internal override int ChildOperationsCount =>
(EventReference is null ? 0 : 1) +
Arguments.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when EventReference != null
=> EventReference,
1 when index < Arguments.Length
=> Arguments[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (EventReference != null) return (true, 0, 0);
else goto case 0;
case 0:
if (!Arguments.IsEmpty) return (true, 1, 0);
else goto case 1;
case 1 when previousIndex + 1 < Arguments.Length:
return (true, 1, previousIndex + 1);
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Arguments.IsEmpty) return (true, 1, Arguments.Length - 1);
else goto case 1;
case 1 when previousIndex > 0:
return (true, 1, previousIndex - 1);
case 1:
if (EventReference != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.RaiseEvent;
public override void Accept(OperationVisitor visitor) => visitor.VisitRaiseEvent(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitRaiseEvent(this, argument);
}
internal sealed partial class LiteralOperation : Operation, ILiteralOperation
{
internal LiteralOperation(SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
OperationConstantValue = constantValue;
Type = type;
}
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Literal;
public override void Accept(OperationVisitor visitor) => visitor.VisitLiteral(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitLiteral(this, argument);
}
internal sealed partial class ConversionOperation : Operation, IConversionOperation
{
internal ConversionOperation(IOperation operand, IConvertibleConversion conversion, bool isTryCast, bool isChecked, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operand = SetParentOperation(operand, this);
ConversionConvertible = conversion;
IsTryCast = isTryCast;
IsChecked = isChecked;
OperationConstantValue = constantValue;
Type = type;
}
public IOperation Operand { get; }
internal IConvertibleConversion ConversionConvertible { get; }
public CommonConversion Conversion => ConversionConvertible.ToCommonConversion();
public bool IsTryCast { get; }
public bool IsChecked { get; }
internal override int ChildOperationsCount =>
(Operand is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operand != null
=> Operand,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operand != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operand != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Conversion;
public override void Accept(OperationVisitor visitor) => visitor.VisitConversion(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitConversion(this, argument);
}
internal sealed partial class InvocationOperation : Operation, IInvocationOperation
{
internal InvocationOperation(IMethodSymbol targetMethod, ITypeSymbol? constrainedToType, IOperation? instance, bool isVirtual, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
TargetMethod = targetMethod;
ConstrainedToType = constrainedToType;
Instance = SetParentOperation(instance, this);
IsVirtual = isVirtual;
Arguments = SetParentOperation(arguments, this);
Type = type;
}
public IMethodSymbol TargetMethod { get; }
public ITypeSymbol? ConstrainedToType { get; }
public IOperation? Instance { get; }
public bool IsVirtual { get; }
public ImmutableArray Arguments { get; }
internal override int ChildOperationsCount =>
(Instance is null ? 0 : 1) +
Arguments.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Instance != null
=> Instance,
1 when index < Arguments.Length
=> Arguments[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
if (!Arguments.IsEmpty) return (true, 1, 0);
else goto case 1;
case 1 when previousIndex + 1 < Arguments.Length:
return (true, 1, previousIndex + 1);
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Arguments.IsEmpty) return (true, 1, Arguments.Length - 1);
else goto case 1;
case 1 when previousIndex > 0:
return (true, 1, previousIndex - 1);
case 1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Invocation;
public override void Accept(OperationVisitor visitor) => visitor.VisitInvocation(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitInvocation(this, argument);
}
internal sealed partial class ArrayElementReferenceOperation : Operation, IArrayElementReferenceOperation
{
internal ArrayElementReferenceOperation(IOperation arrayReference, ImmutableArray indices, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
ArrayReference = SetParentOperation(arrayReference, this);
Indices = SetParentOperation(indices, this);
Type = type;
}
public IOperation ArrayReference { get; }
public ImmutableArray Indices { get; }
internal override int ChildOperationsCount =>
(ArrayReference is null ? 0 : 1) +
Indices.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when ArrayReference != null
=> ArrayReference,
1 when index < Indices.Length
=> Indices[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (ArrayReference != null) return (true, 0, 0);
else goto case 0;
case 0:
if (!Indices.IsEmpty) return (true, 1, 0);
else goto case 1;
case 1 when previousIndex + 1 < Indices.Length:
return (true, 1, previousIndex + 1);
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Indices.IsEmpty) return (true, 1, Indices.Length - 1);
else goto case 1;
case 1 when previousIndex > 0:
return (true, 1, previousIndex - 1);
case 1:
if (ArrayReference != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ArrayElementReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitArrayElementReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitArrayElementReference(this, argument);
}
internal sealed partial class LocalReferenceOperation : Operation, ILocalReferenceOperation
{
internal LocalReferenceOperation(ILocalSymbol local, bool isDeclaration, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Local = local;
IsDeclaration = isDeclaration;
OperationConstantValue = constantValue;
Type = type;
}
public ILocalSymbol Local { get; }
public bool IsDeclaration { get; }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.LocalReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitLocalReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitLocalReference(this, argument);
}
internal sealed partial class ParameterReferenceOperation : Operation, IParameterReferenceOperation
{
internal ParameterReferenceOperation(IParameterSymbol parameter, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Parameter = parameter;
Type = type;
}
public IParameterSymbol Parameter { get; }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ParameterReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitParameterReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitParameterReference(this, argument);
}
internal abstract partial class BaseMemberReferenceOperation : Operation, IMemberReferenceOperation
{
protected BaseMemberReferenceOperation(IOperation? instance, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Instance = SetParentOperation(instance, this);
}
public IOperation? Instance { get; }
public abstract ITypeSymbol? ConstrainedToType { get; }
}
internal sealed partial class FieldReferenceOperation : BaseMemberReferenceOperation, IFieldReferenceOperation
{
internal FieldReferenceOperation(IFieldSymbol field, bool isDeclaration, IOperation? instance, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(instance, semanticModel, syntax, isImplicit)
{
Field = field;
IsDeclaration = isDeclaration;
OperationConstantValue = constantValue;
Type = type;
}
public IFieldSymbol Field { get; }
public bool IsDeclaration { get; }
internal override int ChildOperationsCount =>
(Instance is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Instance != null
=> Instance,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.FieldReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitFieldReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitFieldReference(this, argument);
}
internal sealed partial class MethodReferenceOperation : BaseMemberReferenceOperation, IMethodReferenceOperation
{
internal MethodReferenceOperation(IMethodSymbol method, ITypeSymbol? constrainedToType, bool isVirtual, IOperation? instance, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(instance, semanticModel, syntax, isImplicit)
{
Method = method;
ConstrainedToType = constrainedToType;
IsVirtual = isVirtual;
Type = type;
}
public IMethodSymbol Method { get; }
public override ITypeSymbol? ConstrainedToType { get; }
public bool IsVirtual { get; }
internal override int ChildOperationsCount =>
(Instance is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Instance != null
=> Instance,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.MethodReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitMethodReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitMethodReference(this, argument);
}
internal sealed partial class PropertyReferenceOperation : BaseMemberReferenceOperation, IPropertyReferenceOperation
{
internal PropertyReferenceOperation(IPropertySymbol property, ITypeSymbol? constrainedToType, ImmutableArray arguments, IOperation? instance, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(instance, semanticModel, syntax, isImplicit)
{
Property = property;
ConstrainedToType = constrainedToType;
Arguments = SetParentOperation(arguments, this);
Type = type;
}
public IPropertySymbol Property { get; }
public override ITypeSymbol? ConstrainedToType { get; }
public ImmutableArray Arguments { get; }
internal override int ChildOperationsCount =>
Arguments.Length +
(Instance is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Instance != null
=> Instance,
1 when index < Arguments.Length
=> Arguments[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
if (!Arguments.IsEmpty) return (true, 1, 0);
else goto case 1;
case 1 when previousIndex + 1 < Arguments.Length:
return (true, 1, previousIndex + 1);
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Arguments.IsEmpty) return (true, 1, Arguments.Length - 1);
else goto case 1;
case 1 when previousIndex > 0:
return (true, 1, previousIndex - 1);
case 1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.PropertyReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitPropertyReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitPropertyReference(this, argument);
}
internal sealed partial class EventReferenceOperation : BaseMemberReferenceOperation, IEventReferenceOperation
{
internal EventReferenceOperation(IEventSymbol @event, ITypeSymbol? constrainedToType, IOperation? instance, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(instance, semanticModel, syntax, isImplicit)
{
Event = @event;
ConstrainedToType = constrainedToType;
Type = type;
}
public IEventSymbol Event { get; }
public override ITypeSymbol? ConstrainedToType { get; }
internal override int ChildOperationsCount =>
(Instance is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Instance != null
=> Instance,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.EventReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitEventReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitEventReference(this, argument);
}
internal sealed partial class UnaryOperation : Operation, IUnaryOperation
{
internal UnaryOperation(UnaryOperatorKind operatorKind, IOperation operand, bool isLifted, bool isChecked, IMethodSymbol? operatorMethod, ITypeSymbol? constrainedToType, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
OperatorKind = operatorKind;
Operand = SetParentOperation(operand, this);
IsLifted = isLifted;
IsChecked = isChecked;
OperatorMethod = operatorMethod;
ConstrainedToType = constrainedToType;
OperationConstantValue = constantValue;
Type = type;
}
public UnaryOperatorKind OperatorKind { get; }
public IOperation Operand { get; }
public bool IsLifted { get; }
public bool IsChecked { get; }
public IMethodSymbol? OperatorMethod { get; }
public ITypeSymbol? ConstrainedToType { get; }
internal override int ChildOperationsCount =>
(Operand is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operand != null
=> Operand,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operand != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operand != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Unary;
public override void Accept(OperationVisitor visitor) => visitor.VisitUnaryOperator(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitUnaryOperator(this, argument);
}
internal sealed partial class BinaryOperation : Operation, IBinaryOperation
{
internal BinaryOperation(BinaryOperatorKind operatorKind, IOperation leftOperand, IOperation rightOperand, bool isLifted, bool isChecked, bool isCompareText, IMethodSymbol? operatorMethod, ITypeSymbol? constrainedToType, IMethodSymbol? unaryOperatorMethod, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
OperatorKind = operatorKind;
LeftOperand = SetParentOperation(leftOperand, this);
RightOperand = SetParentOperation(rightOperand, this);
IsLifted = isLifted;
IsChecked = isChecked;
IsCompareText = isCompareText;
OperatorMethod = operatorMethod;
ConstrainedToType = constrainedToType;
UnaryOperatorMethod = unaryOperatorMethod;
OperationConstantValue = constantValue;
Type = type;
}
public BinaryOperatorKind OperatorKind { get; }
public IOperation LeftOperand { get; }
public IOperation RightOperand { get; }
public bool IsLifted { get; }
public bool IsChecked { get; }
public bool IsCompareText { get; }
public IMethodSymbol? OperatorMethod { get; }
public ITypeSymbol? ConstrainedToType { get; }
public IMethodSymbol? UnaryOperatorMethod { get; }
internal override int ChildOperationsCount =>
(LeftOperand is null ? 0 : 1) +
(RightOperand is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when LeftOperand != null
=> LeftOperand,
1 when RightOperand != null
=> RightOperand,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (LeftOperand != null) return (true, 0, 0);
else goto case 0;
case 0:
if (RightOperand != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (RightOperand != null) return (true, 1, 0);
else goto case 1;
case 1:
if (LeftOperand != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Binary;
public override void Accept(OperationVisitor visitor) => visitor.VisitBinaryOperator(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitBinaryOperator(this, argument);
}
internal sealed partial class ConditionalOperation : Operation, IConditionalOperation
{
internal ConditionalOperation(IOperation condition, IOperation whenTrue, IOperation? whenFalse, bool isRef, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Condition = SetParentOperation(condition, this);
WhenTrue = SetParentOperation(whenTrue, this);
WhenFalse = SetParentOperation(whenFalse, this);
IsRef = isRef;
OperationConstantValue = constantValue;
Type = type;
}
public IOperation Condition { get; }
public IOperation WhenTrue { get; }
public IOperation? WhenFalse { get; }
public bool IsRef { get; }
internal override int ChildOperationsCount =>
(Condition is null ? 0 : 1) +
(WhenTrue is null ? 0 : 1) +
(WhenFalse is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Condition != null
=> Condition,
1 when WhenTrue != null
=> WhenTrue,
2 when WhenFalse != null
=> WhenFalse,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Condition != null) return (true, 0, 0);
else goto case 0;
case 0:
if (WhenTrue != null) return (true, 1, 0);
else goto case 1;
case 1:
if (WhenFalse != null) return (true, 2, 0);
else goto case 2;
case 2:
case 3:
return (false, 3, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (WhenFalse != null) return (true, 2, 0);
else goto case 2;
case 2:
if (WhenTrue != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Condition != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Conditional;
public override void Accept(OperationVisitor visitor) => visitor.VisitConditional(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitConditional(this, argument);
}
internal sealed partial class CoalesceOperation : Operation, ICoalesceOperation
{
internal CoalesceOperation(IOperation value, IOperation whenNull, IConvertibleConversion valueConversion, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Value = SetParentOperation(value, this);
WhenNull = SetParentOperation(whenNull, this);
ValueConversionConvertible = valueConversion;
OperationConstantValue = constantValue;
Type = type;
}
public IOperation Value { get; }
public IOperation WhenNull { get; }
internal IConvertibleConversion ValueConversionConvertible { get; }
public CommonConversion ValueConversion => ValueConversionConvertible.ToCommonConversion();
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1) +
(WhenNull is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
1 when WhenNull != null
=> WhenNull,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
if (WhenNull != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (WhenNull != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Coalesce;
public override void Accept(OperationVisitor visitor) => visitor.VisitCoalesce(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitCoalesce(this, argument);
}
internal sealed partial class AnonymousFunctionOperation : Operation, IAnonymousFunctionOperation
{
internal AnonymousFunctionOperation(IMethodSymbol symbol, IBlockOperation body, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Symbol = symbol;
Body = SetParentOperation(body, this);
}
public IMethodSymbol Symbol { get; }
public IBlockOperation Body { get; }
internal override int ChildOperationsCount =>
(Body is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Body != null
=> Body,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Body != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Body != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.AnonymousFunction;
public override void Accept(OperationVisitor visitor) => visitor.VisitAnonymousFunction(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitAnonymousFunction(this, argument);
}
internal sealed partial class ObjectCreationOperation : Operation, IObjectCreationOperation
{
internal ObjectCreationOperation(IMethodSymbol? constructor, IObjectOrCollectionInitializerOperation? initializer, ImmutableArray arguments, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Constructor = constructor;
Initializer = SetParentOperation(initializer, this);
Arguments = SetParentOperation(arguments, this);
OperationConstantValue = constantValue;
Type = type;
}
public IMethodSymbol? Constructor { get; }
public IObjectOrCollectionInitializerOperation? Initializer { get; }
public ImmutableArray Arguments { get; }
internal override int ChildOperationsCount =>
(Initializer is null ? 0 : 1) +
Arguments.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Arguments.Length
=> Arguments[index],
1 when Initializer != null
=> Initializer,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Arguments.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Arguments.Length:
return (true, 0, previousIndex + 1);
case 0:
if (Initializer != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Initializer != null) return (true, 1, 0);
else goto case 1;
case 1:
if (!Arguments.IsEmpty) return (true, 0, Arguments.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.ObjectCreation;
public override void Accept(OperationVisitor visitor) => visitor.VisitObjectCreation(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitObjectCreation(this, argument);
}
internal sealed partial class TypeParameterObjectCreationOperation : Operation, ITypeParameterObjectCreationOperation
{
internal TypeParameterObjectCreationOperation(IObjectOrCollectionInitializerOperation? initializer, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Initializer = SetParentOperation(initializer, this);
Type = type;
}
public IObjectOrCollectionInitializerOperation? Initializer { get; }
internal override int ChildOperationsCount =>
(Initializer is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Initializer != null
=> Initializer,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Initializer != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Initializer != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.TypeParameterObjectCreation;
public override void Accept(OperationVisitor visitor) => visitor.VisitTypeParameterObjectCreation(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitTypeParameterObjectCreation(this, argument);
}
internal sealed partial class ArrayCreationOperation : Operation, IArrayCreationOperation
{
internal ArrayCreationOperation(ImmutableArray dimensionSizes, IArrayInitializerOperation? initializer, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
DimensionSizes = SetParentOperation(dimensionSizes, this);
Initializer = SetParentOperation(initializer, this);
Type = type;
}
public ImmutableArray DimensionSizes { get; }
public IArrayInitializerOperation? Initializer { get; }
internal override int ChildOperationsCount =>
DimensionSizes.Length +
(Initializer is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < DimensionSizes.Length
=> DimensionSizes[index],
1 when Initializer != null
=> Initializer,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!DimensionSizes.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < DimensionSizes.Length:
return (true, 0, previousIndex + 1);
case 0:
if (Initializer != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Initializer != null) return (true, 1, 0);
else goto case 1;
case 1:
if (!DimensionSizes.IsEmpty) return (true, 0, DimensionSizes.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ArrayCreation;
public override void Accept(OperationVisitor visitor) => visitor.VisitArrayCreation(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitArrayCreation(this, argument);
}
internal sealed partial class InstanceReferenceOperation : Operation, IInstanceReferenceOperation
{
internal InstanceReferenceOperation(InstanceReferenceKind referenceKind, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
ReferenceKind = referenceKind;
Type = type;
}
public InstanceReferenceKind ReferenceKind { get; }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.InstanceReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitInstanceReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitInstanceReference(this, argument);
}
internal sealed partial class IsTypeOperation : Operation, IIsTypeOperation
{
internal IsTypeOperation(IOperation valueOperand, ITypeSymbol typeOperand, bool isNegated, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
ValueOperand = SetParentOperation(valueOperand, this);
TypeOperand = typeOperand;
IsNegated = isNegated;
Type = type;
}
public IOperation ValueOperand { get; }
public ITypeSymbol TypeOperand { get; }
public bool IsNegated { get; }
internal override int ChildOperationsCount =>
(ValueOperand is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when ValueOperand != null
=> ValueOperand,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (ValueOperand != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (ValueOperand != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.IsType;
public override void Accept(OperationVisitor visitor) => visitor.VisitIsType(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitIsType(this, argument);
}
internal sealed partial class AwaitOperation : Operation, IAwaitOperation
{
internal AwaitOperation(IOperation operation, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operation = SetParentOperation(operation, this);
Type = type;
}
public IOperation Operation { get; }
internal override int ChildOperationsCount =>
(Operation is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operation != null
=> Operation,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Await;
public override void Accept(OperationVisitor visitor) => visitor.VisitAwait(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitAwait(this, argument);
}
internal abstract partial class BaseAssignmentOperation : Operation, IAssignmentOperation
{
protected BaseAssignmentOperation(IOperation target, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Target = SetParentOperation(target, this);
Value = SetParentOperation(value, this);
}
public IOperation Target { get; }
public IOperation Value { get; }
}
internal sealed partial class SimpleAssignmentOperation : BaseAssignmentOperation, ISimpleAssignmentOperation
{
internal SimpleAssignmentOperation(bool isRef, IOperation target, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(target, value, semanticModel, syntax, isImplicit)
{
IsRef = isRef;
OperationConstantValue = constantValue;
Type = type;
}
public bool IsRef { get; }
internal override int ChildOperationsCount =>
(Target is null ? 0 : 1) +
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Target != null
=> Target,
1 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Value != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.SimpleAssignment;
public override void Accept(OperationVisitor visitor) => visitor.VisitSimpleAssignment(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitSimpleAssignment(this, argument);
}
internal sealed partial class CompoundAssignmentOperation : BaseAssignmentOperation, ICompoundAssignmentOperation
{
internal CompoundAssignmentOperation(IConvertibleConversion inConversion, IConvertibleConversion outConversion, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol? operatorMethod, ITypeSymbol? constrainedToType, IOperation target, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(target, value, semanticModel, syntax, isImplicit)
{
InConversionConvertible = inConversion;
OutConversionConvertible = outConversion;
OperatorKind = operatorKind;
IsLifted = isLifted;
IsChecked = isChecked;
OperatorMethod = operatorMethod;
ConstrainedToType = constrainedToType;
Type = type;
}
internal IConvertibleConversion InConversionConvertible { get; }
public CommonConversion InConversion => InConversionConvertible.ToCommonConversion();
internal IConvertibleConversion OutConversionConvertible { get; }
public CommonConversion OutConversion => OutConversionConvertible.ToCommonConversion();
public BinaryOperatorKind OperatorKind { get; }
public bool IsLifted { get; }
public bool IsChecked { get; }
public IMethodSymbol? OperatorMethod { get; }
public ITypeSymbol? ConstrainedToType { get; }
internal override int ChildOperationsCount =>
(Target is null ? 0 : 1) +
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Target != null
=> Target,
1 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Value != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.CompoundAssignment;
public override void Accept(OperationVisitor visitor) => visitor.VisitCompoundAssignment(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitCompoundAssignment(this, argument);
}
internal sealed partial class ParenthesizedOperation : Operation, IParenthesizedOperation
{
internal ParenthesizedOperation(IOperation operand, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operand = SetParentOperation(operand, this);
OperationConstantValue = constantValue;
Type = type;
}
public IOperation Operand { get; }
internal override int ChildOperationsCount =>
(Operand is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operand != null
=> Operand,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operand != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operand != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.Parenthesized;
public override void Accept(OperationVisitor visitor) => visitor.VisitParenthesized(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitParenthesized(this, argument);
}
internal sealed partial class EventAssignmentOperation : Operation, IEventAssignmentOperation
{
internal EventAssignmentOperation(IOperation eventReference, IOperation handlerValue, bool adds, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
EventReference = SetParentOperation(eventReference, this);
HandlerValue = SetParentOperation(handlerValue, this);
Adds = adds;
Type = type;
}
public IOperation EventReference { get; }
public IOperation HandlerValue { get; }
public bool Adds { get; }
internal override int ChildOperationsCount =>
(EventReference is null ? 0 : 1) +
(HandlerValue is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when EventReference != null
=> EventReference,
1 when HandlerValue != null
=> HandlerValue,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (EventReference != null) return (true, 0, 0);
else goto case 0;
case 0:
if (HandlerValue != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (HandlerValue != null) return (true, 1, 0);
else goto case 1;
case 1:
if (EventReference != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.EventAssignment;
public override void Accept(OperationVisitor visitor) => visitor.VisitEventAssignment(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitEventAssignment(this, argument);
}
internal sealed partial class ConditionalAccessOperation : Operation, IConditionalAccessOperation
{
internal ConditionalAccessOperation(IOperation operation, IOperation whenNotNull, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operation = SetParentOperation(operation, this);
WhenNotNull = SetParentOperation(whenNotNull, this);
Type = type;
}
public IOperation Operation { get; }
public IOperation WhenNotNull { get; }
internal override int ChildOperationsCount =>
(Operation is null ? 0 : 1) +
(WhenNotNull is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operation != null
=> Operation,
1 when WhenNotNull != null
=> WhenNotNull,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
if (WhenNotNull != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (WhenNotNull != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ConditionalAccess;
public override void Accept(OperationVisitor visitor) => visitor.VisitConditionalAccess(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitConditionalAccess(this, argument);
}
internal sealed partial class ConditionalAccessInstanceOperation : Operation, IConditionalAccessInstanceOperation
{
internal ConditionalAccessInstanceOperation(SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Type = type;
}
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ConditionalAccessInstance;
public override void Accept(OperationVisitor visitor) => visitor.VisitConditionalAccessInstance(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitConditionalAccessInstance(this, argument);
}
internal sealed partial class InterpolatedStringOperation : Operation, IInterpolatedStringOperation
{
internal InterpolatedStringOperation(ImmutableArray parts, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Parts = SetParentOperation(parts, this);
OperationConstantValue = constantValue;
Type = type;
}
public ImmutableArray Parts { get; }
internal override int ChildOperationsCount =>
Parts.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Parts.Length
=> Parts[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Parts.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Parts.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Parts.IsEmpty) return (true, 0, Parts.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.InterpolatedString;
public override void Accept(OperationVisitor visitor) => visitor.VisitInterpolatedString(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitInterpolatedString(this, argument);
}
internal sealed partial class AnonymousObjectCreationOperation : Operation, IAnonymousObjectCreationOperation
{
internal AnonymousObjectCreationOperation(ImmutableArray initializers, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Initializers = SetParentOperation(initializers, this);
Type = type;
}
public ImmutableArray Initializers { get; }
internal override int ChildOperationsCount =>
Initializers.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Initializers.Length
=> Initializers[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Initializers.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Initializers.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Initializers.IsEmpty) return (true, 0, Initializers.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.AnonymousObjectCreation;
public override void Accept(OperationVisitor visitor) => visitor.VisitAnonymousObjectCreation(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitAnonymousObjectCreation(this, argument);
}
internal sealed partial class ObjectOrCollectionInitializerOperation : Operation, IObjectOrCollectionInitializerOperation
{
internal ObjectOrCollectionInitializerOperation(ImmutableArray initializers, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Initializers = SetParentOperation(initializers, this);
Type = type;
}
public ImmutableArray Initializers { get; }
internal override int ChildOperationsCount =>
Initializers.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Initializers.Length
=> Initializers[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Initializers.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Initializers.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Initializers.IsEmpty) return (true, 0, Initializers.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ObjectOrCollectionInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitObjectOrCollectionInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitObjectOrCollectionInitializer(this, argument);
}
internal sealed partial class MemberInitializerOperation : Operation, IMemberInitializerOperation
{
internal MemberInitializerOperation(IOperation initializedMember, IObjectOrCollectionInitializerOperation initializer, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
InitializedMember = SetParentOperation(initializedMember, this);
Initializer = SetParentOperation(initializer, this);
Type = type;
}
public IOperation InitializedMember { get; }
public IObjectOrCollectionInitializerOperation Initializer { get; }
internal override int ChildOperationsCount =>
(InitializedMember is null ? 0 : 1) +
(Initializer is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when InitializedMember != null
=> InitializedMember,
1 when Initializer != null
=> Initializer,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (InitializedMember != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Initializer != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Initializer != null) return (true, 1, 0);
else goto case 1;
case 1:
if (InitializedMember != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.MemberInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitMemberInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitMemberInitializer(this, argument);
}
internal sealed partial class NameOfOperation : Operation, INameOfOperation
{
internal NameOfOperation(IOperation argument, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Argument = SetParentOperation(argument, this);
OperationConstantValue = constantValue;
Type = type;
}
public IOperation Argument { get; }
internal override int ChildOperationsCount =>
(Argument is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Argument != null
=> Argument,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Argument != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Argument != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.NameOf;
public override void Accept(OperationVisitor visitor) => visitor.VisitNameOf(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitNameOf(this, argument);
}
internal sealed partial class TupleOperation : Operation, ITupleOperation
{
internal TupleOperation(ImmutableArray elements, ITypeSymbol? naturalType, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Elements = SetParentOperation(elements, this);
NaturalType = naturalType;
Type = type;
}
public ImmutableArray Elements { get; }
public ITypeSymbol? NaturalType { get; }
internal override int ChildOperationsCount =>
Elements.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < Elements.Length
=> Elements[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!Elements.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < Elements.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!Elements.IsEmpty) return (true, 0, Elements.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Tuple;
public override void Accept(OperationVisitor visitor) => visitor.VisitTuple(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitTuple(this, argument);
}
internal sealed partial class DynamicMemberReferenceOperation : Operation, IDynamicMemberReferenceOperation
{
internal DynamicMemberReferenceOperation(IOperation? instance, string memberName, ImmutableArray typeArguments, ITypeSymbol? containingType, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Instance = SetParentOperation(instance, this);
MemberName = memberName;
TypeArguments = typeArguments;
ContainingType = containingType;
Type = type;
}
public IOperation? Instance { get; }
public string MemberName { get; }
public ImmutableArray TypeArguments { get; }
public ITypeSymbol? ContainingType { get; }
internal override int ChildOperationsCount =>
(Instance is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Instance != null
=> Instance,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Instance != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.DynamicMemberReference;
public override void Accept(OperationVisitor visitor) => visitor.VisitDynamicMemberReference(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitDynamicMemberReference(this, argument);
}
internal sealed partial class TranslatedQueryOperation : Operation, ITranslatedQueryOperation
{
internal TranslatedQueryOperation(IOperation operation, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operation = SetParentOperation(operation, this);
Type = type;
}
public IOperation Operation { get; }
internal override int ChildOperationsCount =>
(Operation is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Operation != null
=> Operation,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Operation != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.TranslatedQuery;
public override void Accept(OperationVisitor visitor) => visitor.VisitTranslatedQuery(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitTranslatedQuery(this, argument);
}
internal sealed partial class DelegateCreationOperation : Operation, IDelegateCreationOperation
{
internal DelegateCreationOperation(IOperation target, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Target = SetParentOperation(target, this);
Type = type;
}
public IOperation Target { get; }
internal override int ChildOperationsCount =>
(Target is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Target != null
=> Target,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.DelegateCreation;
public override void Accept(OperationVisitor visitor) => visitor.VisitDelegateCreation(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitDelegateCreation(this, argument);
}
internal sealed partial class DefaultValueOperation : Operation, IDefaultValueOperation
{
internal DefaultValueOperation(SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
OperationConstantValue = constantValue;
Type = type;
}
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.DefaultValue;
public override void Accept(OperationVisitor visitor) => visitor.VisitDefaultValue(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitDefaultValue(this, argument);
}
internal sealed partial class TypeOfOperation : Operation, ITypeOfOperation
{
internal TypeOfOperation(ITypeSymbol typeOperand, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
TypeOperand = typeOperand;
Type = type;
}
public ITypeSymbol TypeOperand { get; }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.TypeOf;
public override void Accept(OperationVisitor visitor) => visitor.VisitTypeOf(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitTypeOf(this, argument);
}
internal sealed partial class SizeOfOperation : Operation, ISizeOfOperation
{
internal SizeOfOperation(ITypeSymbol typeOperand, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, ConstantValue? constantValue, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
TypeOperand = typeOperand;
OperationConstantValue = constantValue;
Type = type;
}
public ITypeSymbol TypeOperand { get; }
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue { get; }
public override OperationKind Kind => OperationKind.SizeOf;
public override void Accept(OperationVisitor visitor) => visitor.VisitSizeOf(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitSizeOf(this, argument);
}
internal sealed partial class AddressOfOperation : Operation, IAddressOfOperation
{
internal AddressOfOperation(IOperation reference, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Reference = SetParentOperation(reference, this);
Type = type;
}
public IOperation Reference { get; }
internal override int ChildOperationsCount =>
(Reference is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Reference != null
=> Reference,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Reference != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Reference != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.AddressOf;
public override void Accept(OperationVisitor visitor) => visitor.VisitAddressOf(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitAddressOf(this, argument);
}
internal sealed partial class IsPatternOperation : Operation, IIsPatternOperation
{
internal IsPatternOperation(IOperation value, IPatternOperation pattern, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Value = SetParentOperation(value, this);
Pattern = SetParentOperation(pattern, this);
Type = type;
}
public IOperation Value { get; }
public IPatternOperation Pattern { get; }
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1) +
(Pattern is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
1 when Pattern != null
=> Pattern,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Pattern != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Pattern != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.IsPattern;
public override void Accept(OperationVisitor visitor) => visitor.VisitIsPattern(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitIsPattern(this, argument);
}
internal sealed partial class IncrementOrDecrementOperation : Operation, IIncrementOrDecrementOperation
{
internal IncrementOrDecrementOperation(bool isPostfix, bool isLifted, bool isChecked, IOperation target, IMethodSymbol? operatorMethod, ITypeSymbol? constrainedToType, OperationKind kind, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
IsPostfix = isPostfix;
IsLifted = isLifted;
IsChecked = isChecked;
Target = SetParentOperation(target, this);
OperatorMethod = operatorMethod;
ConstrainedToType = constrainedToType;
Type = type;
Kind = kind;
}
public bool IsPostfix { get; }
public bool IsLifted { get; }
public bool IsChecked { get; }
public IOperation Target { get; }
public IMethodSymbol? OperatorMethod { get; }
public ITypeSymbol? ConstrainedToType { get; }
internal override int ChildOperationsCount =>
(Target is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Target != null
=> Target,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind { get; }
public override void Accept(OperationVisitor visitor) => visitor.VisitIncrementOrDecrement(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitIncrementOrDecrement(this, argument);
}
internal sealed partial class ThrowOperation : Operation, IThrowOperation
{
internal ThrowOperation(IOperation? exception, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Exception = SetParentOperation(exception, this);
Type = type;
}
public IOperation? Exception { get; }
internal override int ChildOperationsCount =>
(Exception is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Exception != null
=> Exception,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Exception != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Exception != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.Throw;
public override void Accept(OperationVisitor visitor) => visitor.VisitThrow(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitThrow(this, argument);
}
internal sealed partial class DeconstructionAssignmentOperation : BaseAssignmentOperation, IDeconstructionAssignmentOperation
{
internal DeconstructionAssignmentOperation(IOperation target, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(target, value, semanticModel, syntax, isImplicit)
{
Type = type;
}
internal override int ChildOperationsCount =>
(Target is null ? 0 : 1) +
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Target != null
=> Target,
1 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
if (Value != null) return (true, 1, 0);
else goto case 1;
case 1:
case 2:
return (false, 2, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 1, 0);
else goto case 1;
case 1:
if (Target != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.DeconstructionAssignment;
public override void Accept(OperationVisitor visitor) => visitor.VisitDeconstructionAssignment(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitDeconstructionAssignment(this, argument);
}
internal sealed partial class DeclarationExpressionOperation : Operation, IDeclarationExpressionOperation
{
internal DeclarationExpressionOperation(IOperation expression, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Expression = SetParentOperation(expression, this);
Type = type;
}
public IOperation Expression { get; }
internal override int ChildOperationsCount =>
(Expression is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Expression != null
=> Expression,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Expression != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Expression != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.DeclarationExpression;
public override void Accept(OperationVisitor visitor) => visitor.VisitDeclarationExpression(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitDeclarationExpression(this, argument);
}
internal sealed partial class OmittedArgumentOperation : Operation, IOmittedArgumentOperation
{
internal OmittedArgumentOperation(SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Type = type;
}
internal override int ChildOperationsCount => 0;
internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);
public override ITypeSymbol? Type { get; }
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.OmittedArgument;
public override void Accept(OperationVisitor visitor) => visitor.VisitOmittedArgument(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitOmittedArgument(this, argument);
}
internal abstract partial class BaseSymbolInitializerOperation : Operation, ISymbolInitializerOperation
{
protected BaseSymbolInitializerOperation(ImmutableArray locals, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Locals = locals;
Value = SetParentOperation(value, this);
}
public ImmutableArray Locals { get; }
public IOperation Value { get; }
}
internal sealed partial class FieldInitializerOperation : BaseSymbolInitializerOperation, IFieldInitializerOperation
{
internal FieldInitializerOperation(ImmutableArray initializedFields, ImmutableArray locals, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(locals, value, semanticModel, syntax, isImplicit)
{
InitializedFields = initializedFields;
}
public ImmutableArray InitializedFields { get; }
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.FieldInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitFieldInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitFieldInitializer(this, argument);
}
internal sealed partial class VariableInitializerOperation : BaseSymbolInitializerOperation, IVariableInitializerOperation
{
internal VariableInitializerOperation(ImmutableArray locals, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(locals, value, semanticModel, syntax, isImplicit) { }
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.VariableInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitVariableInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitVariableInitializer(this, argument);
}
internal sealed partial class PropertyInitializerOperation : BaseSymbolInitializerOperation, IPropertyInitializerOperation
{
internal PropertyInitializerOperation(ImmutableArray initializedProperties, ImmutableArray locals, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(locals, value, semanticModel, syntax, isImplicit)
{
InitializedProperties = initializedProperties;
}
public ImmutableArray InitializedProperties { get; }
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.PropertyInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitPropertyInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitPropertyInitializer(this, argument);
}
internal sealed partial class ParameterInitializerOperation : BaseSymbolInitializerOperation, IParameterInitializerOperation
{
internal ParameterInitializerOperation(IParameterSymbol parameter, ImmutableArray locals, IOperation value, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(locals, value, semanticModel, syntax, isImplicit)
{
Parameter = parameter;
}
public IParameterSymbol Parameter { get; }
internal override int ChildOperationsCount =>
(Value is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when Value != null
=> Value,
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (Value != null) return (true, 0, 0);
else goto case 0;
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ParameterInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitParameterInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitParameterInitializer(this, argument);
}
internal sealed partial class ArrayInitializerOperation : Operation, IArrayInitializerOperation
{
internal ArrayInitializerOperation(ImmutableArray elementValues, SemanticModel? semanticModel, SyntaxNode syntax, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
ElementValues = SetParentOperation(elementValues, this);
}
public ImmutableArray ElementValues { get; }
internal override int ChildOperationsCount =>
ElementValues.Length;
internal override IOperation GetCurrent(int slot, int index)
=> slot switch
{
0 when index < ElementValues.Length
=> ElementValues[index],
_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),
};
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case -1:
if (!ElementValues.IsEmpty) return (true, 0, 0);
else goto case 0;
case 0 when previousIndex + 1 < ElementValues.Length:
return (true, 0, previousIndex + 1);
case 0:
case 1:
return (false, 1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)
{
switch (previousSlot)
{
case int.MaxValue:
if (!ElementValues.IsEmpty) return (true, 0, ElementValues.Length - 1);
else goto case 0;
case 0 when previousIndex > 0:
return (true, 0, previousIndex - 1);
case 0:
case -1:
return (false, -1, 0);
default:
throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));
}
}
public override ITypeSymbol? Type => null;
internal override ConstantValue? OperationConstantValue => null;
public override OperationKind Kind => OperationKind.ArrayInitializer;
public override void Accept(OperationVisitor visitor) => visitor.VisitArrayInitializer(this);
public override TResult? Accept(OperationVisitor visitor, TArgument argument) where TResult : default => visitor.VisitArrayInitializer(this, argument);
}
internal sealed partial class VariableDeclaratorOperation : Operation, IVariableDeclaratorOperation
{
internal VariableDeclaratorOperation(ILocalSymbol symbol, IVariableInitializerOperation? initializer, ImmutableArray