From 2898c124128a2a52d25c4aa5c59f00be6deae27f Mon Sep 17 00:00:00 2001 From: Heejae Chang Date: Tue, 18 Apr 2017 16:15:39 -0700 Subject: [PATCH] regenerated xml.generated file --- .../CSharp/Portable/Binder/Binder_Patterns.cs | 9 +- .../CSharp/Portable/BoundTree/Expression.cs | 3276 +++++++++-------- .../CSharp/Portable/BoundTree/Statement.cs | 10 +- .../Compilation/MemberSemanticModel.cs | 12 +- .../AsyncRewriter/AwaitExpressionSpiller.cs | 16 +- .../PartiallyLoweredLocalFunctionReference.cs | 18 - .../Operations/CSharpOperationFactory.cs | 568 ++- .../Core/Portable/CodeAnalysis.csproj | 3 +- .../Generated/Operations.xml.Generated.cs | 72 +- .../Core/Portable/Operations/Expressions.cs | 116 - ...renceExpression_IHasArgumentsExpression.cs | 16 +- ...ationExpression_IHasArgumentsExpression.cs | 8 +- ...ationExpression_IHasArgumentsExpression.cs | 8 +- .../Portable/Operations/OperationFactory.cs | 99 + .../Core/Portable/Operations/Statement.cs | 17 - .../Portable/BoundTree/Expression.vb | 2 +- .../Portable/BoundTree/Statement.vb | 24 +- 17 files changed, 2321 insertions(+), 1953 deletions(-) delete mode 100644 src/Compilers/Core/Portable/Operations/Expressions.cs create mode 100644 src/Compilers/Core/Portable/Operations/OperationFactory.cs delete mode 100644 src/Compilers/Core/Portable/Operations/Statement.cs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs index 7864640018f..e9b3429df9e 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs @@ -180,8 +180,8 @@ internal BoundExpression ConvertPatternExpression(TypeSymbol inputType, CSharpSy { case ConversionKind.ExplicitDynamic: case ConversionKind.ImplicitDynamic: - // Since the input was `dynamic`, which is equivalent to `object`, there must also - // exist some unboxing, identity, or reference conversion as well, making the conversion legal. + // Since the input was `dynamic`, which is equivalent to `object`, there must also + // exist some unboxing, identity, or reference conversion as well, making the conversion legal. case ConversionKind.Boxing: case ConversionKind.ExplicitNullable: case ConversionKind.ExplicitReference: @@ -245,7 +245,7 @@ internal BoundExpression ConvertPatternExpression(TypeSymbol inputType, CSharpSy case SyntaxKind.SingleVariableDesignation: break; case SyntaxKind.DiscardDesignation: - return new BoundDeclarationPattern(node, null, boundDeclType, isVar, hasErrors); + return new BoundDeclarationPattern(node, null, new BoundDiscardExpression(node, boundDeclType.Type), boundDeclType, isVar, hasErrors); default: throw ExceptionUtilities.UnexpectedValue(node.Designation.Kind()); } @@ -271,7 +271,8 @@ internal BoundExpression ConvertPatternExpression(TypeSymbol inputType, CSharpSy hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax); } - return new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors); + var expression = localSymbol == null ? new BoundDiscardExpression(node, boundDeclType.Type) : (BoundExpression)new BoundLocal(node, localSymbol, null, boundDeclType.Type); + return new BoundDeclarationPattern(node, localSymbol, expression, boundDeclType, isVar, hasErrors); } else { diff --git a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs index 6a66386533c..bf037433212 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs @@ -10,951 +10,1222 @@ namespace Microsoft.CodeAnalysis.CSharp { - internal partial class BoundExpression : IOperation + internal class Expression { - ITypeSymbol IOperation.Type => this.Type; - - OperationKind IOperation.Kind => this.ExpressionKind; - - bool IOperation.IsInvalid => this.HasErrors; - - Optional IOperation.ConstantValue + internal static BinaryOperationKind DeriveBinaryOperationKind(UnaryOperationKind incrementKind) { - get + switch (incrementKind) { - ConstantValue value = this.ConstantValue; - return value != null ? new Optional(value.Value) : default(Optional); - } - } - SyntaxNode IOperation.Syntax => this.Syntax; - - protected abstract OperationKind ExpressionKind { get; } - - public abstract void Accept(OperationVisitor visitor); - - public abstract TResult Accept(OperationVisitor visitor, TArgument argument); - } - - internal sealed partial class BoundDeconstructValuePlaceholder : BoundValuePlaceholderBase, IPlaceholderExpression - { - protected override OperationKind ExpressionKind => OperationKind.PlaceholderExpression; + case UnaryOperationKind.OperatorMethodPostfixIncrement: + case UnaryOperationKind.OperatorMethodPrefixIncrement: + return BinaryOperationKind.OperatorMethodAdd; + case UnaryOperationKind.OperatorMethodPostfixDecrement: + case UnaryOperationKind.OperatorMethodPrefixDecrement: + return BinaryOperationKind.OperatorMethodSubtract; + case UnaryOperationKind.IntegerPostfixIncrement: + case UnaryOperationKind.IntegerPrefixIncrement: + return BinaryOperationKind.IntegerAdd; + case UnaryOperationKind.IntegerPostfixDecrement: + case UnaryOperationKind.IntegerPrefixDecrement: + return BinaryOperationKind.IntegerSubtract; + case UnaryOperationKind.UnsignedPostfixIncrement: + case UnaryOperationKind.UnsignedPrefixIncrement: + return BinaryOperationKind.UnsignedAdd; + case UnaryOperationKind.UnsignedPostfixDecrement: + case UnaryOperationKind.UnsignedPrefixDecrement: + return BinaryOperationKind.UnsignedSubtract; + case UnaryOperationKind.FloatingPostfixIncrement: + case UnaryOperationKind.FloatingPrefixIncrement: + return BinaryOperationKind.FloatingAdd; + case UnaryOperationKind.FloatingPostfixDecrement: + case UnaryOperationKind.FloatingPrefixDecrement: + return BinaryOperationKind.FloatingSubtract; + case UnaryOperationKind.DecimalPostfixIncrement: + case UnaryOperationKind.DecimalPrefixIncrement: + return BinaryOperationKind.DecimalAdd; + case UnaryOperationKind.DecimalPostfixDecrement: + case UnaryOperationKind.DecimalPrefixDecrement: + return BinaryOperationKind.DecimalSubtract; + case UnaryOperationKind.EnumPostfixIncrement: + case UnaryOperationKind.EnumPrefixIncrement: + return BinaryOperationKind.EnumAdd; + case UnaryOperationKind.EnumPostfixDecrement: + case UnaryOperationKind.EnumPrefixDecrement: + return BinaryOperationKind.EnumSubtract; + case UnaryOperationKind.PointerPostfixIncrement: + case UnaryOperationKind.PointerPrefixIncrement: + return BinaryOperationKind.PointerIntegerAdd; + case UnaryOperationKind.PointerPostfixDecrement: + case UnaryOperationKind.PointerPrefixDecrement: + return BinaryOperationKind.PointerIntegerSubtract; + case UnaryOperationKind.DynamicPostfixIncrement: + case UnaryOperationKind.DynamicPrefixIncrement: + return BinaryOperationKind.DynamicAdd; + case UnaryOperationKind.DynamicPostfixDecrement: + case UnaryOperationKind.DynamicPrefixDecrement: + return BinaryOperationKind.DynamicSubtract; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitPlaceholderExpression(this); + default: + return BinaryOperationKind.Invalid; + } } - public override TResult Accept(OperationVisitor visitor, TArgument argument) + internal static UnaryOperationKind DeriveUnaryOperationKind(UnaryOperatorKind operatorKind) { - return visitor.VisitPlaceholderExpression(this, argument); - } - } + switch (operatorKind & UnaryOperatorKind.OpMask) + { + case UnaryOperatorKind.PostfixIncrement: + switch (operatorKind & UnaryOperatorKind.TypeMask) + { + case UnaryOperatorKind.Int: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.SByte: + case UnaryOperatorKind.Short: + return UnaryOperationKind.IntegerPostfixIncrement; + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.ULong: + case UnaryOperatorKind.Byte: + case UnaryOperatorKind.UShort: + case UnaryOperatorKind.Char: + return UnaryOperationKind.UnsignedPostfixIncrement; + case UnaryOperatorKind.Float: + case UnaryOperatorKind.Double: + return UnaryOperationKind.FloatingPostfixIncrement; + case UnaryOperatorKind.Decimal: + return UnaryOperationKind.DecimalPostfixIncrement; + case UnaryOperatorKind.Enum: + return UnaryOperationKind.EnumPostfixIncrement; + case UnaryOperatorKind.Pointer: + return UnaryOperationKind.PointerPostfixIncrement; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicPostfixIncrement; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodPostfixIncrement; + } - internal partial class BoundCall : IInvocationExpression - { - IMethodSymbol IInvocationExpression.TargetMethod => this.Method; + break; - IOperation IInvocationExpression.Instance => ((object)this.Method == null || this.Method.IsStatic) ? null : this.ReceiverOpt; + case UnaryOperatorKind.PostfixDecrement: + switch (operatorKind & UnaryOperatorKind.TypeMask) + { + case UnaryOperatorKind.Int: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.SByte: + case UnaryOperatorKind.Short: + return UnaryOperationKind.IntegerPostfixDecrement; + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.ULong: + case UnaryOperatorKind.Byte: + case UnaryOperatorKind.UShort: + case UnaryOperatorKind.Char: + return UnaryOperationKind.UnsignedPostfixDecrement; + case UnaryOperatorKind.Float: + case UnaryOperatorKind.Double: + return UnaryOperationKind.FloatingPostfixDecrement; + case UnaryOperatorKind.Decimal: + return UnaryOperationKind.DecimalPostfixDecrement; + case UnaryOperatorKind.Enum: + return UnaryOperationKind.EnumPostfixDecrement; + case UnaryOperatorKind.Pointer: + return UnaryOperationKind.PointerPostfixIncrement; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicPostfixDecrement; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodPostfixDecrement; + } - bool IInvocationExpression.IsVirtual => - (object)this.Method != null && - this.ReceiverOpt != null && - (this.Method.IsVirtual || this.Method.IsAbstract || this.Method.IsOverride) && - !this.ReceiverOpt.SuppressVirtualCalls; + break; - ImmutableArray IInvocationExpression.ArgumentsInSourceOrder - { - get - { - ArrayBuilder sourceOrderArguments = ArrayBuilder.GetInstance(this.Arguments.Length); - for (int argumentIndex = 0; argumentIndex < this.Arguments.Length; argumentIndex++) - { - IArgument argument = DeriveArgument(this.ArgsToParamsOpt.IsDefault ? argumentIndex : this.ArgsToParamsOpt[argumentIndex], argumentIndex, this.Arguments, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, this.Method.Parameters, this.Syntax); - sourceOrderArguments.Add(argument); - if (argument.ArgumentKind == ArgumentKind.ParamArray) + case UnaryOperatorKind.PrefixIncrement: + switch (operatorKind & UnaryOperatorKind.TypeMask) { - break; + case UnaryOperatorKind.Int: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.SByte: + case UnaryOperatorKind.Short: + return UnaryOperationKind.IntegerPrefixIncrement; + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.ULong: + case UnaryOperatorKind.Byte: + case UnaryOperatorKind.UShort: + case UnaryOperatorKind.Char: + return UnaryOperationKind.UnsignedPrefixIncrement; + case UnaryOperatorKind.Float: + case UnaryOperatorKind.Double: + return UnaryOperationKind.FloatingPrefixIncrement; + case UnaryOperatorKind.Decimal: + return UnaryOperationKind.DecimalPrefixIncrement; + case UnaryOperatorKind.Enum: + return UnaryOperationKind.EnumPrefixIncrement; + case UnaryOperatorKind.Pointer: + return UnaryOperationKind.PointerPrefixIncrement; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicPrefixIncrement; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodPrefixIncrement; } - } - return sourceOrderArguments.ToImmutableAndFree(); - } - } + break; - ImmutableArray IHasArgumentsExpression.ArgumentsInParameterOrder => DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Method.Parameters, this.Syntax); + case UnaryOperatorKind.PrefixDecrement: + switch (operatorKind & UnaryOperatorKind.TypeMask) + { + case UnaryOperatorKind.Int: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.SByte: + case UnaryOperatorKind.Short: + return UnaryOperationKind.IntegerPrefixDecrement; + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.ULong: + case UnaryOperatorKind.Byte: + case UnaryOperatorKind.UShort: + case UnaryOperatorKind.Char: + return UnaryOperationKind.UnsignedPrefixDecrement; + case UnaryOperatorKind.Float: + case UnaryOperatorKind.Double: + return UnaryOperationKind.FloatingPrefixDecrement; + case UnaryOperatorKind.Decimal: + return UnaryOperationKind.DecimalPrefixDecrement; + case UnaryOperatorKind.Enum: + return UnaryOperationKind.EnumPrefixDecrement; + case UnaryOperatorKind.Pointer: + return UnaryOperationKind.PointerPrefixIncrement; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicPrefixDecrement; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodPrefixDecrement; + } - IArgument IHasArgumentsExpression.GetArgumentMatchingParameter(IParameterSymbol parameter) - { - return ArgumentMatchingParameter(this.Arguments, this.ArgsToParamsOpt, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, parameter.ContainingSymbol, ((Symbols.MethodSymbol)parameter.ContainingSymbol).Parameters, parameter, this.Syntax); - } + break; - protected override OperationKind ExpressionKind => OperationKind.InvocationExpression; + case UnaryOperatorKind.UnaryPlus: + switch (operatorKind & UnaryOperatorKind.TypeMask) + { + case UnaryOperatorKind.Int: + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.ULong: + return UnaryOperationKind.IntegerPlus; + case UnaryOperatorKind.Float: + case UnaryOperatorKind.Double: + return UnaryOperationKind.FloatingPlus; + case UnaryOperatorKind.Decimal: + return UnaryOperationKind.DecimalPlus; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicPlus; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodPlus; + } - public override void Accept(OperationVisitor visitor) - { - visitor.VisitInvocationExpression(this); - } + break; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitInvocationExpression(this, argument); - } - - internal static ImmutableArray DeriveArguments(ImmutableArray boundArguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentsToParametersOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray parameters, SyntaxNode invocationSyntax) - { - ArrayBuilder arguments = ArrayBuilder.GetInstance(boundArguments.Length); - for (int parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++) - { - int argumentIndex = -1; - if (argumentsToParametersOpt.IsDefault) - { - argumentIndex = parameterIndex; - } - else - { - argumentIndex = argumentsToParametersOpt.IndexOf(parameterIndex); - } + case UnaryOperatorKind.UnaryMinus: + switch (operatorKind & UnaryOperatorKind.TypeMask) + { + case UnaryOperatorKind.Int: + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.ULong: + return UnaryOperationKind.IntegerMinus; + case UnaryOperatorKind.Float: + case UnaryOperatorKind.Double: + return UnaryOperationKind.FloatingMinus; + case UnaryOperatorKind.Decimal: + return UnaryOperationKind.DecimalMinus; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicMinus; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodMinus; + } - if ((uint)argumentIndex >= (uint)boundArguments.Length) - { - // No argument has been supplied for the parameter at `parameterIndex`: - // 1. `argumentIndex == -1' when the arguments are specified out of parameter order, and no argument is provided for parameter corresponding to `parameters[parameterIndex]`. - // 2. `argumentIndex >= boundArguments.Length` when the arguments are specified in parameter order, and no argument is provided at `parameterIndex`. + break; - Symbols.ParameterSymbol parameter = parameters[parameterIndex]; - if (parameter.HasExplicitDefaultValue) + case UnaryOperatorKind.LogicalNegation: + switch (operatorKind & UnaryOperatorKind.TypeMask) { - // The parameter is optional with a default value. - arguments.Add(new Argument(ArgumentKind.DefaultValue, parameter, new LiteralExpression(parameter.ExplicitDefaultConstantValue, parameter.Type, invocationSyntax))); + case UnaryOperatorKind.Bool: + return UnaryOperationKind.BooleanLogicalNot; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicLogicalNot; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodLogicalNot; } - else + + break; + case UnaryOperatorKind.BitwiseComplement: + switch (operatorKind & UnaryOperatorKind.TypeMask) { - // If the invocation is semantically valid, the parameter will be a params array and an empty array will be provided. - // If the argument is otherwise omitted for a parameter with no default value, the invocation is not valid and a null argument will be provided. - arguments.Add(DeriveArgument(parameterIndex, boundArguments.Length, boundArguments, argumentNamesOpt, argumentRefKindsOpt, parameters, invocationSyntax)); + case UnaryOperatorKind.Int: + case UnaryOperatorKind.UInt: + case UnaryOperatorKind.Long: + case UnaryOperatorKind.ULong: + return UnaryOperationKind.IntegerBitwiseNegation; + case UnaryOperatorKind.Bool: + return UnaryOperationKind.BooleanBitwiseNegation; + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicBitwiseNegation; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodBitwiseNegation; } - } - else - { - arguments.Add(DeriveArgument(parameterIndex, argumentIndex, boundArguments, argumentNamesOpt, argumentRefKindsOpt, parameters, invocationSyntax)); - } - } - - return arguments.ToImmutableAndFree(); - } - private static readonly ConditionalWeakTable s_argumentMappings = new ConditionalWeakTable(); + break; - private static IArgument DeriveArgument(int parameterIndex, int argumentIndex, ImmutableArray boundArguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray parameters, SyntaxNode invocationSyntax) - { - if ((uint)argumentIndex >= (uint)boundArguments.Length) - { - // Check for an omitted argument that becomes an empty params array. - if (parameters.Length > 0) - { - Symbols.ParameterSymbol lastParameter = parameters[parameters.Length - 1]; - if (lastParameter.IsParams) + case UnaryOperatorKind.True: + switch (operatorKind & UnaryOperatorKind.TypeMask) { - return new Argument(ArgumentKind.ParamArray, lastParameter, CreateParamArray(lastParameter, boundArguments, argumentIndex, invocationSyntax)); + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicTrue; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodTrue; } - } - - // There is no supplied argument and there is no params parameter. Any action is suspect at this point. - return new SimpleArgument(null, new InvalidExpression(invocationSyntax)); - } - return s_argumentMappings.GetValue( - boundArguments[argumentIndex], - (argument) => - { - string nameOpt = !argumentNamesOpt.IsDefaultOrEmpty ? argumentNamesOpt[argumentIndex] : null; - Symbols.ParameterSymbol parameterOpt = (uint)parameterIndex < (uint)parameters.Length ? parameters[parameterIndex] : null; + break; - if ((object)nameOpt == null) + case UnaryOperatorKind.False: + switch (operatorKind & UnaryOperatorKind.TypeMask) { - RefKind refMode = argumentRefKindsOpt.IsDefaultOrEmpty ? RefKind.None : argumentRefKindsOpt[argumentIndex]; - - if (refMode != RefKind.None) - { - return new Argument(ArgumentKind.Positional, parameterOpt, argument); - } - - if (argumentIndex >= parameters.Length - 1 && - parameters.Length > 0 && - parameters[parameters.Length - 1].IsParams && - // An argument that is an array of the appropriate type is not a params argument. - (boundArguments.Length > argumentIndex + 1 || - ((object)argument.Type != null && // If argument type is null, we are in an error scenario and cannot tell if it is a param array, or not. - (argument.Type.TypeKind != TypeKind.Array || - !argument.Type.Equals(parameters[parameters.Length - 1].Type, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds))))) - { - return new Argument(ArgumentKind.ParamArray, parameters[parameters.Length - 1], CreateParamArray(parameters[parameters.Length - 1], boundArguments, argumentIndex, invocationSyntax)); - } - else - { - return new SimpleArgument(parameterOpt, argument); - } + case UnaryOperatorKind.Dynamic: + return UnaryOperationKind.DynamicFalse; + case UnaryOperatorKind.UserDefined: + return UnaryOperationKind.OperatorMethodFalse; } - return new Argument(ArgumentKind.Named, parameterOpt, argument); - }); - } - - private static IOperation CreateParamArray(IParameterSymbol parameter, ImmutableArray boundArguments, int firstArgumentElementIndex, SyntaxNode invocationSyntax) - { - if (parameter.Type.TypeKind == TypeKind.Array) - { - IArrayTypeSymbol arrayType = (IArrayTypeSymbol)parameter.Type; - ArrayBuilder builder = ArrayBuilder.GetInstance(boundArguments.Length - firstArgumentElementIndex); - - for (int index = firstArgumentElementIndex; index < boundArguments.Length; index++) - { - builder.Add(boundArguments[index]); - } - var paramArrayArguments = builder.ToImmutableAndFree(); - - // Use the invocation syntax node if there is no actual syntax available for the argument (because the paramarray is empty.) - return new ArrayCreationExpression(arrayType, paramArrayArguments, paramArrayArguments.Length > 0 ? paramArrayArguments[0].Syntax : invocationSyntax); - } - - return new InvalidExpression(invocationSyntax); - } - - internal static IArgument ArgumentMatchingParameter(ImmutableArray arguments, ImmutableArray argumentsToParametersOpt, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ISymbol targetMethod, ImmutableArray parameters, IParameterSymbol parameter, SyntaxNode invocationSyntax) - { - int argumentIndex = ArgumentIndexMatchingParameter(argumentsToParametersOpt, targetMethod, parameter); - if (argumentIndex >= 0) - { - return DeriveArgument(parameter.Ordinal, argumentIndex, arguments, argumentNamesOpt, argumentRefKindsOpt, parameters, invocationSyntax); + break; } - return null; + return UnaryOperationKind.Invalid; } - private static int ArgumentIndexMatchingParameter(ImmutableArray argumentsToParametersOpt, ISymbol targetMethod, IParameterSymbol parameter) + internal static BinaryOperationKind DeriveBinaryOperationKind(BinaryOperatorKind operatorKind) { - if (parameter.ContainingSymbol == targetMethod) + switch (operatorKind & BinaryOperatorKind.OpMask) { - int parameterIndex = parameter.Ordinal; - if (!argumentsToParametersOpt.IsDefaultOrEmpty) - { - return argumentsToParametersOpt.IndexOf(parameterIndex); - } + case BinaryOperatorKind.Addition: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerAdd; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedAdd; + case BinaryOperatorKind.Double: + case BinaryOperatorKind.Float: + return BinaryOperationKind.FloatingAdd; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalAdd; + case BinaryOperatorKind.EnumAndUnderlying: + case BinaryOperatorKind.UnderlyingAndEnum: + return BinaryOperationKind.EnumAdd; + case BinaryOperatorKind.PointerAndInt: + case BinaryOperatorKind.PointerAndUInt: + case BinaryOperatorKind.PointerAndLong: + case BinaryOperatorKind.PointerAndULong: + return BinaryOperationKind.PointerIntegerAdd; + case BinaryOperatorKind.IntAndPointer: + case BinaryOperatorKind.UIntAndPointer: + case BinaryOperatorKind.LongAndPointer: + case BinaryOperatorKind.ULongAndPointer: + return BinaryOperationKind.IntegerPointerAdd; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicAdd; + case BinaryOperatorKind.String: + case BinaryOperatorKind.StringAndObject: + case BinaryOperatorKind.ObjectAndString: + return BinaryOperationKind.StringConcatenate; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodAdd; + } - return parameterIndex; - } + break; - return -1; - } + case BinaryOperatorKind.Subtraction: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerSubtract; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedSubtract; + case BinaryOperatorKind.Double: + case BinaryOperatorKind.Float: + return BinaryOperationKind.FloatingSubtract; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalSubtract; + case BinaryOperatorKind.EnumAndUnderlying: + case BinaryOperatorKind.UnderlyingAndEnum: + return BinaryOperationKind.EnumSubtract; + case BinaryOperatorKind.PointerAndInt: + case BinaryOperatorKind.PointerAndUInt: + case BinaryOperatorKind.PointerAndLong: + case BinaryOperatorKind.PointerAndULong: + return BinaryOperationKind.PointerIntegerSubtract; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerSubtract; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicSubtract; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodSubtract; + } - private abstract class ArgumentBase : IArgument - { - public ArgumentBase(IParameterSymbol parameter, IOperation value) - { - Debug.Assert(value != null); + break; - this.Value = value; - this.Parameter = parameter; - } - - public IParameterSymbol Parameter { get; } - - public IOperation Value { get; } - - IOperation IArgument.InConversion => null; - - IOperation IArgument.OutConversion => null; - - bool IOperation.IsInvalid => (object)this.Parameter == null || this.Value.IsInvalid; + case BinaryOperatorKind.Multiplication: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerMultiply; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedMultiply; + case BinaryOperatorKind.Double: + case BinaryOperatorKind.Float: + return BinaryOperationKind.FloatingMultiply; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalMultiply; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicMultiply; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodMultiply; + } - OperationKind IOperation.Kind => OperationKind.Argument; + break; - SyntaxNode IOperation.Syntax => this.Value?.Syntax; + case BinaryOperatorKind.Division: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerDivide; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedDivide; + case BinaryOperatorKind.Double: + case BinaryOperatorKind.Float: + return BinaryOperationKind.FloatingDivide; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalDivide; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicDivide; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodDivide; + } - public ITypeSymbol Type => null; + break; - public Optional ConstantValue => default(Optional); + case BinaryOperatorKind.Remainder: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerRemainder; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedRemainder; + case BinaryOperatorKind.Double: + case BinaryOperatorKind.Float: + return BinaryOperationKind.FloatingRemainder; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicRemainder; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodRemainder; + } - public abstract ArgumentKind ArgumentKind { get; } + break; - void IOperation.Accept(OperationVisitor visitor) - { - visitor.VisitArgument(this); - } + case BinaryOperatorKind.LeftShift: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerLeftShift; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedLeftShift; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicLeftShift; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodLeftShift; + } - TResult IOperation.Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitArgument(this, argument); - } - } + break; - private sealed class SimpleArgument : ArgumentBase - { - public SimpleArgument(IParameterSymbol parameter, IOperation value) - : base(parameter, value) - { } + case BinaryOperatorKind.RightShift: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerRightShift; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedRightShift; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicRightShift; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodRightShift; + } - public override ArgumentKind ArgumentKind => ArgumentKind.Positional; - } + break; - private sealed class Argument : ArgumentBase - { - public Argument(ArgumentKind kind, IParameterSymbol parameter, IOperation value) - : base(parameter, value) - { - this.ArgumentKind = kind; - } + case BinaryOperatorKind.And: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerAnd; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedAnd; + case BinaryOperatorKind.Bool: + if ((operatorKind & BinaryOperatorKind.Logical) != 0) + { + return BinaryOperationKind.BooleanConditionalAnd; + } - public override ArgumentKind ArgumentKind { get; } - } - } + return BinaryOperationKind.BooleanAnd; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumAnd; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicAnd; + case BinaryOperatorKind.UserDefined: + if ((operatorKind & BinaryOperatorKind.Logical) != 0) + { + return BinaryOperationKind.OperatorMethodConditionalAnd; + } - internal partial class BoundLocal : ILocalReferenceExpression - { - ILocalSymbol ILocalReferenceExpression.Local => this.LocalSymbol; + return BinaryOperationKind.OperatorMethodAnd; + } - protected override OperationKind ExpressionKind => OperationKind.LocalReferenceExpression; + break; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitLocalReferenceExpression(this); - } + case BinaryOperatorKind.Or: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerOr; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedOr; + case BinaryOperatorKind.Bool: + if ((operatorKind & BinaryOperatorKind.Logical) != 0) + { + return BinaryOperationKind.BooleanConditionalOr; + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitLocalReferenceExpression(this, argument); - } - } + return BinaryOperationKind.BooleanOr; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumOr; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicOr; + case BinaryOperatorKind.UserDefined: + if ((operatorKind & BinaryOperatorKind.Logical) != 0) + { + return BinaryOperationKind.OperatorMethodConditionalOr; + } - internal partial class BoundFieldAccess : IFieldReferenceExpression - { - IOperation IMemberReferenceExpression.Instance => this.FieldSymbol.IsStatic ? null : this.ReceiverOpt; + return BinaryOperationKind.OperatorMethodOr; + } - ISymbol IMemberReferenceExpression.Member => this.FieldSymbol; + break; - IFieldSymbol IFieldReferenceExpression.Field => this.FieldSymbol; + case BinaryOperatorKind.Xor: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerExclusiveOr; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedExclusiveOr; + case BinaryOperatorKind.Bool: + return BinaryOperationKind.BooleanExclusiveOr; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumExclusiveOr; + case BinaryOperatorKind.Dynamic: + return BinaryOperationKind.DynamicExclusiveOr; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodExclusiveOr; + } - protected override OperationKind ExpressionKind => OperationKind.FieldReferenceExpression; + break; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitFieldReferenceExpression(this); - } + case BinaryOperatorKind.LessThan: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerLessThan; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedLessThan; + case BinaryOperatorKind.Float: + case BinaryOperatorKind.Double: + return BinaryOperationKind.FloatingLessThan; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalLessThan; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerLessThan; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumLessThan; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodLessThan; + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitFieldReferenceExpression(this, argument); - } - } + break; - internal partial class BoundPropertyAccess : IPropertyReferenceExpression - { - IPropertySymbol IPropertyReferenceExpression.Property => this.PropertySymbol; - - IOperation IMemberReferenceExpression.Instance => this.PropertySymbol.IsStatic ? null : this.ReceiverOpt; - - ISymbol IMemberReferenceExpression.Member => this.PropertySymbol; - - protected override OperationKind ExpressionKind => OperationKind.PropertyReferenceExpression; + case BinaryOperatorKind.LessThanOrEqual: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerLessThanOrEqual; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedLessThanOrEqual; + case BinaryOperatorKind.Float: + case BinaryOperatorKind.Double: + return BinaryOperationKind.FloatingLessThanOrEqual; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalLessThanOrEqual; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerLessThanOrEqual; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumLessThanOrEqual; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodLessThanOrEqual; + } - public override void Accept(OperationVisitor visitor) - { - visitor.VisitPropertyReferenceExpression(this); - } + break; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitPropertyReferenceExpression(this, argument); - } - } + case BinaryOperatorKind.Equal: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.IntegerEquals; + case BinaryOperatorKind.Float: + case BinaryOperatorKind.Double: + return BinaryOperationKind.FloatingEquals; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalEquals; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerEquals; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumEquals; + case BinaryOperatorKind.Bool: + return BinaryOperationKind.BooleanEquals; + case BinaryOperatorKind.String: + return BinaryOperationKind.StringEquals; + case BinaryOperatorKind.Object: + return BinaryOperationKind.ObjectEquals; + case BinaryOperatorKind.Delegate: + return BinaryOperationKind.DelegateEquals; + case BinaryOperatorKind.NullableNull: + return BinaryOperationKind.NullableEquals; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodEquals; + } - internal partial class BoundIndexerAccess : IIndexedPropertyReferenceExpression - { - IPropertySymbol IPropertyReferenceExpression.Property => this.Indexer; + break; - IOperation IMemberReferenceExpression.Instance => this.Indexer.IsStatic ? null : this.ReceiverOpt; + case BinaryOperatorKind.NotEqual: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.IntegerNotEquals; + case BinaryOperatorKind.Float: + case BinaryOperatorKind.Double: + return BinaryOperationKind.FloatingNotEquals; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalNotEquals; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerNotEquals; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumNotEquals; + case BinaryOperatorKind.Bool: + return BinaryOperationKind.BooleanNotEquals; + case BinaryOperatorKind.String: + return BinaryOperationKind.StringNotEquals; + case BinaryOperatorKind.Object: + return BinaryOperationKind.ObjectNotEquals; + case BinaryOperatorKind.Delegate: + return BinaryOperationKind.DelegateNotEquals; + case BinaryOperatorKind.NullableNull: + return BinaryOperationKind.NullableNotEquals; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodNotEquals; + } - ISymbol IMemberReferenceExpression.Member => this.Indexer; + break; - ImmutableArray IHasArgumentsExpression.ArgumentsInParameterOrder => BoundCall.DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Indexer.Parameters, this.Syntax); + case BinaryOperatorKind.GreaterThanOrEqual: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerGreaterThanOrEqual; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedGreaterThanOrEqual; + case BinaryOperatorKind.Float: + case BinaryOperatorKind.Double: + return BinaryOperationKind.FloatingGreaterThanOrEqual; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalGreaterThanOrEqual; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerGreaterThanOrEqual; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumGreaterThanOrEqual; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodGreaterThanOrEqual; + } - IArgument IHasArgumentsExpression.GetArgumentMatchingParameter(IParameterSymbol parameter) - { - return BoundCall.ArgumentMatchingParameter(this.Arguments, this.ArgsToParamsOpt, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, this.Indexer, this.Indexer.Parameters, parameter, this.Syntax); - } + break; - protected override OperationKind ExpressionKind => OperationKind.IndexedPropertyReferenceExpression; + case BinaryOperatorKind.GreaterThan: + switch (operatorKind & BinaryOperatorKind.TypeMask) + { + case BinaryOperatorKind.Int: + case BinaryOperatorKind.Long: + return BinaryOperationKind.IntegerGreaterThan; + case BinaryOperatorKind.UInt: + case BinaryOperatorKind.ULong: + return BinaryOperationKind.UnsignedGreaterThan; + case BinaryOperatorKind.Float: + case BinaryOperatorKind.Double: + return BinaryOperationKind.FloatingGreaterThan; + case BinaryOperatorKind.Decimal: + return BinaryOperationKind.DecimalGreaterThan; + case BinaryOperatorKind.Pointer: + return BinaryOperationKind.PointerGreaterThan; + case BinaryOperatorKind.Enum: + return BinaryOperationKind.EnumGreaterThan; + case BinaryOperatorKind.UserDefined: + return BinaryOperationKind.OperatorMethodGreaterThan; + } - public override void Accept(OperationVisitor visitor) - { - visitor.VisitIndexedPropertyReferenceExpression(this); - } + break; + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitIndexedPropertyReferenceExpression(this, argument); + return BinaryOperationKind.Invalid; } } - internal partial class BoundEventAccess : IEventReferenceExpression +#if false + internal partial class BoundExpression : IOperation { - IEventSymbol IEventReferenceExpression.Event => this.EventSymbol; - - IOperation IMemberReferenceExpression.Instance => this.EventSymbol.IsStatic ? null : this.ReceiverOpt; - - ISymbol IMemberReferenceExpression.Member => this.EventSymbol; + ITypeSymbol IOperation.Type => this.Type; - protected override OperationKind ExpressionKind => OperationKind.EventReferenceExpression; + OperationKind IOperation.Kind => this.ExpressionKind; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitEventReferenceExpression(this); - } + bool IOperation.IsInvalid => this.HasErrors; - public override TResult Accept(OperationVisitor visitor, TArgument argument) + Optional IOperation.ConstantValue { - return visitor.VisitEventReferenceExpression(this, argument); + get + { + ConstantValue value = this.ConstantValue; + return value != null ? new Optional(value.Value) : default(Optional); + } } - } - - internal partial class BoundEventAssignmentOperator : IEventAssignmentExpression - { - IEventSymbol IEventAssignmentExpression.Event => this.Event; + SyntaxNode IOperation.Syntax => this.Syntax; - IOperation IEventAssignmentExpression.EventInstance => this.Event.IsStatic ? null : this.ReceiverOpt; + protected abstract OperationKind ExpressionKind { get; } - IOperation IEventAssignmentExpression.HandlerValue => this.Argument; + public abstract void Accept(OperationVisitor visitor); - bool IEventAssignmentExpression.Adds => this.IsAddition; + public abstract TResult Accept(OperationVisitor visitor, TArgument argument); + } - protected override OperationKind ExpressionKind => OperationKind.EventAssignmentExpression; + internal sealed partial class BoundDeconstructValuePlaceholder : BoundValuePlaceholderBase, IPlaceholderExpression + { + protected override OperationKind ExpressionKind => OperationKind.PlaceholderExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitEventAssignmentExpression(this); + visitor.VisitPlaceholderExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitEventAssignmentExpression(this, argument); + return visitor.VisitPlaceholderExpression(this, argument); } } - internal partial class BoundDelegateCreationExpression : IMethodBindingExpression + internal partial class BoundCall : IInvocationExpression { - IOperation IMemberReferenceExpression.Instance + IMethodSymbol IInvocationExpression.TargetMethod => this.Method; + + IOperation IInvocationExpression.Instance => ((object)this.Method == null || this.Method.IsStatic) ? null : this.ReceiverOpt; + + bool IInvocationExpression.IsVirtual => + (object)this.Method != null && + this.ReceiverOpt != null && + (this.Method.IsVirtual || this.Method.IsAbstract || this.Method.IsOverride) && + !this.ReceiverOpt.SuppressVirtualCalls; + + ImmutableArray IInvocationExpression.ArgumentsInSourceOrder { get { - BoundMethodGroup methodGroup = this.Argument as BoundMethodGroup; - if (methodGroup != null) + ArrayBuilder sourceOrderArguments = ArrayBuilder.GetInstance(this.Arguments.Length); + for (int argumentIndex = 0; argumentIndex < this.Arguments.Length; argumentIndex++) { - return methodGroup.InstanceOpt; + IArgument argument = DeriveArgument(this.ArgsToParamsOpt.IsDefault ? argumentIndex : this.ArgsToParamsOpt[argumentIndex], argumentIndex, this.Arguments, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, this.Method.Parameters, this.Syntax); + sourceOrderArguments.Add(argument); + if (argument.ArgumentKind == ArgumentKind.ParamArray) + { + break; + } } - return null; + return sourceOrderArguments.ToImmutableAndFree(); } } - bool IMethodBindingExpression.IsVirtual => - (object)this.MethodOpt != null && - (this.MethodOpt.IsVirtual || this.MethodOpt.IsAbstract || this.MethodOpt.IsOverride) && - !this.SuppressVirtualCalls; - - ISymbol IMemberReferenceExpression.Member => this.MethodOpt; - - IMethodSymbol IMethodBindingExpression.Method => this.MethodOpt; + ImmutableArray IHasArgumentsExpression.ArgumentsInParameterOrder => DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Method.Parameters, this.Syntax); - protected override OperationKind ExpressionKind => OperationKind.MethodBindingExpression; + IArgument IHasArgumentsExpression.GetArgumentMatchingParameter(IParameterSymbol parameter) + { + return ArgumentMatchingParameter(this.Arguments, this.ArgsToParamsOpt, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, parameter.ContainingSymbol, ((Symbols.MethodSymbol)parameter.ContainingSymbol).Parameters, parameter, this.Syntax); + } - // SyntaxNode for MethodBindingExpression is the argument of DelegateCreationExpression - SyntaxNode IOperation.Syntax => this.Argument.Syntax; + protected override OperationKind ExpressionKind => OperationKind.InvocationExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitMethodBindingExpression(this); + visitor.VisitInvocationExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitMethodBindingExpression(this, argument); - } - } - - internal partial class BoundParameter : IParameterReferenceExpression - { - IParameterSymbol IParameterReferenceExpression.Parameter => this.ParameterSymbol; - - protected override OperationKind ExpressionKind => OperationKind.ParameterReferenceExpression; - - public override void Accept(OperationVisitor visitor) - { - visitor.VisitParameterReferenceExpression(this); + return visitor.VisitInvocationExpression(this, argument); } - public override TResult Accept(OperationVisitor visitor, TArgument argument) + internal static ImmutableArray DeriveArguments(ImmutableArray boundArguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentsToParametersOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray parameters, SyntaxNode invocationSyntax) { - return visitor.VisitParameterReferenceExpression(this, argument); - } - } - - internal partial class BoundLiteral : ILiteralExpression - { - string ILiteralExpression.Text => this.Syntax.ToString(); + ArrayBuilder arguments = ArrayBuilder.GetInstance(boundArguments.Length); + for (int parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++) + { + int argumentIndex = -1; + if (argumentsToParametersOpt.IsDefault) + { + argumentIndex = parameterIndex; + } + else + { + argumentIndex = argumentsToParametersOpt.IndexOf(parameterIndex); + } - protected override OperationKind ExpressionKind => OperationKind.LiteralExpression; + if ((uint)argumentIndex >= (uint)boundArguments.Length) + { + // No argument has been supplied for the parameter at `parameterIndex`: + // 1. `argumentIndex == -1' when the arguments are specified out of parameter order, and no argument is provided for parameter corresponding to `parameters[parameterIndex]`. + // 2. `argumentIndex >= boundArguments.Length` when the arguments are specified in parameter order, and no argument is provided at `parameterIndex`. - public override void Accept(OperationVisitor visitor) - { - visitor.VisitLiteralExpression(this); - } + Symbols.ParameterSymbol parameter = parameters[parameterIndex]; + if (parameter.HasExplicitDefaultValue) + { + // The parameter is optional with a default value. + arguments.Add(new Argument(ArgumentKind.DefaultValue, parameter, OperationFactory.CreateLiteralExpression(parameter.ExplicitDefaultConstantValue, parameter.Type, invocationSyntax))); + } + else + { + // If the invocation is semantically valid, the parameter will be a params array and an empty array will be provided. + // If the argument is otherwise omitted for a parameter with no default value, the invocation is not valid and a null argument will be provided. + arguments.Add(DeriveArgument(parameterIndex, boundArguments.Length, boundArguments, argumentNamesOpt, argumentRefKindsOpt, parameters, invocationSyntax)); + } + } + else + { + arguments.Add(DeriveArgument(parameterIndex, argumentIndex, boundArguments, argumentNamesOpt, argumentRefKindsOpt, parameters, invocationSyntax)); + } + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitLiteralExpression(this, argument); + return arguments.ToImmutableAndFree(); } - } - internal partial class BoundTupleExpression - { - protected override OperationKind ExpressionKind => OperationKind.None; + private static readonly ConditionalWeakTable s_argumentMappings = new ConditionalWeakTable(); - public override void Accept(OperationVisitor visitor) + private static IArgument DeriveArgument(int parameterIndex, int argumentIndex, ImmutableArray boundArguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray parameters, SyntaxNode invocationSyntax) { - visitor.VisitNoneOperation(this); - } + if ((uint)argumentIndex >= (uint)boundArguments.Length) + { + // Check for an omitted argument that becomes an empty params array. + if (parameters.Length > 0) + { + Symbols.ParameterSymbol lastParameter = parameters[parameters.Length - 1]; + if (lastParameter.IsParams) + { + return new Argument(ArgumentKind.ParamArray, lastParameter, CreateParamArray(lastParameter, boundArguments, argumentIndex, invocationSyntax)); + } + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitNoneOperation(this, argument); - } - } + // There is no supplied argument and there is no params parameter. Any action is suspect at this point. + return new SimpleArgument(null, OperationFactory.CreateInvalidExpression(invocationSyntax)); + } - internal partial class BoundObjectCreationExpression : IObjectCreationExpression - { - private static readonly ConditionalWeakTable s_memberInitializersMappings = - new ConditionalWeakTable(); + return s_argumentMappings.GetValue( + boundArguments[argumentIndex], + (argument) => + { + string nameOpt = !argumentNamesOpt.IsDefaultOrEmpty ? argumentNamesOpt[argumentIndex] : null; + Symbols.ParameterSymbol parameterOpt = (uint)parameterIndex < (uint)parameters.Length ? parameters[parameterIndex] : null; - IMethodSymbol IObjectCreationExpression.Constructor => this.Constructor; + if ((object)nameOpt == null) + { + RefKind refMode = argumentRefKindsOpt.IsDefaultOrEmpty ? RefKind.None : argumentRefKindsOpt[argumentIndex]; - ImmutableArray IHasArgumentsExpression.ArgumentsInParameterOrder => BoundCall.DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Constructor.Parameters, this.Syntax); + if (refMode != RefKind.None) + { + return new Argument(ArgumentKind.Positional, parameterOpt, argument); + } - IArgument IHasArgumentsExpression.GetArgumentMatchingParameter(IParameterSymbol parameter) - { - return BoundCall.ArgumentMatchingParameter(this.Arguments, this.ArgsToParamsOpt, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, this.Constructor, this.Constructor.Parameters, parameter, this.Syntax); + if (argumentIndex >= parameters.Length - 1 && + parameters.Length > 0 && + parameters[parameters.Length - 1].IsParams && + // An argument that is an array of the appropriate type is not a params argument. + (boundArguments.Length > argumentIndex + 1 || + ((object)argument.Type != null && // If argument type is null, we are in an error scenario and cannot tell if it is a param array, or not. + (argument.Type.TypeKind != TypeKind.Array || + !argument.Type.Equals(parameters[parameters.Length - 1].Type, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds))))) + { + return new Argument(ArgumentKind.ParamArray, parameters[parameters.Length - 1], CreateParamArray(parameters[parameters.Length - 1], boundArguments, argumentIndex, invocationSyntax)); + } + else + { + return new SimpleArgument(parameterOpt, argument); + } + } + + return new Argument(ArgumentKind.Named, parameterOpt, argument); + }); } - ImmutableArray IObjectCreationExpression.MemberInitializers + private static IOperation CreateParamArray(IParameterSymbol parameter, ImmutableArray boundArguments, int firstArgumentElementIndex, SyntaxNode invocationSyntax) { - get + if (parameter.Type.TypeKind == TypeKind.Array) { - return (ImmutableArray)s_memberInitializersMappings.GetValue(this, - objectCreationExpression => - { - var objectInitializerExpression = this.InitializerExpressionOpt as BoundObjectInitializerExpression; - if (objectInitializerExpression != null) - { - var builder = ArrayBuilder.GetInstance(objectInitializerExpression.Initializers.Length); - foreach (var memberAssignment in objectInitializerExpression.Initializers) - { - var assignment = memberAssignment as BoundAssignmentOperator; - var leftSymbol = (assignment?.Left as BoundObjectInitializerMember)?.MemberSymbol; + IArrayTypeSymbol arrayType = (IArrayTypeSymbol)parameter.Type; + ArrayBuilder builder = ArrayBuilder.GetInstance(boundArguments.Length - firstArgumentElementIndex); - if ((object)leftSymbol == null) - { - continue; - } + for (int index = firstArgumentElementIndex; index < boundArguments.Length; index++) + { + builder.Add(boundArguments[index]); + } + var paramArrayArguments = builder.ToImmutableAndFree(); - switch (leftSymbol.Kind) - { - case SymbolKind.Field: - builder.Add(new FieldInitializer(assignment.Syntax, (IFieldSymbol)leftSymbol, assignment.Right)); - break; - case SymbolKind.Property: - builder.Add(new PropertyInitializer(assignment.Syntax, (IPropertySymbol)leftSymbol, assignment.Right)); - break; - } - } - return builder.ToImmutableAndFree(); - } - return ImmutableArray.Empty; - }); + // Use the invocation syntax node if there is no actual syntax available for the argument (because the paramarray is empty.) + return OperationFactory.CreateArrayCreationExpression(arrayType, paramArrayArguments, paramArrayArguments.Length > 0 ? paramArrayArguments[0].Syntax : invocationSyntax); } - } - - protected override OperationKind ExpressionKind => OperationKind.ObjectCreationExpression; - - public override void Accept(OperationVisitor visitor) - { - visitor.VisitObjectCreationExpression(this); - } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitObjectCreationExpression(this, argument); + return OperationFactory.CreateInvalidExpression(invocationSyntax); } - private sealed class FieldInitializer : IFieldInitializer + internal static IArgument ArgumentMatchingParameter(ImmutableArray arguments, ImmutableArray argumentsToParametersOpt, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ISymbol targetMethod, ImmutableArray parameters, IParameterSymbol parameter, SyntaxNode invocationSyntax) { - public FieldInitializer(SyntaxNode syntax, IFieldSymbol initializedField, IOperation value) + int argumentIndex = ArgumentIndexMatchingParameter(argumentsToParametersOpt, targetMethod, parameter); + if (argumentIndex >= 0) { - this.Syntax = syntax; - this.InitializedField = initializedField; - this.Value = value; + return DeriveArgument(parameter.Ordinal, argumentIndex, arguments, argumentNamesOpt, argumentRefKindsOpt, parameters, invocationSyntax); } - public IFieldSymbol InitializedField { get; } - - public ImmutableArray InitializedFields => ImmutableArray.Create(this.InitializedField); - - public IOperation Value { get; } - - OperationKind IOperation.Kind => OperationKind.FieldInitializerInCreation; - - public SyntaxNode Syntax { get; } - - bool IOperation.IsInvalid => this.Value.IsInvalid || (object)this.InitializedField == null; - - public ITypeSymbol Type => null; - - public Optional ConstantValue => default(Optional); + return null; + } - void IOperation.Accept(OperationVisitor visitor) + private static int ArgumentIndexMatchingParameter(ImmutableArray argumentsToParametersOpt, ISymbol targetMethod, IParameterSymbol parameter) + { + if (parameter.ContainingSymbol == targetMethod) { - visitor.VisitFieldInitializer(this); - } + int parameterIndex = parameter.Ordinal; + if (!argumentsToParametersOpt.IsDefaultOrEmpty) + { + return argumentsToParametersOpt.IndexOf(parameterIndex); + } - TResult IOperation.Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitFieldInitializer(this, argument); + return parameterIndex; } + + return -1; } - private sealed class PropertyInitializer : IPropertyInitializer + private abstract class ArgumentBase : IArgument { - public PropertyInitializer(SyntaxNode syntax, IPropertySymbol initializedProperty, IOperation value) + public ArgumentBase(IParameterSymbol parameter, IOperation value) { - this.Syntax = syntax; - this.InitializedProperty = initializedProperty; + Debug.Assert(value != null); + this.Value = value; + this.Parameter = parameter; } - public IPropertySymbol InitializedProperty { get; } + public IParameterSymbol Parameter { get; } public IOperation Value { get; } - OperationKind IOperation.Kind => OperationKind.PropertyInitializerInCreation; + IOperation IArgument.InConversion => null; - public SyntaxNode Syntax { get; } + IOperation IArgument.OutConversion => null; - bool IOperation.IsInvalid => this.Value.IsInvalid || (object)this.InitializedProperty == null; + bool IOperation.IsInvalid => (object)this.Parameter == null || this.Value.IsInvalid; + + OperationKind IOperation.Kind => OperationKind.Argument; + + SyntaxNode IOperation.Syntax => this.Value?.Syntax; public ITypeSymbol Type => null; public Optional ConstantValue => default(Optional); + public abstract ArgumentKind ArgumentKind { get; } + void IOperation.Accept(OperationVisitor visitor) { - visitor.VisitPropertyInitializer(this); + visitor.VisitArgument(this); } TResult IOperation.Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitPropertyInitializer(this, argument); + return visitor.VisitArgument(this, argument); } } - } - internal partial class UnboundLambda : IUnboundLambdaExpression - { - protected override OperationKind ExpressionKind => OperationKind.UnboundLambdaExpression; - - public override void Accept(OperationVisitor visitor) + private sealed class SimpleArgument : ArgumentBase { - visitor.VisitUnboundLambdaExpression(this); + public SimpleArgument(IParameterSymbol parameter, IOperation value) + : base(parameter, value) + { } + + public override ArgumentKind ArgumentKind => ArgumentKind.Positional; } - public override TResult Accept(OperationVisitor visitor, TArgument argument) + private sealed class Argument : ArgumentBase { - return visitor.VisitUnboundLambdaExpression(this, argument); + public Argument(ArgumentKind kind, IParameterSymbol parameter, IOperation value) + : base(parameter, value) + { + this.ArgumentKind = kind; + } + + public override ArgumentKind ArgumentKind { get; } } } - internal partial class BoundLambda : ILambdaExpression + internal partial class BoundLocal : ILocalReferenceExpression { - IMethodSymbol ILambdaExpression.Signature => this.Symbol; - - IBlockStatement ILambdaExpression.Body => this.Body; + ILocalSymbol ILocalReferenceExpression.Local => this.LocalSymbol; - protected override OperationKind ExpressionKind => OperationKind.LambdaExpression; + protected override OperationKind ExpressionKind => OperationKind.LocalReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitLambdaExpression(this); + visitor.VisitLocalReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitLambdaExpression(this, argument); + return visitor.VisitLocalReferenceExpression(this, argument); } } - internal partial class BoundConversion : IConversionExpression, IMethodBindingExpression + internal partial class BoundFieldAccess : IFieldReferenceExpression { - IOperation IConversionExpression.Operand => this.Operand; + IOperation IMemberReferenceExpression.Instance => this.FieldSymbol.IsStatic ? null : this.ReceiverOpt; - Semantics.ConversionKind IConversionExpression.ConversionKind - { - get - { - switch (this.ConversionKind) - { - case CSharp.ConversionKind.ExplicitUserDefined: - case CSharp.ConversionKind.ImplicitUserDefined: - return Semantics.ConversionKind.OperatorMethod; + ISymbol IMemberReferenceExpression.Member => this.FieldSymbol; - case CSharp.ConversionKind.ExplicitReference: - case CSharp.ConversionKind.ImplicitReference: - case CSharp.ConversionKind.Boxing: - case CSharp.ConversionKind.Unboxing: - case CSharp.ConversionKind.Identity: - return Semantics.ConversionKind.Cast; + IFieldSymbol IFieldReferenceExpression.Field => this.FieldSymbol; - case CSharp.ConversionKind.AnonymousFunction: - case CSharp.ConversionKind.ExplicitDynamic: - case CSharp.ConversionKind.ImplicitDynamic: - case CSharp.ConversionKind.ExplicitEnumeration: - case CSharp.ConversionKind.ImplicitEnumeration: - case CSharp.ConversionKind.ImplicitThrow: - case CSharp.ConversionKind.ImplicitTupleLiteral: - case CSharp.ConversionKind.ImplicitTuple: - case CSharp.ConversionKind.ExplicitTupleLiteral: - case CSharp.ConversionKind.ExplicitTuple: - case CSharp.ConversionKind.ExplicitNullable: - case CSharp.ConversionKind.ImplicitNullable: - case CSharp.ConversionKind.ExplicitNumeric: - case CSharp.ConversionKind.ImplicitNumeric: - case CSharp.ConversionKind.ImplicitConstant: - case CSharp.ConversionKind.IntegerToPointer: - case CSharp.ConversionKind.IntPtr: - case CSharp.ConversionKind.NullLiteral: - case CSharp.ConversionKind.NullToPointer: - case CSharp.ConversionKind.PointerToInteger: - case CSharp.ConversionKind.PointerToPointer: - case CSharp.ConversionKind.PointerToVoid: - return Semantics.ConversionKind.CSharp; + protected override OperationKind ExpressionKind => OperationKind.FieldReferenceExpression; - default: - return Semantics.ConversionKind.Invalid; - } - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitFieldReferenceExpression(this); } - bool IConversionExpression.IsExplicit => this.ExplicitCastInCode; - - IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.SymbolOpt; - - bool IHasOperatorMethodExpression.UsesOperatorMethod => this.ConversionKind == CSharp.ConversionKind.ExplicitUserDefined || this.ConversionKind == CSharp.ConversionKind.ImplicitUserDefined; - - // Consider introducing a different bound node type for method group conversions. These aren't truly conversions, but represent selection of a particular method. - protected override OperationKind ExpressionKind => this.ConversionKind == ConversionKind.MethodGroup ? OperationKind.MethodBindingExpression : OperationKind.ConversionExpression; - - IMethodSymbol IMethodBindingExpression.Method => this.ConversionKind == ConversionKind.MethodGroup ? this.SymbolOpt : null; - - bool IMethodBindingExpression.IsVirtual + public override TResult Accept(OperationVisitor visitor, TArgument argument) { - get - { - var method = this.SymbolOpt; - return (object)method != null && - (method.IsAbstract || method.IsOverride || method.IsVirtual) && - !this.SuppressVirtualCalls; - } + return visitor.VisitFieldReferenceExpression(this, argument); } + } - IOperation IMemberReferenceExpression.Instance - { - get - { - if (this.ConversionKind == ConversionKind.MethodGroup) - { - BoundMethodGroup methodGroup = this.Operand as BoundMethodGroup; - if (methodGroup != null) - { - return methodGroup.InstanceOpt; - } - } + internal partial class BoundPropertyAccess : IPropertyReferenceExpression + { + IPropertySymbol IPropertyReferenceExpression.Property => this.PropertySymbol; - return null; - } - } + IOperation IMemberReferenceExpression.Instance => this.PropertySymbol.IsStatic ? null : this.ReceiverOpt; - ISymbol IMemberReferenceExpression.Member => ((IMethodBindingExpression)this).Method; + ISymbol IMemberReferenceExpression.Member => this.PropertySymbol; + + protected override OperationKind ExpressionKind => OperationKind.PropertyReferenceExpression; public override void Accept(OperationVisitor visitor) { - if (this.ExpressionKind == OperationKind.MethodBindingExpression) - { - visitor.VisitMethodBindingExpression(this); - } - else - { - visitor.VisitConversionExpression(this); - } + visitor.VisitPropertyReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return this.ExpressionKind == OperationKind.MethodBindingExpression - ? visitor.VisitMethodBindingExpression(this, argument) - : visitor.VisitConversionExpression(this, argument); + return visitor.VisitPropertyReferenceExpression(this, argument); } } - internal partial class BoundAsOperator : IConversionExpression + internal partial class BoundIndexerAccess : IIndexedPropertyReferenceExpression { - IOperation IConversionExpression.Operand => this.Operand; + IPropertySymbol IPropertyReferenceExpression.Property => this.Indexer; - Semantics.ConversionKind IConversionExpression.ConversionKind => Semantics.ConversionKind.TryCast; + IOperation IMemberReferenceExpression.Instance => this.Indexer.IsStatic ? null : this.ReceiverOpt; - bool IConversionExpression.IsExplicit => true; + ISymbol IMemberReferenceExpression.Member => this.Indexer; - IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => null; + ImmutableArray IHasArgumentsExpression.ArgumentsInParameterOrder => BoundCall.DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Indexer.Parameters, this.Syntax); - bool IHasOperatorMethodExpression.UsesOperatorMethod => false; + IArgument IHasArgumentsExpression.GetArgumentMatchingParameter(IParameterSymbol parameter) + { + return BoundCall.ArgumentMatchingParameter(this.Arguments, this.ArgsToParamsOpt, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, this.Indexer, this.Indexer.Parameters, parameter, this.Syntax); + } - protected override OperationKind ExpressionKind => OperationKind.ConversionExpression; + protected override OperationKind ExpressionKind => OperationKind.IndexedPropertyReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitConversionExpression(this); + visitor.VisitIndexedPropertyReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitConversionExpression(this, argument); + return visitor.VisitIndexedPropertyReferenceExpression(this, argument); } } - internal partial class BoundIsOperator : IIsTypeExpression + internal partial class BoundEventAccess : IEventReferenceExpression { - IOperation IIsTypeExpression.Operand => this.Operand; + IEventSymbol IEventReferenceExpression.Event => this.EventSymbol; - ITypeSymbol IIsTypeExpression.IsType => this.TargetType.Type; + IOperation IMemberReferenceExpression.Instance => this.EventSymbol.IsStatic ? null : this.ReceiverOpt; - protected override OperationKind ExpressionKind => OperationKind.IsTypeExpression; + ISymbol IMemberReferenceExpression.Member => this.EventSymbol; + + protected override OperationKind ExpressionKind => OperationKind.EventReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitIsTypeExpression(this); + visitor.VisitEventReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitIsTypeExpression(this, argument); + return visitor.VisitEventReferenceExpression(this, argument); } } - internal partial class BoundSizeOfOperator : ISizeOfExpression + internal partial class BoundEventAssignmentOperator : IEventAssignmentExpression { - ITypeSymbol ITypeOperationExpression.TypeOperand => this.SourceType.Type; - - protected override OperationKind ExpressionKind => OperationKind.SizeOfExpression; + IEventSymbol IEventAssignmentExpression.Event => this.Event; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitSizeOfExpression(this); - } + IOperation IEventAssignmentExpression.EventInstance => this.Event.IsStatic ? null : this.ReceiverOpt; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitSizeOfExpression(this, argument); - } - } + IOperation IEventAssignmentExpression.HandlerValue => this.Argument; - internal partial class BoundTypeOfOperator : ITypeOfExpression - { - ITypeSymbol ITypeOperationExpression.TypeOperand => this.SourceType.Type; + bool IEventAssignmentExpression.Adds => this.IsAddition; - protected override OperationKind ExpressionKind => OperationKind.TypeOfExpression; + protected override OperationKind ExpressionKind => OperationKind.EventAssignmentExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitTypeOfExpression(this); + visitor.VisitEventAssignmentExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitTypeOfExpression(this, argument); + return visitor.VisitEventAssignmentExpression(this, argument); } } - internal partial class BoundArrayCreation : IArrayCreationExpression + internal partial class BoundDelegateCreationExpression : IMethodBindingExpression { - ITypeSymbol IArrayCreationExpression.ElementType + IOperation IMemberReferenceExpression.Instance { get { - IArrayTypeSymbol arrayType = this.Type as IArrayTypeSymbol; - if ((object)arrayType != null) + BoundMethodGroup methodGroup = this.Argument as BoundMethodGroup; + if (methodGroup != null) { - return arrayType.ElementType; + return methodGroup.InstanceOpt; } return null; } } - ImmutableArray IArrayCreationExpression.DimensionSizes => this.Bounds.As(); + bool IMethodBindingExpression.IsVirtual => + (object)this.MethodOpt != null && + (this.MethodOpt.IsVirtual || this.MethodOpt.IsAbstract || this.MethodOpt.IsOverride) && + !this.SuppressVirtualCalls; - IArrayInitializer IArrayCreationExpression.Initializer => this.InitializerOpt; + ISymbol IMemberReferenceExpression.Member => this.MethodOpt; - protected override OperationKind ExpressionKind => OperationKind.ArrayCreationExpression; + IMethodSymbol IMethodBindingExpression.Method => this.MethodOpt; + + protected override OperationKind ExpressionKind => OperationKind.MethodBindingExpression; + + // SyntaxNode for MethodBindingExpression is the argument of DelegateCreationExpression + SyntaxNode IOperation.Syntax => this.Argument.Syntax; public override void Accept(OperationVisitor visitor) { - visitor.VisitArrayCreationExpression(this); + visitor.VisitMethodBindingExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitArrayCreationExpression(this, argument); + return visitor.VisitMethodBindingExpression(this, argument); } } - internal partial class BoundArrayInitialization : IArrayInitializer + internal partial class BoundParameter : IParameterReferenceExpression { - public ImmutableArray ElementValues => this.Initializers.As(); + IParameterSymbol IParameterReferenceExpression.Parameter => this.ParameterSymbol; - protected override OperationKind ExpressionKind => OperationKind.ArrayInitializer; + protected override OperationKind ExpressionKind => OperationKind.ParameterReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitArrayInitializer(this); + visitor.VisitParameterReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitArrayInitializer(this, argument); + return visitor.VisitParameterReferenceExpression(this, argument); } } - internal partial class BoundDefaultOperator : IDefaultValueExpression + internal partial class BoundLiteral : ILiteralExpression { - protected override OperationKind ExpressionKind => OperationKind.DefaultValueExpression; + string ILiteralExpression.Text => this.Syntax.ToString(); + + protected override OperationKind ExpressionKind => OperationKind.LiteralExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitDefaultValueExpression(this); + visitor.VisitLiteralExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitDefaultValueExpression(this, argument); + return visitor.VisitLiteralExpression(this, argument); } } - internal partial class BoundDup + internal partial class BoundTupleExpression { protected override OperationKind ExpressionKind => OperationKind.None; @@ -969,741 +1240,910 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundBaseReference : IInstanceReferenceExpression + internal partial class BoundObjectCreationExpression : IObjectCreationExpression { - InstanceReferenceKind IInstanceReferenceExpression.InstanceReferenceKind => InstanceReferenceKind.BaseClass; - - protected override OperationKind ExpressionKind => OperationKind.InstanceReferenceExpression; - - public override void Accept(OperationVisitor visitor) - { - visitor.VisitInstanceReferenceExpression(this); - } - - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitInstanceReferenceExpression(this, argument); - } - } + private static readonly ConditionalWeakTable s_memberInitializersMappings = + new ConditionalWeakTable(); - internal partial class BoundThisReference : IInstanceReferenceExpression - { - InstanceReferenceKind IInstanceReferenceExpression.InstanceReferenceKind => this.Syntax.Kind() == SyntaxKind.ThisExpression ? InstanceReferenceKind.Explicit : InstanceReferenceKind.Implicit; + IMethodSymbol IObjectCreationExpression.Constructor => this.Constructor; - protected override OperationKind ExpressionKind => OperationKind.InstanceReferenceExpression; + ImmutableArray IHasArgumentsExpression.ArgumentsInParameterOrder => BoundCall.DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Constructor.Parameters, this.Syntax); - public override void Accept(OperationVisitor visitor) + IArgument IHasArgumentsExpression.GetArgumentMatchingParameter(IParameterSymbol parameter) { - visitor.VisitInstanceReferenceExpression(this); + return BoundCall.ArgumentMatchingParameter(this.Arguments, this.ArgsToParamsOpt, this.ArgumentNamesOpt, this.ArgumentRefKindsOpt, this.Constructor, this.Constructor.Parameters, parameter, this.Syntax); } - public override TResult Accept(OperationVisitor visitor, TArgument argument) + ImmutableArray IObjectCreationExpression.MemberInitializers { - return visitor.VisitInstanceReferenceExpression(this, argument); - } - } - - internal partial class BoundAssignmentOperator : IAssignmentExpression - { - IOperation IAssignmentExpression.Target => this.Left; - - IOperation IAssignmentExpression.Value => this.Right; - - protected override OperationKind ExpressionKind => OperationKind.AssignmentExpression; + get + { + return (ImmutableArray)s_memberInitializersMappings.GetValue(this, + objectCreationExpression => + { + var objectInitializerExpression = this.InitializerExpressionOpt as BoundObjectInitializerExpression; + if (objectInitializerExpression != null) + { + var builder = ArrayBuilder.GetInstance(objectInitializerExpression.Initializers.Length); + foreach (var memberAssignment in objectInitializerExpression.Initializers) + { + var assignment = memberAssignment as BoundAssignmentOperator; + var leftSymbol = (assignment?.Left as BoundObjectInitializerMember)?.MemberSymbol; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitAssignmentExpression(this); - } + if ((object)leftSymbol == null) + { + continue; + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitAssignmentExpression(this, argument); + switch (leftSymbol.Kind) + { + case SymbolKind.Field: + builder.Add(new FieldInitializer(assignment.Syntax, (IFieldSymbol)leftSymbol, assignment.Right)); + break; + case SymbolKind.Property: + builder.Add(new PropertyInitializer(assignment.Syntax, (IPropertySymbol)leftSymbol, assignment.Right)); + break; + } + } + return builder.ToImmutableAndFree(); + } + return ImmutableArray.Empty; + }); + } } - } - internal sealed partial class BoundDeconstructionAssignmentOperator : BoundExpression - { - // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) - protected override OperationKind ExpressionKind => OperationKind.None; + protected override OperationKind ExpressionKind => OperationKind.ObjectCreationExpression; public override void Accept(OperationVisitor visitor) { - // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) - visitor.VisitNoneOperation(this); + visitor.VisitObjectCreationExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitObjectCreationExpression(this, argument); } - } - internal partial class BoundCompoundAssignmentOperator : ICompoundAssignmentExpression - { - BinaryOperationKind ICompoundAssignmentExpression.BinaryOperationKind => Expression.DeriveBinaryOperationKind(this.Operator.Kind); + private sealed class FieldInitializer : IFieldInitializer + { + public FieldInitializer(SyntaxNode syntax, IFieldSymbol initializedField, IOperation value) + { + this.Syntax = syntax; + this.InitializedField = initializedField; + this.Value = value; + } - IOperation IAssignmentExpression.Target => this.Left; + public IFieldSymbol InitializedField { get; } - IOperation IAssignmentExpression.Value => this.Right; + public ImmutableArray InitializedFields => ImmutableArray.Create(this.InitializedField); - bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.Operator.Kind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined; + public IOperation Value { get; } - IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.Operator.Method; + OperationKind IOperation.Kind => OperationKind.FieldInitializerInCreation; - protected override OperationKind ExpressionKind => OperationKind.CompoundAssignmentExpression; + public SyntaxNode Syntax { get; } - public override void Accept(OperationVisitor visitor) - { - visitor.VisitCompoundAssignmentExpression(this); - } + bool IOperation.IsInvalid => this.Value.IsInvalid || (object)this.InitializedField == null; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitCompoundAssignmentExpression(this, argument); - } - } + public ITypeSymbol Type => null; - internal partial class BoundIncrementOperator : IIncrementExpression - { - UnaryOperationKind IIncrementExpression.IncrementOperationKind => Expression.DeriveUnaryOperationKind(this.OperatorKind); + public Optional ConstantValue => default(Optional); - BinaryOperationKind ICompoundAssignmentExpression.BinaryOperationKind => Expression.DeriveBinaryOperationKind(((IIncrementExpression)this).IncrementOperationKind); + void IOperation.Accept(OperationVisitor visitor) + { + visitor.VisitFieldInitializer(this); + } - IOperation IAssignmentExpression.Target => this.Operand; + TResult IOperation.Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitFieldInitializer(this, argument); + } + } - private static readonly ConditionalWeakTable s_incrementValueMappings = new ConditionalWeakTable(); + private sealed class PropertyInitializer : IPropertyInitializer + { + public PropertyInitializer(SyntaxNode syntax, IPropertySymbol initializedProperty, IOperation value) + { + this.Syntax = syntax; + this.InitializedProperty = initializedProperty; + this.Value = value; + } - IOperation IAssignmentExpression.Value => s_incrementValueMappings.GetValue(this, (increment) => new BoundLiteral(this.Syntax, Semantics.Expression.SynthesizeNumeric(increment.Type, 1), increment.Type)); + public IPropertySymbol InitializedProperty { get; } - bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined; + public IOperation Value { get; } - IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.MethodOpt; + OperationKind IOperation.Kind => OperationKind.PropertyInitializerInCreation; - protected override OperationKind ExpressionKind => OperationKind.IncrementExpression; + public SyntaxNode Syntax { get; } - public override void Accept(OperationVisitor visitor) - { - visitor.VisitIncrementExpression(this); - } + bool IOperation.IsInvalid => this.Value.IsInvalid || (object)this.InitializedProperty == null; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitIncrementExpression(this, argument); - } - } + public ITypeSymbol Type => null; - internal partial class BoundBadExpression : IInvalidExpression - { - protected override OperationKind ExpressionKind => OperationKind.InvalidExpression; + public Optional ConstantValue => default(Optional); - public override void Accept(OperationVisitor visitor) - { - visitor.VisitInvalidExpression(this); - } + void IOperation.Accept(OperationVisitor visitor) + { + visitor.VisitPropertyInitializer(this); + } - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitInvalidExpression(this, argument); + TResult IOperation.Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitPropertyInitializer(this, argument); + } } } - internal partial class BoundNewT : ITypeParameterObjectCreationExpression + internal partial class UnboundLambda : IUnboundLambdaExpression { - protected override OperationKind ExpressionKind => OperationKind.TypeParameterObjectCreationExpression; + protected override OperationKind ExpressionKind => OperationKind.UnboundLambdaExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitTypeParameterObjectCreationExpression(this); + visitor.VisitUnboundLambdaExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitTypeParameterObjectCreationExpression(this, argument); + return visitor.VisitUnboundLambdaExpression(this, argument); } } - internal partial class BoundUnaryOperator : IUnaryOperatorExpression + internal partial class BoundLambda : ILambdaExpression { - UnaryOperationKind IUnaryOperatorExpression.UnaryOperationKind => Expression.DeriveUnaryOperationKind(this.OperatorKind); - - IOperation IUnaryOperatorExpression.Operand => this.Operand; - - bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined; + IMethodSymbol ILambdaExpression.Signature => this.Symbol; - IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.MethodOpt; + IBlockStatement ILambdaExpression.Body => this.Body; - protected override OperationKind ExpressionKind => OperationKind.UnaryOperatorExpression; + protected override OperationKind ExpressionKind => OperationKind.LambdaExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitUnaryOperatorExpression(this); + visitor.VisitLambdaExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitUnaryOperatorExpression(this, argument); + return visitor.VisitLambdaExpression(this, argument); } } - internal partial class BoundBinaryOperator : IBinaryOperatorExpression + internal partial class BoundConversion : IConversionExpression, IMethodBindingExpression { - BinaryOperationKind IBinaryOperatorExpression.BinaryOperationKind => Expression.DeriveBinaryOperationKind(this.OperatorKind); - - IOperation IBinaryOperatorExpression.LeftOperand => this.Left; - - IOperation IBinaryOperatorExpression.RightOperand => this.Right; - - bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.OperatorKind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined; - - IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.MethodOpt; + IOperation IConversionExpression.Operand => this.Operand; - protected override OperationKind ExpressionKind + Semantics.ConversionKind IConversionExpression.ConversionKind { get { - switch (this.OperatorKind & BinaryOperatorKind.OpMask) + switch (this.ConversionKind) { - case BinaryOperatorKind.Addition: - case BinaryOperatorKind.Subtraction: - case BinaryOperatorKind.Multiplication: - case BinaryOperatorKind.Division: - case BinaryOperatorKind.Remainder: - case BinaryOperatorKind.LeftShift: - case BinaryOperatorKind.RightShift: - case BinaryOperatorKind.And: - case BinaryOperatorKind.Or: - case BinaryOperatorKind.Xor: - case BinaryOperatorKind.LessThan: - case BinaryOperatorKind.LessThanOrEqual: - case BinaryOperatorKind.Equal: - case BinaryOperatorKind.NotEqual: - case BinaryOperatorKind.GreaterThan: - case BinaryOperatorKind.GreaterThanOrEqual: - return OperationKind.BinaryOperatorExpression; - - default: - return OperationKind.InvalidExpression; - } - } - } + case CSharp.ConversionKind.ExplicitUserDefined: + case CSharp.ConversionKind.ImplicitUserDefined: + return Semantics.ConversionKind.OperatorMethod; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitBinaryOperatorExpression(this); - } + case CSharp.ConversionKind.ExplicitReference: + case CSharp.ConversionKind.ImplicitReference: + case CSharp.ConversionKind.Boxing: + case CSharp.ConversionKind.Unboxing: + case CSharp.ConversionKind.Identity: + return Semantics.ConversionKind.Cast; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitBinaryOperatorExpression(this, argument); + case CSharp.ConversionKind.AnonymousFunction: + case CSharp.ConversionKind.ExplicitDynamic: + case CSharp.ConversionKind.ImplicitDynamic: + case CSharp.ConversionKind.ExplicitEnumeration: + case CSharp.ConversionKind.ImplicitEnumeration: + case CSharp.ConversionKind.ImplicitThrow: + case CSharp.ConversionKind.ImplicitTupleLiteral: + case CSharp.ConversionKind.ImplicitTuple: + case CSharp.ConversionKind.ExplicitTupleLiteral: + case CSharp.ConversionKind.ExplicitTuple: + case CSharp.ConversionKind.ExplicitNullable: + case CSharp.ConversionKind.ImplicitNullable: + case CSharp.ConversionKind.ExplicitNumeric: + case CSharp.ConversionKind.ImplicitNumeric: + case CSharp.ConversionKind.ImplicitConstant: + case CSharp.ConversionKind.IntegerToPointer: + case CSharp.ConversionKind.IntPtr: + case CSharp.ConversionKind.NullLiteral: + case CSharp.ConversionKind.NullToPointer: + case CSharp.ConversionKind.PointerToInteger: + case CSharp.ConversionKind.PointerToPointer: + case CSharp.ConversionKind.PointerToVoid: + return Semantics.ConversionKind.CSharp; + + default: + return Semantics.ConversionKind.Invalid; + } + } } - } - internal partial class BoundConditionalOperator : IConditionalChoiceExpression - { - IOperation IConditionalChoiceExpression.Condition => this.Condition; + bool IConversionExpression.IsExplicit => this.ExplicitCastInCode; - IOperation IConditionalChoiceExpression.IfTrueValue => this.Consequence; + IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.SymbolOpt; - IOperation IConditionalChoiceExpression.IfFalseValue => this.Alternative; + bool IHasOperatorMethodExpression.UsesOperatorMethod => this.ConversionKind == CSharp.ConversionKind.ExplicitUserDefined || this.ConversionKind == CSharp.ConversionKind.ImplicitUserDefined; - protected override OperationKind ExpressionKind => OperationKind.ConditionalChoiceExpression; + // Consider introducing a different bound node type for method group conversions. These aren't truly conversions, but represent selection of a particular method. + protected override OperationKind ExpressionKind => this.ConversionKind == ConversionKind.MethodGroup ? OperationKind.MethodBindingExpression : OperationKind.ConversionExpression; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitConditionalChoiceExpression(this); - } + IMethodSymbol IMethodBindingExpression.Method => this.ConversionKind == ConversionKind.MethodGroup ? this.SymbolOpt : null; - public override TResult Accept(OperationVisitor visitor, TArgument argument) + bool IMethodBindingExpression.IsVirtual { - return visitor.VisitConditionalChoiceExpression(this, argument); + get + { + var method = this.SymbolOpt; + return (object)method != null && + (method.IsAbstract || method.IsOverride || method.IsVirtual) && + !this.SuppressVirtualCalls; + } } - } - internal partial class BoundNullCoalescingOperator : INullCoalescingExpression - { - IOperation INullCoalescingExpression.PrimaryOperand => this.LeftOperand; + IOperation IMemberReferenceExpression.Instance + { + get + { + if (this.ConversionKind == ConversionKind.MethodGroup) + { + BoundMethodGroup methodGroup = this.Operand as BoundMethodGroup; + if (methodGroup != null) + { + return methodGroup.InstanceOpt; + } + } - IOperation INullCoalescingExpression.SecondaryOperand => this.RightOperand; + return null; + } + } - protected override OperationKind ExpressionKind => OperationKind.NullCoalescingExpression; + ISymbol IMemberReferenceExpression.Member => ((IMethodBindingExpression)this).Method; public override void Accept(OperationVisitor visitor) { - visitor.VisitNullCoalescingExpression(this); + if (this.ExpressionKind == OperationKind.MethodBindingExpression) + { + visitor.VisitMethodBindingExpression(this); + } + else + { + visitor.VisitConversionExpression(this); + } } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNullCoalescingExpression(this, argument); + return this.ExpressionKind == OperationKind.MethodBindingExpression + ? visitor.VisitMethodBindingExpression(this, argument) + : visitor.VisitConversionExpression(this, argument); } } - internal partial class BoundAwaitExpression : IAwaitExpression + internal partial class BoundAsOperator : IConversionExpression { - IOperation IAwaitExpression.AwaitedValue => this.Expression; + IOperation IConversionExpression.Operand => this.Operand; - protected override OperationKind ExpressionKind => OperationKind.AwaitExpression; + Semantics.ConversionKind IConversionExpression.ConversionKind => Semantics.ConversionKind.TryCast; + + bool IConversionExpression.IsExplicit => true; + + IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => null; + + bool IHasOperatorMethodExpression.UsesOperatorMethod => false; + + protected override OperationKind ExpressionKind => OperationKind.ConversionExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitAwaitExpression(this); + visitor.VisitConversionExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitAwaitExpression(this, argument); + return visitor.VisitConversionExpression(this, argument); } } - internal partial class BoundArrayAccess : IArrayElementReferenceExpression + internal partial class BoundIsOperator : IIsTypeExpression { - IOperation IArrayElementReferenceExpression.ArrayReference => this.Expression; + IOperation IIsTypeExpression.Operand => this.Operand; - ImmutableArray IArrayElementReferenceExpression.Indices => this.Indices.As(); + ITypeSymbol IIsTypeExpression.IsType => this.TargetType.Type; - protected override OperationKind ExpressionKind => OperationKind.ArrayElementReferenceExpression; + protected override OperationKind ExpressionKind => OperationKind.IsTypeExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitArrayElementReferenceExpression(this); + visitor.VisitIsTypeExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitArrayElementReferenceExpression(this, argument); + return visitor.VisitIsTypeExpression(this, argument); } } - internal partial class BoundPointerIndirectionOperator : IPointerIndirectionReferenceExpression + internal partial class BoundSizeOfOperator : ISizeOfExpression { - IOperation IPointerIndirectionReferenceExpression.Pointer => this.Operand; + ITypeSymbol ITypeOperationExpression.TypeOperand => this.SourceType.Type; - protected override OperationKind ExpressionKind => OperationKind.PointerIndirectionReferenceExpression; + protected override OperationKind ExpressionKind => OperationKind.SizeOfExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitPointerIndirectionReferenceExpression(this); + visitor.VisitSizeOfExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitPointerIndirectionReferenceExpression(this, argument); + return visitor.VisitSizeOfExpression(this, argument); } } - internal partial class BoundAddressOfOperator : IAddressOfExpression + internal partial class BoundTypeOfOperator : ITypeOfExpression { - IOperation IAddressOfExpression.Reference => this.Operand; + ITypeSymbol ITypeOperationExpression.TypeOperand => this.SourceType.Type; - protected override OperationKind ExpressionKind => OperationKind.AddressOfExpression; + protected override OperationKind ExpressionKind => OperationKind.TypeOfExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitAddressOfExpression(this); + visitor.VisitTypeOfExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitAddressOfExpression(this, argument); + return visitor.VisitTypeOfExpression(this, argument); } } - internal partial class BoundImplicitReceiver : IInstanceReferenceExpression + internal partial class BoundArrayCreation : IArrayCreationExpression { - InstanceReferenceKind IInstanceReferenceExpression.InstanceReferenceKind => InstanceReferenceKind.Implicit; + ITypeSymbol IArrayCreationExpression.ElementType + { + get + { + IArrayTypeSymbol arrayType = this.Type as IArrayTypeSymbol; + if ((object)arrayType != null) + { + return arrayType.ElementType; + } - protected override OperationKind ExpressionKind => OperationKind.InstanceReferenceExpression; + return null; + } + } + + ImmutableArray IArrayCreationExpression.DimensionSizes => this.Bounds.As(); + + IArrayInitializer IArrayCreationExpression.Initializer => this.InitializerOpt; + + protected override OperationKind ExpressionKind => OperationKind.ArrayCreationExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitInstanceReferenceExpression(this); + visitor.VisitArrayCreationExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitInstanceReferenceExpression(this, argument); + return visitor.VisitArrayCreationExpression(this, argument); } } - internal partial class BoundConditionalAccess : IConditionalAccessExpression + internal partial class BoundArrayInitialization : IArrayInitializer { - IOperation IConditionalAccessExpression.ConditionalValue => this.AccessExpression; - - IOperation IConditionalAccessExpression.ConditionalInstance => this.Receiver; + public ImmutableArray ElementValues => this.Initializers.As(); - protected override OperationKind ExpressionKind => OperationKind.ConditionalAccessExpression; + protected override OperationKind ExpressionKind => OperationKind.ArrayInitializer; public override void Accept(OperationVisitor visitor) { - visitor.VisitConditionalAccessExpression(this); + visitor.VisitArrayInitializer(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitConditionalAccessExpression(this, argument); + return visitor.VisitArrayInitializer(this, argument); } } - internal partial class BoundConditionalReceiver : IConditionalAccessInstanceExpression + internal partial class BoundDefaultOperator : IDefaultValueExpression { - protected override OperationKind ExpressionKind => OperationKind.ConditionalAccessInstanceExpression; + protected override OperationKind ExpressionKind => OperationKind.DefaultValueExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitConditionalAccessInstanceExpression(this); + visitor.VisitDefaultValueExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitConditionalAccessInstanceExpression(this, argument); + return visitor.VisitDefaultValueExpression(this, argument); } } - internal partial class BoundEqualsValue : ISymbolInitializer + internal partial class BoundDup { - IOperation ISymbolInitializer.Value => this.Value; - - SyntaxNode IOperation.Syntax => this.Syntax; - - bool IOperation.IsInvalid => ((IOperation)this.Value).IsInvalid; - - OperationKind IOperation.Kind => this.OperationKind; - - protected abstract OperationKind OperationKind { get; } - - ITypeSymbol IOperation.Type => null; - - Optional IOperation.ConstantValue => default(Optional); + protected override OperationKind ExpressionKind => OperationKind.None; - public abstract void Accept(OperationVisitor visitor); + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - public abstract TResult Accept(OperationVisitor visitor, TArgument argument); + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } } - internal partial class BoundFieldEqualsValue : IFieldInitializer + internal partial class BoundBaseReference : IInstanceReferenceExpression { - ImmutableArray IFieldInitializer.InitializedFields => ImmutableArray.Create(this.Field); + InstanceReferenceKind IInstanceReferenceExpression.InstanceReferenceKind => InstanceReferenceKind.BaseClass; - protected override OperationKind OperationKind => OperationKind.FieldInitializerAtDeclaration; + protected override OperationKind ExpressionKind => OperationKind.InstanceReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitFieldInitializer(this); + visitor.VisitInstanceReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitFieldInitializer(this, argument); + return visitor.VisitInstanceReferenceExpression(this, argument); } } - internal partial class BoundPropertyEqualsValue : IPropertyInitializer + internal partial class BoundThisReference : IInstanceReferenceExpression { - IPropertySymbol IPropertyInitializer.InitializedProperty => this.Property; + InstanceReferenceKind IInstanceReferenceExpression.InstanceReferenceKind => this.Syntax.Kind() == SyntaxKind.ThisExpression ? InstanceReferenceKind.Explicit : InstanceReferenceKind.Implicit; - protected override OperationKind OperationKind => OperationKind.PropertyInitializerAtDeclaration; + protected override OperationKind ExpressionKind => OperationKind.InstanceReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitPropertyInitializer(this); + visitor.VisitInstanceReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitPropertyInitializer(this, argument); + return visitor.VisitInstanceReferenceExpression(this, argument); } } - internal partial class BoundParameterEqualsValue : IParameterInitializer + internal partial class BoundAssignmentOperator : IAssignmentExpression { - IParameterSymbol IParameterInitializer.Parameter => this.Parameter; + IOperation IAssignmentExpression.Target => this.Left; - protected override OperationKind OperationKind => OperationKind.ParameterInitializerAtDeclaration; + IOperation IAssignmentExpression.Value => this.Right; + + protected override OperationKind ExpressionKind => OperationKind.AssignmentExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitParameterInitializer(this); + visitor.VisitAssignmentExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitParameterInitializer(this, argument); + return visitor.VisitAssignmentExpression(this, argument); } } - internal partial class BoundDynamicIndexerAccess + internal sealed partial class BoundDeconstructionAssignmentOperator : BoundExpression { + // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) protected override OperationKind ExpressionKind => OperationKind.None; public override void Accept(OperationVisitor visitor) { + // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) visitor.VisitNoneOperation(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { + // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) return visitor.VisitNoneOperation(this, argument); } } - internal partial class BoundUserDefinedConditionalLogicalOperator + internal partial class BoundCompoundAssignmentOperator : ICompoundAssignmentExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + BinaryOperationKind ICompoundAssignmentExpression.BinaryOperationKind => Expression.DeriveBinaryOperationKind(this.Operator.Kind); + + IOperation IAssignmentExpression.Target => this.Left; + + IOperation IAssignmentExpression.Value => this.Right; + + bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.Operator.Kind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined; + + IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.Operator.Method; + + protected override OperationKind ExpressionKind => OperationKind.CompoundAssignmentExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitCompoundAssignmentExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitCompoundAssignmentExpression(this, argument); } } - internal partial class BoundAnonymousObjectCreationExpression + internal partial class BoundIncrementOperator : IIncrementExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + UnaryOperationKind IIncrementExpression.IncrementOperationKind => Expression.DeriveUnaryOperationKind(this.OperatorKind); + + BinaryOperationKind ICompoundAssignmentExpression.BinaryOperationKind => Expression.DeriveBinaryOperationKind(((IIncrementExpression)this).IncrementOperationKind); + + IOperation IAssignmentExpression.Target => this.Operand; + + private static readonly ConditionalWeakTable s_incrementValueMappings = new ConditionalWeakTable(); + + IOperation IAssignmentExpression.Value => s_incrementValueMappings.GetValue(this, (increment) => new BoundLiteral(this.Syntax, Semantics.Expression.SynthesizeNumeric(increment.Type, 1), increment.Type)); + + bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined; + + IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.MethodOpt; + + protected override OperationKind ExpressionKind => OperationKind.IncrementExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitIncrementExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitIncrementExpression(this, argument); } } - internal partial class BoundAnonymousPropertyDeclaration + internal partial class BoundBadExpression : IInvalidExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + protected override OperationKind ExpressionKind => OperationKind.InvalidExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitInvalidExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitInvalidExpression(this, argument); } } - internal partial class BoundAttribute + internal partial class BoundNewT : ITypeParameterObjectCreationExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + protected override OperationKind ExpressionKind => OperationKind.TypeParameterObjectCreationExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitTypeParameterObjectCreationExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitTypeParameterObjectCreationExpression(this, argument); } } - internal partial class BoundRangeVariable + internal partial class BoundUnaryOperator : IUnaryOperatorExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + UnaryOperationKind IUnaryOperatorExpression.UnaryOperationKind => Expression.DeriveUnaryOperationKind(this.OperatorKind); + + IOperation IUnaryOperatorExpression.Operand => this.Operand; + + bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined; + + IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.MethodOpt; + + protected override OperationKind ExpressionKind => OperationKind.UnaryOperatorExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitUnaryOperatorExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitUnaryOperatorExpression(this, argument); } } - internal partial class BoundLabel + internal partial class BoundBinaryOperator : IBinaryOperatorExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + BinaryOperationKind IBinaryOperatorExpression.BinaryOperationKind => Expression.DeriveBinaryOperationKind(this.OperatorKind); + + IOperation IBinaryOperatorExpression.LeftOperand => this.Left; + + IOperation IBinaryOperatorExpression.RightOperand => this.Right; + + bool IHasOperatorMethodExpression.UsesOperatorMethod => (this.OperatorKind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined; + + IMethodSymbol IHasOperatorMethodExpression.OperatorMethod => this.MethodOpt; + + protected override OperationKind ExpressionKind + { + get + { + switch (this.OperatorKind & BinaryOperatorKind.OpMask) + { + case BinaryOperatorKind.Addition: + case BinaryOperatorKind.Subtraction: + case BinaryOperatorKind.Multiplication: + case BinaryOperatorKind.Division: + case BinaryOperatorKind.Remainder: + case BinaryOperatorKind.LeftShift: + case BinaryOperatorKind.RightShift: + case BinaryOperatorKind.And: + case BinaryOperatorKind.Or: + case BinaryOperatorKind.Xor: + case BinaryOperatorKind.LessThan: + case BinaryOperatorKind.LessThanOrEqual: + case BinaryOperatorKind.Equal: + case BinaryOperatorKind.NotEqual: + case BinaryOperatorKind.GreaterThan: + case BinaryOperatorKind.GreaterThanOrEqual: + return OperationKind.BinaryOperatorExpression; + + default: + return OperationKind.InvalidExpression; + } + } + } public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitBinaryOperatorExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitBinaryOperatorExpression(this, argument); } } - internal partial class BoundObjectInitializerMember + internal partial class BoundConditionalOperator : IConditionalChoiceExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation IConditionalChoiceExpression.Condition => this.Condition; + + IOperation IConditionalChoiceExpression.IfTrueValue => this.Consequence; + + IOperation IConditionalChoiceExpression.IfFalseValue => this.Alternative; + + protected override OperationKind ExpressionKind => OperationKind.ConditionalChoiceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitConditionalChoiceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitConditionalChoiceExpression(this, argument); } } - internal partial class BoundQueryClause + internal partial class BoundNullCoalescingOperator : INullCoalescingExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation INullCoalescingExpression.PrimaryOperand => this.LeftOperand; + + IOperation INullCoalescingExpression.SecondaryOperand => this.RightOperand; + + protected override OperationKind ExpressionKind => OperationKind.NullCoalescingExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitNullCoalescingExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitNullCoalescingExpression(this, argument); } } - internal partial class BoundArgListOperator + internal partial class BoundAwaitExpression : IAwaitExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation IAwaitExpression.AwaitedValue => this.Expression; + + protected override OperationKind ExpressionKind => OperationKind.AwaitExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitAwaitExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitAwaitExpression(this, argument); } } - internal partial class BoundPropertyGroup + internal partial class BoundArrayAccess : IArrayElementReferenceExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation IArrayElementReferenceExpression.ArrayReference => this.Expression; + + ImmutableArray IArrayElementReferenceExpression.Indices => this.Indices.As(); + + protected override OperationKind ExpressionKind => OperationKind.ArrayElementReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitArrayElementReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitArrayElementReferenceExpression(this, argument); } } - internal partial class BoundCollectionElementInitializer + internal partial class BoundPointerIndirectionOperator : IPointerIndirectionReferenceExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation IPointerIndirectionReferenceExpression.Pointer => this.Operand; + + protected override OperationKind ExpressionKind => OperationKind.PointerIndirectionReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitPointerIndirectionReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitPointerIndirectionReferenceExpression(this, argument); } } - internal partial class BoundNameOfOperator + internal partial class BoundAddressOfOperator : IAddressOfExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation IAddressOfExpression.Reference => this.Operand; + + protected override OperationKind ExpressionKind => OperationKind.AddressOfExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitAddressOfExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitAddressOfExpression(this, argument); } } - internal partial class BoundMethodGroup + internal partial class BoundImplicitReceiver : IInstanceReferenceExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + InstanceReferenceKind IInstanceReferenceExpression.InstanceReferenceKind => InstanceReferenceKind.Implicit; + + protected override OperationKind ExpressionKind => OperationKind.InstanceReferenceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitInstanceReferenceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitInstanceReferenceExpression(this, argument); } } - internal partial class BoundTypeExpression + internal partial class BoundConditionalAccess : IConditionalAccessExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation IConditionalAccessExpression.ConditionalValue => this.AccessExpression; + + IOperation IConditionalAccessExpression.ConditionalInstance => this.Receiver; + + protected override OperationKind ExpressionKind => OperationKind.ConditionalAccessExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitConditionalAccessExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitConditionalAccessExpression(this, argument); } } - internal partial class BoundNamespaceExpression + internal partial class BoundConditionalReceiver : IConditionalAccessInstanceExpression { - protected override OperationKind ExpressionKind => OperationKind.None; + protected override OperationKind ExpressionKind => OperationKind.ConditionalAccessInstanceExpression; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitConditionalAccessInstanceExpression(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitConditionalAccessInstanceExpression(this, argument); } } - internal partial class BoundSequencePointExpression + internal partial class BoundEqualsValue : ISymbolInitializer { - protected override OperationKind ExpressionKind => OperationKind.None; + IOperation ISymbolInitializer.Value => this.Value; - public override void Accept(OperationVisitor visitor) - { - visitor.VisitNoneOperation(this); - } + SyntaxNode IOperation.Syntax => this.Syntax; - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - return visitor.VisitNoneOperation(this, argument); - } + bool IOperation.IsInvalid => ((IOperation)this.Value).IsInvalid; + + OperationKind IOperation.Kind => this.OperationKind; + + protected abstract OperationKind OperationKind { get; } + + ITypeSymbol IOperation.Type => null; + + Optional IOperation.ConstantValue => default(Optional); + + public abstract void Accept(OperationVisitor visitor); + + public abstract TResult Accept(OperationVisitor visitor, TArgument argument); } - internal partial class BoundSequence + internal partial class BoundFieldEqualsValue : IFieldInitializer { - protected override OperationKind ExpressionKind => OperationKind.None; + ImmutableArray IFieldInitializer.InitializedFields => ImmutableArray.Create(this.Field); + + protected override OperationKind OperationKind => OperationKind.FieldInitializerAtDeclaration; public override void Accept(OperationVisitor visitor) { - visitor.VisitNoneOperation(this); + visitor.VisitFieldInitializer(this); } public override TResult Accept(OperationVisitor visitor, TArgument argument) { - return visitor.VisitNoneOperation(this, argument); + return visitor.VisitFieldInitializer(this, argument); } } - internal partial class BoundPreviousSubmissionReference + internal partial class BoundPropertyEqualsValue : IPropertyInitializer + { + IPropertySymbol IPropertyInitializer.InitializedProperty => this.Property; + + protected override OperationKind OperationKind => OperationKind.PropertyInitializerAtDeclaration; + + public override void Accept(OperationVisitor visitor) + { + visitor.VisitPropertyInitializer(this); + } + + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitPropertyInitializer(this, argument); + } + } + + internal partial class BoundParameterEqualsValue : IParameterInitializer + { + IParameterSymbol IParameterInitializer.Parameter => this.Parameter; + + protected override OperationKind OperationKind => OperationKind.ParameterInitializerAtDeclaration; + + public override void Accept(OperationVisitor visitor) + { + visitor.VisitParameterInitializer(this); + } + + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitParameterInitializer(this, argument); + } + } + + internal partial class BoundDynamicIndexerAccess { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1718,7 +2158,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundHostObjectMemberReference + internal partial class BoundUserDefinedConditionalLogicalOperator { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1733,7 +2173,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundTypeOrValueExpression + internal partial class BoundAnonymousObjectCreationExpression { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1748,7 +2188,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundPseudoVariable + internal partial class BoundAnonymousPropertyDeclaration { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1763,7 +2203,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundPointerElementAccess + internal partial class BoundAttribute { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1778,7 +2218,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundRefTypeOperator + internal partial class BoundRangeVariable { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1793,7 +2233,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundDynamicMemberAccess + internal partial class BoundLabel { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1808,7 +2248,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundMakeRefOperator + internal partial class BoundObjectInitializerMember { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1823,7 +2263,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundRefValueOperator + internal partial class BoundQueryClause { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1838,7 +2278,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundDynamicInvocation + internal partial class BoundArgListOperator { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1853,7 +2293,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundArrayLength + internal partial class BoundPropertyGroup { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1868,7 +2308,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundMethodDefIndex + internal partial class BoundCollectionElementInitializer { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1883,7 +2323,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundModuleVersionId + internal partial class BoundNameOfOperator { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1898,7 +2338,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundModuleVersionIdString + internal partial class BoundMethodGroup { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1913,7 +2353,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundInstrumentationPayloadRoot + internal partial class BoundTypeExpression { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1928,7 +2368,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundMaximumMethodDefIndex + internal partial class BoundNamespaceExpression { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1942,8 +2382,8 @@ public override void Accept(OperationVisitor visitor) return visitor.VisitNoneOperation(this, argument); } } - - internal partial class BoundSourceDocumentIndex + + internal partial class BoundSequencePointExpression { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1958,7 +2398,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundMethodInfo + internal partial class BoundSequence { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1973,7 +2413,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundCollectionInitializerExpression + internal partial class BoundPreviousSubmissionReference { protected override OperationKind ExpressionKind => OperationKind.None; @@ -1988,7 +2428,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundFieldInfo + internal partial class BoundHostObjectMemberReference { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2003,7 +2443,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundLoweredConditionalAccess + internal partial class BoundTypeOrValueExpression { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2018,7 +2458,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundArgList + internal partial class BoundPseudoVariable { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2033,7 +2473,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundDynamicCollectionElementInitializer + internal partial class BoundPointerElementAccess { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2048,7 +2488,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundComplexConditionalReceiver + internal partial class BoundRefTypeOperator { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2063,7 +2503,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundFixedLocalCollectionInitializer + internal partial class BoundDynamicMemberAccess { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2078,7 +2518,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundStackAllocArrayCreation + internal partial class BoundMakeRefOperator { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2093,7 +2533,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundDynamicObjectCreationExpression + internal partial class BoundRefValueOperator { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2108,7 +2548,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundHoistedFieldAccess + internal partial class BoundDynamicInvocation { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2123,7 +2563,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundInterpolatedString + internal partial class BoundArrayLength { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2138,7 +2578,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundNoPiaObjectCreationExpression + internal partial class BoundMethodDefIndex { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2153,7 +2593,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundObjectInitializerExpression + internal partial class BoundModuleVersionId { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2168,7 +2608,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundStringInsert + internal partial class BoundModuleVersionIdString { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2183,7 +2623,7 @@ public override void Accept(OperationVisitor visitor) } } - internal partial class BoundDynamicObjectInitializerMember + internal partial class BoundInstrumentationPayloadRoot { protected override OperationKind ExpressionKind => OperationKind.None; @@ -2198,712 +2638,273 @@ public override void Accept(OperationVisitor visitor) } } - internal class Expression + internal partial class BoundMaximumMethodDefIndex { - internal static BinaryOperationKind DeriveBinaryOperationKind(UnaryOperationKind incrementKind) + protected override OperationKind ExpressionKind => OperationKind.None; + + public override void Accept(OperationVisitor visitor) { - switch (incrementKind) - { - case UnaryOperationKind.OperatorMethodPostfixIncrement: - case UnaryOperationKind.OperatorMethodPrefixIncrement: - return BinaryOperationKind.OperatorMethodAdd; - case UnaryOperationKind.OperatorMethodPostfixDecrement: - case UnaryOperationKind.OperatorMethodPrefixDecrement: - return BinaryOperationKind.OperatorMethodSubtract; - case UnaryOperationKind.IntegerPostfixIncrement: - case UnaryOperationKind.IntegerPrefixIncrement: - return BinaryOperationKind.IntegerAdd; - case UnaryOperationKind.IntegerPostfixDecrement: - case UnaryOperationKind.IntegerPrefixDecrement: - return BinaryOperationKind.IntegerSubtract; - case UnaryOperationKind.UnsignedPostfixIncrement: - case UnaryOperationKind.UnsignedPrefixIncrement: - return BinaryOperationKind.UnsignedAdd; - case UnaryOperationKind.UnsignedPostfixDecrement: - case UnaryOperationKind.UnsignedPrefixDecrement: - return BinaryOperationKind.UnsignedSubtract; - case UnaryOperationKind.FloatingPostfixIncrement: - case UnaryOperationKind.FloatingPrefixIncrement: - return BinaryOperationKind.FloatingAdd; - case UnaryOperationKind.FloatingPostfixDecrement: - case UnaryOperationKind.FloatingPrefixDecrement: - return BinaryOperationKind.FloatingSubtract; - case UnaryOperationKind.DecimalPostfixIncrement: - case UnaryOperationKind.DecimalPrefixIncrement: - return BinaryOperationKind.DecimalAdd; - case UnaryOperationKind.DecimalPostfixDecrement: - case UnaryOperationKind.DecimalPrefixDecrement: - return BinaryOperationKind.DecimalSubtract; - case UnaryOperationKind.EnumPostfixIncrement: - case UnaryOperationKind.EnumPrefixIncrement: - return BinaryOperationKind.EnumAdd; - case UnaryOperationKind.EnumPostfixDecrement: - case UnaryOperationKind.EnumPrefixDecrement: - return BinaryOperationKind.EnumSubtract; - case UnaryOperationKind.PointerPostfixIncrement: - case UnaryOperationKind.PointerPrefixIncrement: - return BinaryOperationKind.PointerIntegerAdd; - case UnaryOperationKind.PointerPostfixDecrement: - case UnaryOperationKind.PointerPrefixDecrement: - return BinaryOperationKind.PointerIntegerSubtract; - case UnaryOperationKind.DynamicPostfixIncrement: - case UnaryOperationKind.DynamicPrefixIncrement: - return BinaryOperationKind.DynamicAdd; - case UnaryOperationKind.DynamicPostfixDecrement: - case UnaryOperationKind.DynamicPrefixDecrement: - return BinaryOperationKind.DynamicSubtract; + visitor.VisitNoneOperation(this); + } - default: - return BinaryOperationKind.Invalid; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); } + } + + internal partial class BoundSourceDocumentIndex + { + protected override OperationKind ExpressionKind => OperationKind.None; - internal static UnaryOperationKind DeriveUnaryOperationKind(UnaryOperatorKind operatorKind) + public override void Accept(OperationVisitor visitor) { - switch (operatorKind & UnaryOperatorKind.OpMask) - { - case UnaryOperatorKind.PostfixIncrement: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.SByte: - case UnaryOperatorKind.Short: - return UnaryOperationKind.IntegerPostfixIncrement; - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.ULong: - case UnaryOperatorKind.Byte: - case UnaryOperatorKind.UShort: - case UnaryOperatorKind.Char: - return UnaryOperationKind.UnsignedPostfixIncrement; - case UnaryOperatorKind.Float: - case UnaryOperatorKind.Double: - return UnaryOperationKind.FloatingPostfixIncrement; - case UnaryOperatorKind.Decimal: - return UnaryOperationKind.DecimalPostfixIncrement; - case UnaryOperatorKind.Enum: - return UnaryOperationKind.EnumPostfixIncrement; - case UnaryOperatorKind.Pointer: - return UnaryOperationKind.PointerPostfixIncrement; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicPostfixIncrement; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodPostfixIncrement; - } + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case UnaryOperatorKind.PostfixDecrement: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.SByte: - case UnaryOperatorKind.Short: - return UnaryOperationKind.IntegerPostfixDecrement; - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.ULong: - case UnaryOperatorKind.Byte: - case UnaryOperatorKind.UShort: - case UnaryOperatorKind.Char: - return UnaryOperationKind.UnsignedPostfixDecrement; - case UnaryOperatorKind.Float: - case UnaryOperatorKind.Double: - return UnaryOperationKind.FloatingPostfixDecrement; - case UnaryOperatorKind.Decimal: - return UnaryOperationKind.DecimalPostfixDecrement; - case UnaryOperatorKind.Enum: - return UnaryOperationKind.EnumPostfixDecrement; - case UnaryOperatorKind.Pointer: - return UnaryOperationKind.PointerPostfixIncrement; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicPostfixDecrement; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodPostfixDecrement; - } + internal partial class BoundMethodInfo + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - case UnaryOperatorKind.PrefixIncrement: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.SByte: - case UnaryOperatorKind.Short: - return UnaryOperationKind.IntegerPrefixIncrement; - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.ULong: - case UnaryOperatorKind.Byte: - case UnaryOperatorKind.UShort: - case UnaryOperatorKind.Char: - return UnaryOperationKind.UnsignedPrefixIncrement; - case UnaryOperatorKind.Float: - case UnaryOperatorKind.Double: - return UnaryOperationKind.FloatingPrefixIncrement; - case UnaryOperatorKind.Decimal: - return UnaryOperationKind.DecimalPrefixIncrement; - case UnaryOperatorKind.Enum: - return UnaryOperationKind.EnumPrefixIncrement; - case UnaryOperatorKind.Pointer: - return UnaryOperationKind.PointerPrefixIncrement; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicPrefixIncrement; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodPrefixIncrement; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - break; + internal partial class BoundCollectionInitializerExpression + { + protected override OperationKind ExpressionKind => OperationKind.None; - case UnaryOperatorKind.PrefixDecrement: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.SByte: - case UnaryOperatorKind.Short: - return UnaryOperationKind.IntegerPrefixDecrement; - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.ULong: - case UnaryOperatorKind.Byte: - case UnaryOperatorKind.UShort: - case UnaryOperatorKind.Char: - return UnaryOperationKind.UnsignedPrefixDecrement; - case UnaryOperatorKind.Float: - case UnaryOperatorKind.Double: - return UnaryOperationKind.FloatingPrefixDecrement; - case UnaryOperatorKind.Decimal: - return UnaryOperationKind.DecimalPrefixDecrement; - case UnaryOperatorKind.Enum: - return UnaryOperationKind.EnumPrefixDecrement; - case UnaryOperatorKind.Pointer: - return UnaryOperationKind.PointerPrefixIncrement; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicPrefixDecrement; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodPrefixDecrement; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case UnaryOperatorKind.UnaryPlus: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.ULong: - return UnaryOperationKind.IntegerPlus; - case UnaryOperatorKind.Float: - case UnaryOperatorKind.Double: - return UnaryOperationKind.FloatingPlus; - case UnaryOperatorKind.Decimal: - return UnaryOperationKind.DecimalPlus; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicPlus; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodPlus; - } + internal partial class BoundFieldInfo + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - case UnaryOperatorKind.UnaryMinus: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.ULong: - return UnaryOperationKind.IntegerMinus; - case UnaryOperatorKind.Float: - case UnaryOperatorKind.Double: - return UnaryOperationKind.FloatingMinus; - case UnaryOperatorKind.Decimal: - return UnaryOperationKind.DecimalMinus; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicMinus; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodMinus; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - break; + internal partial class BoundLoweredConditionalAccess + { + protected override OperationKind ExpressionKind => OperationKind.None; - case UnaryOperatorKind.LogicalNegation: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Bool: - return UnaryOperationKind.BooleanLogicalNot; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicLogicalNot; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodLogicalNot; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - break; - case UnaryOperatorKind.BitwiseComplement: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Int: - case UnaryOperatorKind.UInt: - case UnaryOperatorKind.Long: - case UnaryOperatorKind.ULong: - return UnaryOperationKind.IntegerBitwiseNegation; - case UnaryOperatorKind.Bool: - return UnaryOperationKind.BooleanBitwiseNegation; - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicBitwiseNegation; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodBitwiseNegation; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - break; + internal partial class BoundArgList + { + protected override OperationKind ExpressionKind => OperationKind.None; - case UnaryOperatorKind.True: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicTrue; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodTrue; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case UnaryOperatorKind.False: - switch (operatorKind & UnaryOperatorKind.TypeMask) - { - case UnaryOperatorKind.Dynamic: - return UnaryOperationKind.DynamicFalse; - case UnaryOperatorKind.UserDefined: - return UnaryOperationKind.OperatorMethodFalse; - } + internal partial class BoundDynamicCollectionElementInitializer + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - return UnaryOperationKind.Invalid; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); } + } - internal static BinaryOperationKind DeriveBinaryOperationKind(BinaryOperatorKind operatorKind) + internal partial class BoundComplexConditionalReceiver + { + protected override OperationKind ExpressionKind => OperationKind.None; + + public override void Accept(OperationVisitor visitor) { - switch (operatorKind & BinaryOperatorKind.OpMask) - { - case BinaryOperatorKind.Addition: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerAdd; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedAdd; - case BinaryOperatorKind.Double: - case BinaryOperatorKind.Float: - return BinaryOperationKind.FloatingAdd; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalAdd; - case BinaryOperatorKind.EnumAndUnderlying: - case BinaryOperatorKind.UnderlyingAndEnum: - return BinaryOperationKind.EnumAdd; - case BinaryOperatorKind.PointerAndInt: - case BinaryOperatorKind.PointerAndUInt: - case BinaryOperatorKind.PointerAndLong: - case BinaryOperatorKind.PointerAndULong: - return BinaryOperationKind.PointerIntegerAdd; - case BinaryOperatorKind.IntAndPointer: - case BinaryOperatorKind.UIntAndPointer: - case BinaryOperatorKind.LongAndPointer: - case BinaryOperatorKind.ULongAndPointer: - return BinaryOperationKind.IntegerPointerAdd; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicAdd; - case BinaryOperatorKind.String: - case BinaryOperatorKind.StringAndObject: - case BinaryOperatorKind.ObjectAndString: - return BinaryOperationKind.StringConcatenate; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodAdd; - } + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case BinaryOperatorKind.Subtraction: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerSubtract; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedSubtract; - case BinaryOperatorKind.Double: - case BinaryOperatorKind.Float: - return BinaryOperationKind.FloatingSubtract; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalSubtract; - case BinaryOperatorKind.EnumAndUnderlying: - case BinaryOperatorKind.UnderlyingAndEnum: - return BinaryOperationKind.EnumSubtract; - case BinaryOperatorKind.PointerAndInt: - case BinaryOperatorKind.PointerAndUInt: - case BinaryOperatorKind.PointerAndLong: - case BinaryOperatorKind.PointerAndULong: - return BinaryOperationKind.PointerIntegerSubtract; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerSubtract; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicSubtract; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodSubtract; - } - - break; - - case BinaryOperatorKind.Multiplication: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerMultiply; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedMultiply; - case BinaryOperatorKind.Double: - case BinaryOperatorKind.Float: - return BinaryOperationKind.FloatingMultiply; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalMultiply; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicMultiply; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodMultiply; - } - - break; - - case BinaryOperatorKind.Division: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerDivide; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedDivide; - case BinaryOperatorKind.Double: - case BinaryOperatorKind.Float: - return BinaryOperationKind.FloatingDivide; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalDivide; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicDivide; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodDivide; - } - - break; - - case BinaryOperatorKind.Remainder: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerRemainder; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedRemainder; - case BinaryOperatorKind.Double: - case BinaryOperatorKind.Float: - return BinaryOperationKind.FloatingRemainder; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicRemainder; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodRemainder; - } - - break; - - case BinaryOperatorKind.LeftShift: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerLeftShift; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedLeftShift; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicLeftShift; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodLeftShift; - } + internal partial class BoundFixedLocalCollectionInitializer + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - case BinaryOperatorKind.RightShift: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerRightShift; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedRightShift; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicRightShift; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodRightShift; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - break; + internal partial class BoundStackAllocArrayCreation + { + protected override OperationKind ExpressionKind => OperationKind.None; - case BinaryOperatorKind.And: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerAnd; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedAnd; - case BinaryOperatorKind.Bool: - if ((operatorKind & BinaryOperatorKind.Logical) != 0) - { - return BinaryOperationKind.BooleanConditionalAnd; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - return BinaryOperationKind.BooleanAnd; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumAnd; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicAnd; - case BinaryOperatorKind.UserDefined: - if ((operatorKind & BinaryOperatorKind.Logical) != 0) - { - return BinaryOperationKind.OperatorMethodConditionalAnd; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - return BinaryOperationKind.OperatorMethodAnd; - } + internal partial class BoundDynamicObjectCreationExpression + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - case BinaryOperatorKind.Or: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerOr; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedOr; - case BinaryOperatorKind.Bool: - if ((operatorKind & BinaryOperatorKind.Logical) != 0) - { - return BinaryOperationKind.BooleanConditionalOr; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - return BinaryOperationKind.BooleanOr; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumOr; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicOr; - case BinaryOperatorKind.UserDefined: - if ((operatorKind & BinaryOperatorKind.Logical) != 0) - { - return BinaryOperationKind.OperatorMethodConditionalOr; - } + internal partial class BoundHoistedFieldAccess + { + protected override OperationKind ExpressionKind => OperationKind.None; - return BinaryOperationKind.OperatorMethodOr; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case BinaryOperatorKind.Xor: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerExclusiveOr; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedExclusiveOr; - case BinaryOperatorKind.Bool: - return BinaryOperationKind.BooleanExclusiveOr; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumExclusiveOr; - case BinaryOperatorKind.Dynamic: - return BinaryOperationKind.DynamicExclusiveOr; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodExclusiveOr; - } + internal partial class BoundInterpolatedString + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - case BinaryOperatorKind.LessThan: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerLessThan; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedLessThan; - case BinaryOperatorKind.Float: - case BinaryOperatorKind.Double: - return BinaryOperationKind.FloatingLessThan; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalLessThan; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerLessThan; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumLessThan; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodLessThan; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - break; + internal partial class BoundNoPiaObjectCreationExpression + { + protected override OperationKind ExpressionKind => OperationKind.None; - case BinaryOperatorKind.LessThanOrEqual: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerLessThanOrEqual; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedLessThanOrEqual; - case BinaryOperatorKind.Float: - case BinaryOperatorKind.Double: - return BinaryOperationKind.FloatingLessThanOrEqual; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalLessThanOrEqual; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerLessThanOrEqual; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumLessThanOrEqual; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodLessThanOrEqual; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case BinaryOperatorKind.Equal: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.IntegerEquals; - case BinaryOperatorKind.Float: - case BinaryOperatorKind.Double: - return BinaryOperationKind.FloatingEquals; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalEquals; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerEquals; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumEquals; - case BinaryOperatorKind.Bool: - return BinaryOperationKind.BooleanEquals; - case BinaryOperatorKind.String: - return BinaryOperationKind.StringEquals; - case BinaryOperatorKind.Object: - return BinaryOperationKind.ObjectEquals; - case BinaryOperatorKind.Delegate: - return BinaryOperationKind.DelegateEquals; - case BinaryOperatorKind.NullableNull: - return BinaryOperationKind.NullableEquals; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodEquals; - } + internal partial class BoundObjectInitializerExpression + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - case BinaryOperatorKind.NotEqual: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.IntegerNotEquals; - case BinaryOperatorKind.Float: - case BinaryOperatorKind.Double: - return BinaryOperationKind.FloatingNotEquals; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalNotEquals; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerNotEquals; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumNotEquals; - case BinaryOperatorKind.Bool: - return BinaryOperationKind.BooleanNotEquals; - case BinaryOperatorKind.String: - return BinaryOperationKind.StringNotEquals; - case BinaryOperatorKind.Object: - return BinaryOperationKind.ObjectNotEquals; - case BinaryOperatorKind.Delegate: - return BinaryOperationKind.DelegateNotEquals; - case BinaryOperatorKind.NullableNull: - return BinaryOperationKind.NullableNotEquals; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodNotEquals; - } + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - break; + internal partial class BoundStringInsert + { + protected override OperationKind ExpressionKind => OperationKind.None; - case BinaryOperatorKind.GreaterThanOrEqual: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerGreaterThanOrEqual; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedGreaterThanOrEqual; - case BinaryOperatorKind.Float: - case BinaryOperatorKind.Double: - return BinaryOperationKind.FloatingGreaterThanOrEqual; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalGreaterThanOrEqual; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerGreaterThanOrEqual; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumGreaterThanOrEqual; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodGreaterThanOrEqual; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - break; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); + } + } - case BinaryOperatorKind.GreaterThan: - switch (operatorKind & BinaryOperatorKind.TypeMask) - { - case BinaryOperatorKind.Int: - case BinaryOperatorKind.Long: - return BinaryOperationKind.IntegerGreaterThan; - case BinaryOperatorKind.UInt: - case BinaryOperatorKind.ULong: - return BinaryOperationKind.UnsignedGreaterThan; - case BinaryOperatorKind.Float: - case BinaryOperatorKind.Double: - return BinaryOperationKind.FloatingGreaterThan; - case BinaryOperatorKind.Decimal: - return BinaryOperationKind.DecimalGreaterThan; - case BinaryOperatorKind.Pointer: - return BinaryOperationKind.PointerGreaterThan; - case BinaryOperatorKind.Enum: - return BinaryOperationKind.EnumGreaterThan; - case BinaryOperatorKind.UserDefined: - return BinaryOperationKind.OperatorMethodGreaterThan; - } + internal partial class BoundDynamicObjectInitializerMember + { + protected override OperationKind ExpressionKind => OperationKind.None; - break; - } + public override void Accept(OperationVisitor visitor) + { + visitor.VisitNoneOperation(this); + } - return BinaryOperationKind.Invalid; + public override TResult Accept(OperationVisitor visitor, TArgument argument) + { + return visitor.VisitNoneOperation(this, argument); } } @@ -3012,4 +3013,5 @@ public override void Accept(OperationVisitor visitor) // TODO: implement IOperation for pattern-matching constructs (https://github.com/dotnet/roslyn/issues/8699) protected override OperationKind ExpressionKind => OperationKind.None; } +#endif } diff --git a/src/Compilers/CSharp/Portable/BoundTree/Statement.cs b/src/Compilers/CSharp/Portable/BoundTree/Statement.cs index 617873d5885..b6766636ffe 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Statement.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Statement.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#if false using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Semantics; using System.Collections.Immutable; @@ -262,8 +263,8 @@ public override void Accept(OperationVisitor visitor) internal partial class BoundForEachStatement : IForEachLoopStatement { - ILocalSymbol IForEachLoopStatement.IterationVariable => this.IterationVariables.Length == 1? - this.IterationVariables.FirstOrDefault(): + ILocalSymbol IForEachLoopStatement.IterationVariable => this.IterationVariables.Length == 1 ? + this.IterationVariables.FirstOrDefault() : null; IOperation IForEachLoopStatement.Collection => this.Expression; @@ -612,7 +613,7 @@ ImmutableArray IVariableDeclarationStatement.Variables get { return (ImmutableArray)s_variablesMappings.GetValue(this, - declaration => ImmutableArray.Create(new VariableDeclaration(declaration.LocalSymbol, declaration.InitializerOpt, declaration.Syntax))); + declaration => ImmutableArray.Create(OperationFactory.CreateVariableDeclaration(declaration.LocalSymbol, declaration.InitializerOpt, declaration.Syntax))); } } @@ -641,7 +642,7 @@ ImmutableArray IVariableDeclarationStatement.Variables return (ImmutableArray)s_variablesMappings.GetValue(this, multipleDeclarations => multipleDeclarations.LocalDeclarations.SelectAsArray(declaration => - (IVariableDeclaration)new VariableDeclaration(declaration.LocalSymbol, declaration.InitializerOpt, declaration.Syntax))); + (IVariableDeclaration)OperationFactory.CreateVariableDeclaration(declaration.LocalSymbol, declaration.InitializerOpt, declaration.Syntax))); } } @@ -837,3 +838,4 @@ public override void Accept(OperationVisitor visitor) } } } +#endif \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index e00dc3d234d..8d0c052e385 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -103,7 +103,7 @@ public override CSharpSemanticModel ParentModel internal override MemberSemanticModel GetMemberModel(SyntaxNode node) { // We do have to override this method, but should never call it because it might not do the right thing. - Debug.Assert(false); + Debug.Assert(false); return IsInTree(node) ? this : null; } @@ -591,7 +591,7 @@ private LocalFunctionSymbol GetDeclaredLocalFunction(LocalFunctionStatementSynta private static LocalFunctionSymbol GetDeclaredLocalFunction(Binder enclosingBinder, SyntaxToken declaredIdentifier) { - for (var binder = enclosingBinder ; binder != null; binder = binder.Next) + for (var binder = enclosingBinder; binder != null; binder = binder.Next) { foreach (var localFunction in binder.LocalFunctions) { @@ -929,7 +929,7 @@ public override ISymbol GetDeclaredSymbol(ArgumentSyntax declaratorSyntax, Cance { var elements = tupleLiteralType.TupleElements; - if(!elements.IsDefault) + if (!elements.IsDefault) { var idx = tupleLiteral.Arguments.IndexOf(declaratorSyntax); return elements[idx]; @@ -978,7 +978,7 @@ internal override IOperation GetOperationWorker(CSharpSyntaxNode node, GetOperat break; } - return result as IOperation; + return CSharpOperationFactory.Create(result); } internal override SymbolInfo GetSymbolInfoWorker(CSharpSyntaxNode node, SymbolInfoOptions options, CancellationToken cancellationToken = default(CancellationToken)) @@ -1520,7 +1520,7 @@ private static Binder GetQueryEnclosingBinder(int position, CSharpSyntaxNode sta } while (node != null); -done: + done: return GetEnclosingBinderInternalWithinRoot(AdjustStartingNodeAccordingToNewRoot(startingNode, queryClause.Syntax), position, queryClause.Binder, queryClause.Syntax); } @@ -1805,7 +1805,7 @@ protected CSharpSyntaxNode GetBindableParentNode(CSharpSyntaxNode node) { return null; } - + throw new ArgumentException($"The parent of {nameof(node)} must not be null unless this is a speculative semantic model.", nameof(node)); } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs index 1306f545dbe..7a693134184 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs @@ -56,18 +56,6 @@ public bool HasLocals } } - protected override OperationKind ExpressionKind => OperationKind.None; - - public override void Accept(OperationVisitor visitor) - { - throw ExceptionUtilities.Unreachable; - } - - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - throw ExceptionUtilities.Unreachable; - } - public ImmutableArray GetLocals() { return (_locals == null) ? ImmutableArray.Empty : _locals.ToImmutable(); @@ -772,8 +760,8 @@ public override BoundNode VisitCall(BoundCall node) private static RefKind ReceiverSpillRefKind(BoundExpression receiver) { - return LocalRewriter.WouldBeAssignableIfUsedAsMethodReceiver(receiver) ? - RefKind.Ref : + return LocalRewriter.WouldBeAssignableIfUsedAsMethodReceiver(receiver) ? + RefKind.Ref : RefKind.None; } diff --git a/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/PartiallyLoweredLocalFunctionReference.cs b/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/PartiallyLoweredLocalFunctionReference.cs index d7f39860d33..c79d1ca0f04 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/PartiallyLoweredLocalFunctionReference.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/PartiallyLoweredLocalFunctionReference.cs @@ -29,23 +29,5 @@ internal class PartiallyLoweredLocalFunctionReference : BoundExpression public override BoundNode Accept(BoundTreeVisitor visitor) => visitor.Visit(this); - - protected override OperationKind ExpressionKind - { - get - { - throw new InvalidOperationException(); - } - } - - public override void Accept(OperationVisitor visitor) - { - throw new InvalidOperationException(); - } - - public override TResult Accept(OperationVisitor visitor, TArgument argument) - { - throw new InvalidOperationException(); - } } } diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index bfcc5d7ef29..439fb39c698 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.CSharp; namespace Microsoft.CodeAnalysis.Semantics @@ -168,12 +169,12 @@ private static IPlaceholderExpression CreateBoundDeconstructValuePlaceholderOper private static IInvocationExpression CreateBoundCallOperation(BoundCall boundCall) { IMethodSymbol targetMethod = boundCall.Method; - Lazy instance = new Lazy(() => ((object)boundCall.Method == null || boundCall.Method.IsStatic) ? null : boundCall.ReceiverOpt); + Lazy instance = new Lazy(() => (IOperation)Create(((object)boundCall.Method == null || boundCall.Method.IsStatic) ? null : boundCall.ReceiverOpt)); bool isVirtual = (object)boundCall.Method != null && boundCall.ReceiverOpt != null && (boundCall.Method.IsVirtual || boundCall.Method.IsAbstract || boundCall.Method.IsOverride) && !boundCall.ReceiverOpt.SuppressVirtualCalls; - Lazy> argumentsInSourceOrder = new Lazy>(() => ((IInvocationExpression)boundCall).ArgumentsInSourceOrder /* MANUAL */); + Lazy> argumentsInSourceOrder = new Lazy>(() => GetArgumentsInSourceOrder(boundCall)); bool isInvalid = boundCall.HasErrors; SyntaxNode syntax = boundCall.Syntax; ITypeSymbol type = boundCall.Type; @@ -192,7 +193,7 @@ private static ILocalReferenceExpression CreateBoundLocalOperation(BoundLocal bo private static IFieldReferenceExpression CreateBoundFieldAccessOperation(BoundFieldAccess boundFieldAccess) { IFieldSymbol field = boundFieldAccess.FieldSymbol; - Lazy instance = new Lazy(() => boundFieldAccess.FieldSymbol.IsStatic ? null : boundFieldAccess.ReceiverOpt); + Lazy instance = new Lazy(() => (IOperation)Create(boundFieldAccess.FieldSymbol.IsStatic ? null : boundFieldAccess.ReceiverOpt)); ISymbol member = boundFieldAccess.FieldSymbol; bool isInvalid = boundFieldAccess.HasErrors; SyntaxNode syntax = boundFieldAccess.Syntax; @@ -203,7 +204,7 @@ private static IFieldReferenceExpression CreateBoundFieldAccessOperation(BoundFi private static IPropertyReferenceExpression CreateBoundPropertyAccessOperation(BoundPropertyAccess boundPropertyAccess) { IPropertySymbol property = boundPropertyAccess.PropertySymbol; - Lazy instance = new Lazy(() => boundPropertyAccess.PropertySymbol.IsStatic ? null : boundPropertyAccess.ReceiverOpt); + Lazy instance = new Lazy(() => (IOperation)Create(boundPropertyAccess.PropertySymbol.IsStatic ? null : boundPropertyAccess.ReceiverOpt)); ISymbol member = boundPropertyAccess.PropertySymbol; bool isInvalid = boundPropertyAccess.HasErrors; SyntaxNode syntax = boundPropertyAccess.Syntax; @@ -214,7 +215,7 @@ private static IPropertyReferenceExpression CreateBoundPropertyAccessOperation(B private static IIndexedPropertyReferenceExpression CreateBoundIndexerAccessOperation(BoundIndexerAccess boundIndexerAccess) { IPropertySymbol property = boundIndexerAccess.Indexer; - Lazy instance = new Lazy(() => boundIndexerAccess.Indexer.IsStatic ? null : boundIndexerAccess.ReceiverOpt); + Lazy instance = new Lazy(() => (IOperation)Create(boundIndexerAccess.Indexer.IsStatic ? null : boundIndexerAccess.ReceiverOpt)); ISymbol member = boundIndexerAccess.Indexer; bool isInvalid = boundIndexerAccess.HasErrors; SyntaxNode syntax = boundIndexerAccess.Syntax; @@ -225,7 +226,7 @@ private static IIndexedPropertyReferenceExpression CreateBoundIndexerAccessOpera private static IEventReferenceExpression CreateBoundEventAccessOperation(BoundEventAccess boundEventAccess) { IEventSymbol @event = boundEventAccess.EventSymbol; - Lazy instance = new Lazy(() => boundEventAccess.EventSymbol.IsStatic ? null : boundEventAccess.ReceiverOpt); + Lazy instance = new Lazy(() => (IOperation)Create(boundEventAccess.EventSymbol.IsStatic ? null : boundEventAccess.ReceiverOpt)); ISymbol member = boundEventAccess.EventSymbol; bool isInvalid = boundEventAccess.HasErrors; SyntaxNode syntax = boundEventAccess.Syntax; @@ -236,8 +237,8 @@ private static IEventReferenceExpression CreateBoundEventAccessOperation(BoundEv private static IEventAssignmentExpression CreateBoundEventAssignmentOperatorOperation(BoundEventAssignmentOperator boundEventAssignmentOperator) { IEventSymbol @event = boundEventAssignmentOperator.Event; - Lazy eventInstance = new Lazy(() => boundEventAssignmentOperator.Event.IsStatic ? null : boundEventAssignmentOperator.ReceiverOpt); - Lazy handlerValue = new Lazy(() => boundEventAssignmentOperator.Argument); + Lazy eventInstance = new Lazy(() => (IOperation)Create(boundEventAssignmentOperator.Event.IsStatic ? null : boundEventAssignmentOperator.ReceiverOpt)); + Lazy handlerValue = new Lazy(() => (IOperation)Create(boundEventAssignmentOperator.Argument)); bool adds = boundEventAssignmentOperator.IsAddition; bool isInvalid = boundEventAssignmentOperator.HasErrors; SyntaxNode syntax = boundEventAssignmentOperator.Syntax; @@ -251,7 +252,7 @@ private static IMethodBindingExpression CreateBoundDelegateCreationExpressionOpe bool isVirtual = (object)boundDelegateCreationExpression.MethodOpt != null && (boundDelegateCreationExpression.MethodOpt.IsVirtual || boundDelegateCreationExpression.MethodOpt.IsAbstract || boundDelegateCreationExpression.MethodOpt.IsOverride) && !boundDelegateCreationExpression.SuppressVirtualCalls; - Lazy instance = new Lazy(() => ((IMemberReferenceExpression)boundDelegateCreationExpression).Instance /* MANUAL */); + Lazy instance = new Lazy(() => GetDelegateCreationInstance(boundDelegateCreationExpression)); ISymbol member = boundDelegateCreationExpression.MethodOpt; bool isInvalid = boundDelegateCreationExpression.HasErrors; SyntaxNode syntax = boundDelegateCreationExpression.Argument.Syntax; @@ -280,7 +281,7 @@ private static ILiteralExpression CreateBoundLiteralOperation(BoundLiteral bound private static IObjectCreationExpression CreateBoundObjectCreationExpressionOperation(BoundObjectCreationExpression boundObjectCreationExpression) { IMethodSymbol constructor = boundObjectCreationExpression.Constructor; - Lazy> memberInitializers = new Lazy>(() => ((IObjectCreationExpression)boundObjectCreationExpression).MemberInitializers /* MANUAL */); + Lazy> memberInitializers = new Lazy>(() => GetObjectCreationMemberInitializers(boundObjectCreationExpression)); bool isInvalid = boundObjectCreationExpression.HasErrors; SyntaxNode syntax = boundObjectCreationExpression.Syntax; ITypeSymbol type = boundObjectCreationExpression.Type; @@ -298,7 +299,7 @@ private static IUnboundLambdaExpression CreateUnboundLambdaOperation(UnboundLamb private static ILambdaExpression CreateBoundLambdaOperation(BoundLambda boundLambda) { IMethodSymbol signature = boundLambda.Symbol; - Lazy body = new Lazy(() => boundLambda.Body); + Lazy body = new Lazy(() => (IBlockStatement)Create(boundLambda.Body)); bool isInvalid = boundLambda.HasErrors; SyntaxNode syntax = boundLambda.Syntax; ITypeSymbol type = boundLambda.Type; @@ -307,8 +308,8 @@ private static ILambdaExpression CreateBoundLambdaOperation(BoundLambda boundLam } private static IConversionExpression CreateBoundConversionOperation(BoundConversion boundConversion) { - Lazy operand = new Lazy(() => boundConversion.Operand); - ConversionKind conversionKind = ((IConversionExpression)boundConversion).ConversionKind /* MANUAL */; + Lazy operand = new Lazy(() => (IOperation)Create(boundConversion.Operand)); + ConversionKind conversionKind = GetConversionKind(boundConversion.ConversionKind); bool isExplicit = boundConversion.ExplicitCastInCode; bool usesOperatorMethod = boundConversion.ConversionKind == CSharp.ConversionKind.ExplicitUserDefined || boundConversion.ConversionKind == CSharp.ConversionKind.ImplicitUserDefined; IMethodSymbol operatorMethod = boundConversion.SymbolOpt; @@ -320,7 +321,7 @@ private static IConversionExpression CreateBoundConversionOperation(BoundConvers } private static IConversionExpression CreateBoundAsOperatorOperation(BoundAsOperator boundAsOperator) { - Lazy operand = new Lazy(() => boundAsOperator.Operand); + Lazy operand = new Lazy(() => (IOperation)Create(boundAsOperator.Operand)); ConversionKind conversionKind = Semantics.ConversionKind.TryCast; bool isExplicit = true; bool usesOperatorMethod = false; @@ -333,7 +334,7 @@ private static IConversionExpression CreateBoundAsOperatorOperation(BoundAsOpera } private static IIsTypeExpression CreateBoundIsOperatorOperation(BoundIsOperator boundIsOperator) { - Lazy operand = new Lazy(() => boundIsOperator.Operand); + Lazy operand = new Lazy(() => (IOperation)Create(boundIsOperator.Operand)); ITypeSymbol isType = boundIsOperator.TargetType.Type; bool isInvalid = boundIsOperator.HasErrors; SyntaxNode syntax = boundIsOperator.Syntax; @@ -361,9 +362,9 @@ private static ITypeOfExpression CreateBoundTypeOfOperatorOperation(BoundTypeOfO } private static IArrayCreationExpression CreateBoundArrayCreationOperation(BoundArrayCreation boundArrayCreation) { - ITypeSymbol elementType = ((IArrayCreationExpression)boundArrayCreation).ElementType /* MANUAL */; - Lazy> dimensionSizes = new Lazy>(() => boundArrayCreation.Bounds.As()); - Lazy initializer = new Lazy(() => boundArrayCreation.InitializerOpt); + ITypeSymbol elementType = GetArrayCreationElementType(boundArrayCreation); + Lazy> dimensionSizes = new Lazy>(() => boundArrayCreation.Bounds.SelectAsArray(n => (IOperation)Create(n))); + Lazy initializer = new Lazy(() => (IArrayInitializer)Create(boundArrayCreation.InitializerOpt)); bool isInvalid = boundArrayCreation.HasErrors; SyntaxNode syntax = boundArrayCreation.Syntax; ITypeSymbol type = boundArrayCreation.Type; @@ -372,7 +373,7 @@ private static IArrayCreationExpression CreateBoundArrayCreationOperation(BoundA } private static IArrayInitializer CreateBoundArrayInitializationOperation(BoundArrayInitialization boundArrayInitialization) { - Lazy> elementValues = new Lazy>(() => boundArrayInitialization.Initializers.As()); + Lazy> elementValues = new Lazy>(() => boundArrayInitialization.Initializers.SelectAsArray(n => (IOperation)Create(n))); bool isInvalid = boundArrayInitialization.HasErrors; SyntaxNode syntax = boundArrayInitialization.Syntax; ITypeSymbol type = boundArrayInitialization.Type; @@ -407,8 +408,8 @@ private static IInstanceReferenceExpression CreateBoundThisReferenceOperation(Bo } private static IAssignmentExpression CreateBoundAssignmentOperatorOperation(BoundAssignmentOperator boundAssignmentOperator) { - Lazy target = new Lazy(() => boundAssignmentOperator.Left); - Lazy value = new Lazy(() => boundAssignmentOperator.Right); + Lazy target = new Lazy(() => (IOperation)Create(boundAssignmentOperator.Left)); + Lazy value = new Lazy(() => (IOperation)Create(boundAssignmentOperator.Right)); bool isInvalid = boundAssignmentOperator.HasErrors; SyntaxNode syntax = boundAssignmentOperator.Syntax; ITypeSymbol type = boundAssignmentOperator.Type; @@ -418,8 +419,8 @@ private static IAssignmentExpression CreateBoundAssignmentOperatorOperation(Boun private static ICompoundAssignmentExpression CreateBoundCompoundAssignmentOperatorOperation(BoundCompoundAssignmentOperator boundCompoundAssignmentOperator) { BinaryOperationKind binaryOperationKind = CSharp.Expression.DeriveBinaryOperationKind(boundCompoundAssignmentOperator.Operator.Kind); - Lazy target = new Lazy(() => boundCompoundAssignmentOperator.Left); - Lazy value = new Lazy(() => boundCompoundAssignmentOperator.Right); + Lazy target = new Lazy(() => (IOperation)Create(boundCompoundAssignmentOperator.Left)); + Lazy value = new Lazy(() => (IOperation)Create(boundCompoundAssignmentOperator.Right)); bool usesOperatorMethod = (boundCompoundAssignmentOperator.Operator.Kind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined; IMethodSymbol operatorMethod = boundCompoundAssignmentOperator.Operator.Method; bool isInvalid = boundCompoundAssignmentOperator.HasErrors; @@ -432,7 +433,7 @@ private static IIncrementExpression CreateBoundIncrementOperatorOperation(BoundI { UnaryOperationKind incrementOperationKind = CSharp.Expression.DeriveUnaryOperationKind(boundIncrementOperator.OperatorKind); BinaryOperationKind binaryOperationKind = CSharp.Expression.DeriveBinaryOperationKind(incrementOperationKind); - Lazy target = new Lazy(() => boundIncrementOperator.Operand); + Lazy target = new Lazy(() => (IOperation)Create(boundIncrementOperator.Operand)); Lazy value = new Lazy(() => CreateIncrementOneLiteralExpression(boundIncrementOperator)); bool usesOperatorMethod = (boundIncrementOperator.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined; IMethodSymbol operatorMethod = boundIncrementOperator.MethodOpt; @@ -461,7 +462,7 @@ private static ITypeParameterObjectCreationExpression CreateBoundNewTOperation(B private static IUnaryOperatorExpression CreateBoundUnaryOperatorOperation(BoundUnaryOperator boundUnaryOperator) { UnaryOperationKind unaryOperationKind = CSharp.Expression.DeriveUnaryOperationKind(boundUnaryOperator.OperatorKind); - Lazy operand = new Lazy(() => boundUnaryOperator.Operand); + Lazy operand = new Lazy(() => (IOperation)Create(boundUnaryOperator.Operand)); bool usesOperatorMethod = (boundUnaryOperator.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined; IMethodSymbol operatorMethod = boundUnaryOperator.MethodOpt; bool isInvalid = boundUnaryOperator.HasErrors; @@ -473,8 +474,8 @@ private static IUnaryOperatorExpression CreateBoundUnaryOperatorOperation(BoundU private static IBinaryOperatorExpression CreateBoundBinaryOperatorOperation(BoundBinaryOperator boundBinaryOperator) { BinaryOperationKind binaryOperationKind = CSharp.Expression.DeriveBinaryOperationKind(boundBinaryOperator.OperatorKind); - Lazy leftOperand = new Lazy(() => boundBinaryOperator.Left); - Lazy rightOperand = new Lazy(() => boundBinaryOperator.Right); + Lazy leftOperand = new Lazy(() => (IOperation)Create(boundBinaryOperator.Left)); + Lazy rightOperand = new Lazy(() => (IOperation)Create(boundBinaryOperator.Right)); bool usesOperatorMethod = (boundBinaryOperator.OperatorKind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined; IMethodSymbol operatorMethod = boundBinaryOperator.MethodOpt; bool isInvalid = boundBinaryOperator.HasErrors; @@ -485,9 +486,9 @@ private static IBinaryOperatorExpression CreateBoundBinaryOperatorOperation(Boun } private static IConditionalChoiceExpression CreateBoundConditionalOperatorOperation(BoundConditionalOperator boundConditionalOperator) { - Lazy condition = new Lazy(() => boundConditionalOperator.Condition); - Lazy ifTrueValue = new Lazy(() => boundConditionalOperator.Consequence); - Lazy ifFalseValue = new Lazy(() => boundConditionalOperator.Alternative); + Lazy condition = new Lazy(() => (IOperation)Create(boundConditionalOperator.Condition)); + Lazy ifTrueValue = new Lazy(() => (IOperation)Create(boundConditionalOperator.Consequence)); + Lazy ifFalseValue = new Lazy(() => (IOperation)Create(boundConditionalOperator.Alternative)); bool isInvalid = boundConditionalOperator.HasErrors; SyntaxNode syntax = boundConditionalOperator.Syntax; ITypeSymbol type = boundConditionalOperator.Type; @@ -496,8 +497,8 @@ private static IConditionalChoiceExpression CreateBoundConditionalOperatorOperat } private static INullCoalescingExpression CreateBoundNullCoalescingOperatorOperation(BoundNullCoalescingOperator boundNullCoalescingOperator) { - Lazy primaryOperand = new Lazy(() => boundNullCoalescingOperator.LeftOperand); - Lazy secondaryOperand = new Lazy(() => boundNullCoalescingOperator.RightOperand); + Lazy primaryOperand = new Lazy(() => (IOperation)Create(boundNullCoalescingOperator.LeftOperand)); + Lazy secondaryOperand = new Lazy(() => (IOperation)Create(boundNullCoalescingOperator.RightOperand)); bool isInvalid = boundNullCoalescingOperator.HasErrors; SyntaxNode syntax = boundNullCoalescingOperator.Syntax; ITypeSymbol type = boundNullCoalescingOperator.Type; @@ -506,7 +507,7 @@ private static INullCoalescingExpression CreateBoundNullCoalescingOperatorOperat } private static IAwaitExpression CreateBoundAwaitExpressionOperation(BoundAwaitExpression boundAwaitExpression) { - Lazy awaitedValue = new Lazy(() => boundAwaitExpression.Expression); + Lazy awaitedValue = new Lazy(() => (IOperation)Create(boundAwaitExpression.Expression)); bool isInvalid = boundAwaitExpression.HasErrors; SyntaxNode syntax = boundAwaitExpression.Syntax; ITypeSymbol type = boundAwaitExpression.Type; @@ -515,8 +516,8 @@ private static IAwaitExpression CreateBoundAwaitExpressionOperation(BoundAwaitEx } private static IArrayElementReferenceExpression CreateBoundArrayAccessOperation(BoundArrayAccess boundArrayAccess) { - Lazy arrayReference = new Lazy(() => boundArrayAccess.Expression); - Lazy> indices = new Lazy>(() => boundArrayAccess.Indices.As()); + Lazy arrayReference = new Lazy(() => (IOperation)Create(boundArrayAccess.Expression)); + Lazy> indices = new Lazy>(() => boundArrayAccess.Indices.SelectAsArray(n => (IOperation)Create(n))); bool isInvalid = boundArrayAccess.HasErrors; SyntaxNode syntax = boundArrayAccess.Syntax; ITypeSymbol type = boundArrayAccess.Type; @@ -525,7 +526,7 @@ private static IArrayElementReferenceExpression CreateBoundArrayAccessOperation( } private static IPointerIndirectionReferenceExpression CreateBoundPointerIndirectionOperatorOperation(BoundPointerIndirectionOperator boundPointerIndirectionOperator) { - Lazy pointer = new Lazy(() => boundPointerIndirectionOperator.Operand); + Lazy pointer = new Lazy(() => (IOperation)Create(boundPointerIndirectionOperator.Operand)); bool isInvalid = boundPointerIndirectionOperator.HasErrors; SyntaxNode syntax = boundPointerIndirectionOperator.Syntax; ITypeSymbol type = boundPointerIndirectionOperator.Type; @@ -534,7 +535,7 @@ private static IPointerIndirectionReferenceExpression CreateBoundPointerIndirect } private static IAddressOfExpression CreateBoundAddressOfOperatorOperation(BoundAddressOfOperator boundAddressOfOperator) { - Lazy reference = new Lazy(() => boundAddressOfOperator.Operand); + Lazy reference = new Lazy(() => (IOperation)Create(boundAddressOfOperator.Operand)); bool isInvalid = boundAddressOfOperator.HasErrors; SyntaxNode syntax = boundAddressOfOperator.Syntax; ITypeSymbol type = boundAddressOfOperator.Type; @@ -552,8 +553,8 @@ private static IInstanceReferenceExpression CreateBoundImplicitReceiverOperation } private static IConditionalAccessExpression CreateBoundConditionalAccessOperation(BoundConditionalAccess boundConditionalAccess) { - Lazy conditionalValue = new Lazy(() => boundConditionalAccess.AccessExpression); - Lazy conditionalInstance = new Lazy(() => boundConditionalAccess.Receiver); + Lazy conditionalValue = new Lazy(() => (IOperation)Create(boundConditionalAccess.AccessExpression)); + Lazy conditionalInstance = new Lazy(() => (IOperation)Create(boundConditionalAccess.Receiver)); bool isInvalid = boundConditionalAccess.HasErrors; SyntaxNode syntax = boundConditionalAccess.Syntax; ITypeSymbol type = boundConditionalAccess.Type; @@ -571,7 +572,7 @@ private static IConditionalAccessInstanceExpression CreateBoundConditionalReceiv private static IFieldInitializer CreateBoundFieldEqualsValueOperation(BoundFieldEqualsValue boundFieldEqualsValue) { ImmutableArray initializedFields = ImmutableArray.Create(boundFieldEqualsValue.Field); - Lazy value = new Lazy(() => boundFieldEqualsValue.Value); + Lazy value = new Lazy(() => (IOperation)Create(boundFieldEqualsValue.Value)); OperationKind kind = OperationKind.FieldInitializerAtDeclaration; bool isInvalid = ((IOperation)boundFieldEqualsValue.Value).IsInvalid; SyntaxNode syntax = boundFieldEqualsValue.Syntax; @@ -582,7 +583,7 @@ private static IFieldInitializer CreateBoundFieldEqualsValueOperation(BoundField private static IPropertyInitializer CreateBoundPropertyEqualsValueOperation(BoundPropertyEqualsValue boundPropertyEqualsValue) { IPropertySymbol initializedProperty = boundPropertyEqualsValue.Property; - Lazy value = new Lazy(() => boundPropertyEqualsValue.Value); + Lazy value = new Lazy(() => (IOperation)Create(boundPropertyEqualsValue.Value)); OperationKind kind = OperationKind.PropertyInitializerAtDeclaration; bool isInvalid = ((IOperation)boundPropertyEqualsValue.Value).IsInvalid; SyntaxNode syntax = boundPropertyEqualsValue.Syntax; @@ -593,7 +594,7 @@ private static IPropertyInitializer CreateBoundPropertyEqualsValueOperation(Boun private static IParameterInitializer CreateBoundParameterEqualsValueOperation(BoundParameterEqualsValue boundParameterEqualsValue) { IParameterSymbol parameter = boundParameterEqualsValue.Parameter; - Lazy value = new Lazy(() => boundParameterEqualsValue.Value); + Lazy value = new Lazy(() => (IOperation)Create(boundParameterEqualsValue.Value)); OperationKind kind = OperationKind.ParameterInitializerAtDeclaration; bool isInvalid = ((IOperation)boundParameterEqualsValue.Value).IsInvalid; SyntaxNode syntax = boundParameterEqualsValue.Syntax; @@ -603,7 +604,7 @@ private static IParameterInitializer CreateBoundParameterEqualsValueOperation(Bo } private static IBlockStatement CreateBoundBlockOperation(BoundBlock boundBlock) { - Lazy> statements = new Lazy>(() => ((IBlockStatement)boundBlock).Statements /* MANUAL */); + Lazy> statements = new Lazy>(() => GetBlockStatement(boundBlock)); ImmutableArray locals = boundBlock.Locals.As(); bool isInvalid = boundBlock.HasErrors; SyntaxNode syntax = boundBlock.Syntax; @@ -633,7 +634,7 @@ private static IBranchStatement CreateBoundBreakStatementOperation(BoundBreakSta } private static IReturnStatement CreateBoundYieldBreakStatementOperation(BoundYieldBreakStatement boundYieldBreakStatement) { - Lazy returnedValue = new Lazy(() => null); + Lazy returnedValue = new Lazy(() => (IOperation)Create(null)); bool isInvalid = boundYieldBreakStatement.HasErrors; SyntaxNode syntax = boundYieldBreakStatement.Syntax; ITypeSymbol type = null; @@ -660,9 +661,9 @@ private static IEmptyStatement CreateBoundNoOpStatementOperation(BoundNoOpStatem } private static IIfStatement CreateBoundIfStatementOperation(BoundIfStatement boundIfStatement) { - Lazy condition = new Lazy(() => boundIfStatement.Condition); - Lazy ifTrueStatement = new Lazy(() => boundIfStatement.Consequence); - Lazy ifFalseStatement = new Lazy(() => boundIfStatement.AlternativeOpt); + Lazy condition = new Lazy(() => (IOperation)Create(boundIfStatement.Condition)); + Lazy ifTrueStatement = new Lazy(() => (IOperation)Create(boundIfStatement.Consequence)); + Lazy ifFalseStatement = new Lazy(() => (IOperation)Create(boundIfStatement.AlternativeOpt)); bool isInvalid = boundIfStatement.HasErrors; SyntaxNode syntax = boundIfStatement.Syntax; ITypeSymbol type = null; @@ -673,9 +674,9 @@ private static IWhileUntilLoopStatement CreateBoundWhileStatementOperation(Bound { bool isTopTest = true; bool isWhile = true; - Lazy condition = new Lazy(() => boundWhileStatement.Condition); + Lazy condition = new Lazy(() => (IOperation)Create(boundWhileStatement.Condition)); LoopKind loopKind = LoopKind.WhileUntil; - Lazy body = new Lazy(() => boundWhileStatement.Body); + Lazy body = new Lazy(() => (IOperation)Create(boundWhileStatement.Body)); bool isInvalid = boundWhileStatement.HasErrors; SyntaxNode syntax = boundWhileStatement.Syntax; ITypeSymbol type = null; @@ -686,9 +687,9 @@ private static IWhileUntilLoopStatement CreateBoundDoStatementOperation(BoundDoS { bool isTopTest = false; bool isWhile = true; - Lazy condition = new Lazy(() => boundDoStatement.Condition); + Lazy condition = new Lazy(() => (IOperation)Create(boundDoStatement.Condition)); LoopKind loopKind = LoopKind.WhileUntil; - Lazy body = new Lazy(() => boundDoStatement.Body); + Lazy body = new Lazy(() => (IOperation)Create(boundDoStatement.Body)); bool isInvalid = boundDoStatement.HasErrors; SyntaxNode syntax = boundDoStatement.Syntax; ITypeSymbol type = null; @@ -700,9 +701,9 @@ private static IForLoopStatement CreateBoundForStatementOperation(BoundForStatem Lazy> before = new Lazy>(() => ToStatements(boundForStatement.Initializer)); Lazy> atLoopBottom = new Lazy>(() => ToStatements(boundForStatement.Increment)); ImmutableArray locals = boundForStatement.OuterLocals.As(); - Lazy condition = new Lazy(() => boundForStatement.Condition); + Lazy condition = new Lazy(() => (IOperation)Create(boundForStatement.Condition)); LoopKind loopKind = LoopKind.For; - Lazy body = new Lazy(() => boundForStatement.Body); + Lazy body = new Lazy(() => (IOperation)Create(boundForStatement.Body)); bool isInvalid = boundForStatement.HasErrors; SyntaxNode syntax = boundForStatement.Syntax; ITypeSymbol type = null; @@ -714,9 +715,9 @@ private static IForEachLoopStatement CreateBoundForEachStatementOperation(BoundF ILocalSymbol iterationVariable = boundForEachStatement.IterationVariables.Length == 1 ? boundForEachStatement.IterationVariables.FirstOrDefault() : null; - Lazy collection = new Lazy(() => boundForEachStatement.Expression); + Lazy collection = new Lazy(() => (IOperation)Create(boundForEachStatement.Expression)); LoopKind loopKind = LoopKind.ForEach; - Lazy body = new Lazy(() => boundForEachStatement.Body); + Lazy body = new Lazy(() => (IOperation)Create(boundForEachStatement.Body)); bool isInvalid = boundForEachStatement.HasErrors; SyntaxNode syntax = boundForEachStatement.Syntax; ITypeSymbol type = null; @@ -725,8 +726,8 @@ private static IForEachLoopStatement CreateBoundForEachStatementOperation(BoundF } private static ISwitchStatement CreateBoundSwitchStatementOperation(BoundSwitchStatement boundSwitchStatement) { - Lazy value = new Lazy(() => boundSwitchStatement.Expression); - Lazy> cases = new Lazy>(() => ((ISwitchStatement)boundSwitchStatement).Cases /* MANUAL */); + Lazy value = new Lazy(() => (IOperation)Create(boundSwitchStatement.Expression)); + Lazy> cases = new Lazy>(() => GetSwitchStatementCases(boundSwitchStatement)); bool isInvalid = boundSwitchStatement.HasErrors; SyntaxNode syntax = boundSwitchStatement.Syntax; ITypeSymbol type = null; @@ -735,8 +736,8 @@ private static ISwitchStatement CreateBoundSwitchStatementOperation(BoundSwitchS } private static ISingleValueCaseClause CreateBoundSwitchLabelOperation(BoundSwitchLabel boundSwitchLabel) { - Lazy value = new Lazy(() => boundSwitchLabel.ExpressionOpt); - BinaryOperationKind equality = ((ISingleValueCaseClause)boundSwitchLabel).Equality /* MANUAL */; + Lazy value = new Lazy(() => (IOperation)Create(boundSwitchLabel.ExpressionOpt)); + BinaryOperationKind equality = GetLabelEqualityKind(boundSwitchLabel); CaseKind caseKind = boundSwitchLabel.ExpressionOpt != null ? CaseKind.SingleValue : CaseKind.Default; bool isInvalid = boundSwitchLabel.HasErrors; SyntaxNode syntax = boundSwitchLabel.Syntax; @@ -746,9 +747,9 @@ private static ISingleValueCaseClause CreateBoundSwitchLabelOperation(BoundSwitc } private static ITryStatement CreateBoundTryStatementOperation(BoundTryStatement boundTryStatement) { - Lazy body = new Lazy(() => boundTryStatement.TryBlock); - Lazy> catches = new Lazy>(() => boundTryStatement.CatchBlocks.As()); - Lazy finallyHandler = new Lazy(() => boundTryStatement.FinallyBlockOpt); + Lazy body = new Lazy(() => (IBlockStatement)Create(boundTryStatement.TryBlock)); + Lazy> catches = new Lazy>(() => boundTryStatement.CatchBlocks.SelectAsArray(n => (ICatchClause)Create(n))); + Lazy finallyHandler = new Lazy(() => (IBlockStatement)Create(boundTryStatement.FinallyBlockOpt)); bool isInvalid = boundTryStatement.HasErrors; SyntaxNode syntax = boundTryStatement.Syntax; ITypeSymbol type = null; @@ -757,10 +758,10 @@ private static ITryStatement CreateBoundTryStatementOperation(BoundTryStatement } private static ICatchClause CreateBoundCatchBlockOperation(BoundCatchBlock boundCatchBlock) { - Lazy handler = new Lazy(() => boundCatchBlock.Body); + Lazy handler = new Lazy(() => (IBlockStatement)Create(boundCatchBlock.Body)); ITypeSymbol caughtType = boundCatchBlock.ExceptionTypeOpt; - Lazy filter = new Lazy(() => boundCatchBlock.ExceptionFilterOpt); - ILocalSymbol exceptionLocal = ((ICatchClause)boundCatchBlock).ExceptionLocal /* MANUAL */; + Lazy filter = new Lazy(() => (IOperation)Create(boundCatchBlock.ExceptionFilterOpt)); + ILocalSymbol exceptionLocal = (boundCatchBlock.Locals.FirstOrDefault()?.DeclarationKind == CSharp.Symbols.LocalDeclarationKind.CatchVariable) ? boundCatchBlock.Locals.FirstOrDefault() : null; bool isInvalid = boundCatchBlock.Body.HasErrors || (boundCatchBlock.ExceptionFilterOpt != null && boundCatchBlock.ExceptionFilterOpt.HasErrors); SyntaxNode syntax = boundCatchBlock.Syntax; ITypeSymbol type = null; @@ -769,8 +770,8 @@ private static ICatchClause CreateBoundCatchBlockOperation(BoundCatchBlock bound } private static IFixedStatement CreateBoundFixedStatementOperation(BoundFixedStatement boundFixedStatement) { - Lazy variables = new Lazy(() => boundFixedStatement.Declarations); - Lazy body = new Lazy(() => boundFixedStatement.Body); + Lazy variables = new Lazy(() => (IVariableDeclarationStatement)Create(boundFixedStatement.Declarations)); + Lazy body = new Lazy(() => (IOperation)Create(boundFixedStatement.Body)); bool isInvalid = boundFixedStatement.HasErrors; SyntaxNode syntax = boundFixedStatement.Syntax; ITypeSymbol type = null; @@ -779,9 +780,9 @@ private static IFixedStatement CreateBoundFixedStatementOperation(BoundFixedStat } private static IUsingStatement CreateBoundUsingStatementOperation(BoundUsingStatement boundUsingStatement) { - Lazy body = new Lazy(() => boundUsingStatement.Body); - Lazy declaration = new Lazy(() => boundUsingStatement.DeclarationsOpt); - Lazy value = new Lazy(() => boundUsingStatement.ExpressionOpt); + Lazy body = new Lazy(() => (IOperation)Create(boundUsingStatement.Body)); + Lazy declaration = new Lazy(() => (IVariableDeclarationStatement)Create(boundUsingStatement.DeclarationsOpt)); + Lazy value = new Lazy(() => (IOperation)Create(boundUsingStatement.ExpressionOpt)); bool isInvalid = boundUsingStatement.HasErrors; SyntaxNode syntax = boundUsingStatement.Syntax; ITypeSymbol type = null; @@ -790,7 +791,7 @@ private static IUsingStatement CreateBoundUsingStatementOperation(BoundUsingStat } private static IThrowStatement CreateBoundThrowStatementOperation(BoundThrowStatement boundThrowStatement) { - Lazy thrownObject = new Lazy(() => boundThrowStatement.ExpressionOpt); + Lazy thrownObject = new Lazy(() => (IOperation)Create(boundThrowStatement.ExpressionOpt)); bool isInvalid = boundThrowStatement.HasErrors; SyntaxNode syntax = boundThrowStatement.Syntax; ITypeSymbol type = null; @@ -799,7 +800,7 @@ private static IThrowStatement CreateBoundThrowStatementOperation(BoundThrowStat } private static IReturnStatement CreateBoundReturnStatementOperation(BoundReturnStatement boundReturnStatement) { - Lazy returnedValue = new Lazy(() => boundReturnStatement.ExpressionOpt); + Lazy returnedValue = new Lazy(() => (IOperation)Create(boundReturnStatement.ExpressionOpt)); bool isInvalid = boundReturnStatement.HasErrors; SyntaxNode syntax = boundReturnStatement.Syntax; ITypeSymbol type = null; @@ -808,7 +809,7 @@ private static IReturnStatement CreateBoundReturnStatementOperation(BoundReturnS } private static IReturnStatement CreateBoundYieldReturnStatementOperation(BoundYieldReturnStatement boundYieldReturnStatement) { - Lazy returnedValue = new Lazy(() => boundYieldReturnStatement.Expression); + Lazy returnedValue = new Lazy(() => (IOperation)Create(boundYieldReturnStatement.Expression)); bool isInvalid = boundYieldReturnStatement.HasErrors; SyntaxNode syntax = boundYieldReturnStatement.Syntax; ITypeSymbol type = null; @@ -817,8 +818,8 @@ private static IReturnStatement CreateBoundYieldReturnStatementOperation(BoundYi } private static ILockStatement CreateBoundLockStatementOperation(BoundLockStatement boundLockStatement) { - Lazy lockedObject = new Lazy(() => boundLockStatement.Argument); - Lazy body = new Lazy(() => boundLockStatement.Body); + Lazy lockedObject = new Lazy(() => (IOperation)Create(boundLockStatement.Argument)); + Lazy body = new Lazy(() => (IOperation)Create(boundLockStatement.Body)); bool isInvalid = boundLockStatement.HasErrors; SyntaxNode syntax = boundLockStatement.Syntax; ITypeSymbol type = null; @@ -835,7 +836,7 @@ private static IInvalidStatement CreateBoundBadStatementOperation(BoundBadStatem } private static IVariableDeclarationStatement CreateBoundLocalDeclarationOperation(BoundLocalDeclaration boundLocalDeclaration) { - Lazy> variables = new Lazy>(() => ((IVariableDeclarationStatement)boundLocalDeclaration).Variables /* MANUAL */); + Lazy> variables = new Lazy>(() => GetVariableDeclarationStatementVariables(boundLocalDeclaration)); bool isInvalid = boundLocalDeclaration.HasErrors; SyntaxNode syntax = boundLocalDeclaration.Syntax; ITypeSymbol type = null; @@ -844,7 +845,7 @@ private static IVariableDeclarationStatement CreateBoundLocalDeclarationOperatio } private static IVariableDeclarationStatement CreateBoundMultipleLocalDeclarationsOperation(BoundMultipleLocalDeclarations boundMultipleLocalDeclarations) { - Lazy> variables = new Lazy>(() => ((IVariableDeclarationStatement)boundMultipleLocalDeclarations).Variables /* MANUAL */); + Lazy> variables = new Lazy>(() => GetVariableDeclarationStatementVariables(boundMultipleLocalDeclarations)); bool isInvalid = boundMultipleLocalDeclarations.HasErrors; SyntaxNode syntax = boundMultipleLocalDeclarations.Syntax; ITypeSymbol type = null; @@ -854,7 +855,7 @@ private static IVariableDeclarationStatement CreateBoundMultipleLocalDeclaration private static ILabelStatement CreateBoundLabelStatementOperation(BoundLabelStatement boundLabelStatement) { ILabelSymbol label = boundLabelStatement.Label; - Lazy labeledStatement = new Lazy(() => null); + Lazy labeledStatement = new Lazy(() => (IOperation)Create(null)); bool isInvalid = boundLabelStatement.HasErrors; SyntaxNode syntax = boundLabelStatement.Syntax; ITypeSymbol type = null; @@ -864,7 +865,7 @@ private static ILabelStatement CreateBoundLabelStatementOperation(BoundLabelStat private static ILabelStatement CreateBoundLabeledStatementOperation(BoundLabeledStatement boundLabeledStatement) { ILabelSymbol label = boundLabeledStatement.Label; - Lazy labeledStatement = new Lazy(() => boundLabeledStatement.Body); + Lazy labeledStatement = new Lazy(() => (IOperation)Create(boundLabeledStatement.Body)); bool isInvalid = boundLabeledStatement.HasErrors; SyntaxNode syntax = boundLabeledStatement.Syntax; ITypeSymbol type = null; @@ -873,7 +874,7 @@ private static ILabelStatement CreateBoundLabeledStatementOperation(BoundLabeled } private static IExpressionStatement CreateBoundExpressionStatementOperation(BoundExpressionStatement boundExpressionStatement) { - Lazy expression = new Lazy(() => boundExpressionStatement.Expression); + Lazy expression = new Lazy(() => (IOperation)Create(boundExpressionStatement.Expression)); bool isInvalid = boundExpressionStatement.HasErrors; SyntaxNode syntax = boundExpressionStatement.Syntax; ITypeSymbol type = null; @@ -892,24 +893,415 @@ private static ImmutableArray ToStatements(BoundStatement statement) BoundStatementList statementList = statement as BoundStatementList; if (statementList != null) { - return statementList.Statements.As(); + return statementList.Statements.Select(n => Create(n)).ToImmutableArray(); } else if (statement == null) { return ImmutableArray.Empty; } - return ImmutableArray.Create(statement); + return ImmutableArray.Create(Create(statement)); } + private static readonly ConditionalWeakTable s_incrementValueMappings = new ConditionalWeakTable(); + private static ILiteralExpression CreateIncrementOneLiteralExpression(BoundIncrementOperator boundIncrementOperator) { - string text = boundIncrementOperator.Syntax.ToString(); - bool isInvalid = false; - SyntaxNode syntax = boundIncrementOperator.Syntax; - ITypeSymbol type = boundIncrementOperator.Type; - Optional constantValue = ConvertToOptional(Semantics.Expression.SynthesizeNumeric(boundIncrementOperator.Type, 1)); - return new LiteralExpression(text, isInvalid, syntax, type, constantValue); + return s_incrementValueMappings.GetValue(boundIncrementOperator, (increment) => + { + string text = increment.Syntax.ToString(); + bool isInvalid = false; + SyntaxNode syntax = increment.Syntax; + ITypeSymbol type = increment.Type; + Optional constantValue = ConvertToOptional(Semantics.Expression.SynthesizeNumeric(increment.Type, 1)); + return new LiteralExpression(text, isInvalid, syntax, type, constantValue); + }); + } + + private static ImmutableArray GetArgumentsInSourceOrder(BoundCall call) + { + ArrayBuilder sourceOrderArguments = ArrayBuilder.GetInstance(call.Arguments.Length); + for (int argumentIndex = 0; argumentIndex < call.Arguments.Length; argumentIndex++) + { + IArgument argument = DeriveArgument( + call.ArgsToParamsOpt.IsDefault ? argumentIndex : call.ArgsToParamsOpt[argumentIndex], + argumentIndex, + call.Arguments, + call.ArgumentNamesOpt, + call.ArgumentRefKindsOpt, + call.Method.Parameters.As(), + call.Syntax); + + sourceOrderArguments.Add(argument); + if (argument.ArgumentKind == ArgumentKind.ParamArray) + { + break; + } + } + + return sourceOrderArguments.ToImmutableAndFree(); + } + + private static readonly ConditionalWeakTable s_argumentMappings = new ConditionalWeakTable(); + + private static IArgument DeriveArgument( + int parameterIndex, + int argumentIndex, + ImmutableArray boundArguments, + ImmutableArray argumentNamesOpt, + ImmutableArray argumentRefKindsOpt, + ImmutableArray parameters, + SyntaxNode invocationSyntax) + { + if ((uint)argumentIndex >= (uint)boundArguments.Length) + { + // Check for an omitted argument that becomes an empty params array. + if (parameters.Length > 0) + { + IParameterSymbol lastParameter = parameters[parameters.Length - 1]; + if (lastParameter.IsParams) + { + var value = CreateParamArray(lastParameter, boundArguments, argumentIndex, invocationSyntax); + return new Argument( + argumentKind: ArgumentKind.ParamArray, + parameter: lastParameter, + value: value, + inConversion: null, + outConversion: null, + isInvalid: lastParameter == null || value.IsInvalid, + syntax: value.Syntax, + type: null, + constantValue: default(Optional)); + } + } + + // There is no supplied argument and there is no params parameter. Any action is suspect at this point. + var invalid = OperationFactory.CreateInvalidExpression(invocationSyntax); + return new Argument( + argumentKind: ArgumentKind.Positional, + parameter: null, + value: invalid, + inConversion: null, + outConversion: null, + isInvalid: true, + syntax: null, + type: null, + constantValue: default(Optional)); + } + + return s_argumentMappings.GetValue( + boundArguments[argumentIndex], + (argument) => + { + string nameOpt = !argumentNamesOpt.IsDefaultOrEmpty ? argumentNamesOpt[argumentIndex] : null; + IParameterSymbol parameterOpt = (uint)parameterIndex < (uint)parameters.Length ? parameters[parameterIndex] : null; + + if ((object)nameOpt == null) + { + RefKind refMode = argumentRefKindsOpt.IsDefaultOrEmpty ? RefKind.None : argumentRefKindsOpt[argumentIndex]; + + if (refMode != RefKind.None) + { + var value = Create(argument); + return new Argument( + argumentKind: ArgumentKind.Positional, + parameter: parameterOpt, + value: value, + inConversion: null, + outConversion: null, + isInvalid: parameterOpt == null || value.IsInvalid, + syntax: argument.Syntax, + type: null, + constantValue: default(Optional)); + } + + if (argumentIndex >= parameters.Length - 1 && + parameters.Length > 0 && + parameters[parameters.Length - 1].IsParams && + // An argument that is an array of the appropriate type is not a params argument. + (boundArguments.Length > argumentIndex + 1 || + ((object)argument.Type != null && // If argument type is null, we are in an error scenario and cannot tell if it is a param array, or not. + (argument.Type.TypeKind != TypeKind.Array || + !argument.Type.Equals((CSharp.Symbols.TypeSymbol)parameters[parameters.Length - 1].Type, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds))))) + { + var parameter = parameters[parameters.Length - 1]; + var value = CreateParamArray(parameter, boundArguments, argumentIndex, invocationSyntax); + + return new Argument( + argumentKind: ArgumentKind.ParamArray, + parameter: parameter, + value: value, + inConversion: null, + outConversion: null, + isInvalid: parameter == null || value.IsInvalid, + syntax: value.Syntax, + type: null, + constantValue: default(Optional)); + } + else + { + var value = Create(argument); + return new Argument( + argumentKind: ArgumentKind.Positional, + parameter: parameterOpt, + value: value, + inConversion: null, + outConversion: null, + isInvalid: parameterOpt == null || value.IsInvalid, + syntax: value.Syntax, + type: null, + constantValue: default(Optional)); + } + } + + var operation = Create(argument); + return new Argument( + argumentKind: ArgumentKind.Named, + parameter: parameterOpt, + value: operation, + inConversion: null, + outConversion: null, + isInvalid: parameterOpt == null || operation.IsInvalid, + syntax: operation.Syntax, + type: null, + constantValue: default(Optional)); + }); + } + + private static IOperation CreateParamArray(IParameterSymbol parameter, ImmutableArray boundArguments, int firstArgumentElementIndex, SyntaxNode invocationSyntax) + { + if (parameter.Type.TypeKind == TypeKind.Array) + { + IArrayTypeSymbol arrayType = (IArrayTypeSymbol)parameter.Type; + ArrayBuilder builder = ArrayBuilder.GetInstance(boundArguments.Length - firstArgumentElementIndex); + + for (int index = firstArgumentElementIndex; index < boundArguments.Length; index++) + { + builder.Add(Create(boundArguments[index])); + } + + var paramArrayArguments = builder.ToImmutableAndFree(); + + // Use the invocation syntax node if there is no actual syntax available for the argument (because the paramarray is empty.) + return OperationFactory.CreateArrayCreationExpression(arrayType, paramArrayArguments, paramArrayArguments.Length > 0 ? paramArrayArguments[0].Syntax : invocationSyntax); + } + + return OperationFactory.CreateInvalidExpression(invocationSyntax); + } + + private static IOperation GetDelegateCreationInstance(BoundDelegateCreationExpression expression) + { + BoundMethodGroup methodGroup = expression.Argument as BoundMethodGroup; + if (methodGroup != null) + { + return Create(methodGroup.InstanceOpt); + } + + return null; + } + + private static readonly ConditionalWeakTable s_memberInitializersMappings = + new ConditionalWeakTable(); + + private static ImmutableArray GetObjectCreationMemberInitializers(BoundObjectCreationExpression expression) + { + return (ImmutableArray)s_memberInitializersMappings.GetValue(expression, + objectCreationExpression => + { + var objectInitializerExpression = expression.InitializerExpressionOpt as BoundObjectInitializerExpression; + if (objectInitializerExpression != null) + { + var builder = ArrayBuilder.GetInstance(objectInitializerExpression.Initializers.Length); + foreach (var memberAssignment in objectInitializerExpression.Initializers) + { + var assignment = memberAssignment as BoundAssignmentOperator; + var leftSymbol = (assignment?.Left as BoundObjectInitializerMember)?.MemberSymbol; + + if ((object)leftSymbol == null) + { + continue; + } + + switch (leftSymbol.Kind) + { + case SymbolKind.Field: + { + var value = Create(assignment.Right); + builder.Add(new FieldInitializer( + ImmutableArray.Create((IFieldSymbol)leftSymbol), + value, + OperationKind.FieldInitializerInCreation, + value.IsInvalid || leftSymbol == null, + assignment.Syntax, + type: null, + constantValue: default(Optional))); + break; + } + case SymbolKind.Property: + { + var value = Create(assignment.Right); + builder.Add(new PropertyInitializer( + (IPropertySymbol)leftSymbol, + value, + OperationKind.PropertyInitializerInCreation, + value.IsInvalid || leftSymbol == null, + assignment.Syntax, + type: null, + constantValue: default(Optional))); + break; + } + } + } + + return builder.ToImmutableAndFree(); + } + + return ImmutableArray.Empty; + }); + } + + private static ConversionKind GetConversionKind(CSharp.ConversionKind kind) + { + switch (kind) + { + case CSharp.ConversionKind.ExplicitUserDefined: + case CSharp.ConversionKind.ImplicitUserDefined: + return Semantics.ConversionKind.OperatorMethod; + + case CSharp.ConversionKind.ExplicitReference: + case CSharp.ConversionKind.ImplicitReference: + case CSharp.ConversionKind.Boxing: + case CSharp.ConversionKind.Unboxing: + case CSharp.ConversionKind.Identity: + return Semantics.ConversionKind.Cast; + + case CSharp.ConversionKind.AnonymousFunction: + case CSharp.ConversionKind.ExplicitDynamic: + case CSharp.ConversionKind.ImplicitDynamic: + case CSharp.ConversionKind.ExplicitEnumeration: + case CSharp.ConversionKind.ImplicitEnumeration: + case CSharp.ConversionKind.ImplicitThrow: + case CSharp.ConversionKind.ImplicitTupleLiteral: + case CSharp.ConversionKind.ImplicitTuple: + case CSharp.ConversionKind.ExplicitTupleLiteral: + case CSharp.ConversionKind.ExplicitTuple: + case CSharp.ConversionKind.ExplicitNullable: + case CSharp.ConversionKind.ImplicitNullable: + case CSharp.ConversionKind.ExplicitNumeric: + case CSharp.ConversionKind.ImplicitNumeric: + case CSharp.ConversionKind.ImplicitConstant: + case CSharp.ConversionKind.IntegerToPointer: + case CSharp.ConversionKind.IntPtr: + case CSharp.ConversionKind.NullLiteral: + case CSharp.ConversionKind.NullToPointer: + case CSharp.ConversionKind.PointerToInteger: + case CSharp.ConversionKind.PointerToPointer: + case CSharp.ConversionKind.PointerToVoid: + return Semantics.ConversionKind.CSharp; + + default: + return Semantics.ConversionKind.Invalid; + } + } + + private static ITypeSymbol GetArrayCreationElementType(BoundArrayCreation creation) + { + IArrayTypeSymbol arrayType = creation.Type as IArrayTypeSymbol; + if ((object)arrayType != null) + { + return arrayType.ElementType; + } + + return null; + } + + private static readonly ConditionalWeakTable s_blockStatementsMappings = + new ConditionalWeakTable(); + + private static ImmutableArray GetBlockStatement(BoundBlock block) + { + // This is to filter out operations of kind None. + return (ImmutableArray)s_blockStatementsMappings.GetValue(block, + blockStatement => + { + return blockStatement.Statements.Select(s => Create(s)).Where(s => s.Kind != OperationKind.None).ToImmutableArray(); + }); + } + + private static readonly ConditionalWeakTable s_switchSectionsMappings = + new ConditionalWeakTable(); + + private static ImmutableArray GetSwitchStatementCases(BoundSwitchStatement statement) + { + return (ImmutableArray)s_switchSectionsMappings.GetValue(statement, + switchStatement => + { + return switchStatement.SwitchSections.SelectAsArray(switchSection => + { + var clauses = switchSection.SwitchLabels.Select(s => (ICaseClause)Create(s)).ToImmutableArray(); + var body = switchSection.Statements.Select(s => Create(s)).ToImmutableArray(); + + return new SwitchCase(clauses, body, switchSection.HasErrors, switchSection.Syntax, type: null, constantValue: default(Optional)); + }); + }); + } + + private static BinaryOperationKind GetLabelEqualityKind(BoundSwitchLabel label) + { + BoundExpression caseValue = label.ExpressionOpt; + if (caseValue != null) + { + switch (caseValue.Type.SpecialType) + { + case SpecialType.System_Int32: + case SpecialType.System_Int64: + case SpecialType.System_UInt32: + case SpecialType.System_UInt64: + case SpecialType.System_UInt16: + case SpecialType.System_Int16: + case SpecialType.System_SByte: + case SpecialType.System_Byte: + case SpecialType.System_Char: + return BinaryOperationKind.IntegerEquals; + + case SpecialType.System_Boolean: + return BinaryOperationKind.BooleanEquals; + + case SpecialType.System_String: + return BinaryOperationKind.StringEquals; + } + + if (caseValue.Type.TypeKind == TypeKind.Enum) + { + return BinaryOperationKind.EnumEquals; + } + + return BinaryOperationKind.Invalid; + } + + // Return None for `default` case. + return BinaryOperationKind.None; + } + + private static readonly ConditionalWeakTable s_variablesMappings = + new ConditionalWeakTable(); + + private static ImmutableArray GetVariableDeclarationStatementVariables(BoundLocalDeclaration decl) + { + return (ImmutableArray)s_variablesMappings.GetValue(decl, + declaration => ImmutableArray.Create( + OperationFactory.CreateVariableDeclaration(declaration.LocalSymbol, Create(declaration.InitializerOpt), declaration.Syntax))); + } + + private static readonly ConditionalWeakTable s_multiVariablesMappings = + new ConditionalWeakTable(); + + private static ImmutableArray GetVariableDeclarationStatementVariables(BoundMultipleLocalDeclarations decl) + { + return (ImmutableArray)s_multiVariablesMappings.GetValue(decl, + multipleDeclarations => + multipleDeclarations.LocalDeclarations.SelectAsArray(declaration => + OperationFactory.CreateVariableDeclaration(declaration.LocalSymbol, Create(declaration.InitializerOpt), declaration.Syntax))); } } } diff --git a/src/Compilers/Core/Portable/CodeAnalysis.csproj b/src/Compilers/Core/Portable/CodeAnalysis.csproj index f34ef0fde72..638ddce26a1 100644 --- a/src/Compilers/Core/Portable/CodeAnalysis.csproj +++ b/src/Compilers/Core/Portable/CodeAnalysis.csproj @@ -43,7 +43,6 @@ - @@ -131,6 +130,7 @@ + @@ -403,7 +403,6 @@ - diff --git a/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs b/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs index 2ba003597ac..29afbbbf989 100644 --- a/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs +++ b/src/Compilers/Core/Portable/Generated/Operations.xml.Generated.cs @@ -1913,12 +1913,19 @@ public override void Accept(OperationVisitor visitor) /// internal sealed partial class IndexedPropertyReferenceExpression : PropertyReferenceExpressionBase, IHasArgumentsExpression, IIndexedPropertyReferenceExpression { - public IndexedPropertyReferenceExpression(IPropertySymbol property, IOperation instance, ISymbol member, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : + public IndexedPropertyReferenceExpression(IPropertySymbol property, IOperation instance, ISymbol member, ImmutableArray argumentsInParameterOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(property, member, OperationKind.IndexedPropertyReferenceExpression, isInvalid, syntax, type, constantValue) { + ArgumentsInParameterOrder = argumentsInParameterOrder; Instance = instance ?? throw new System.ArgumentNullException("instance"); } /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public ImmutableArray ArgumentsInParameterOrder { get; } + /// /// Instance of the type. Null if the reference is to a static/shared member. /// public override IOperation Instance { get; } @@ -1938,11 +1945,20 @@ public override void Accept(OperationVisitor visitor) internal sealed partial class LazyIndexedPropertyReferenceExpression : PropertyReferenceExpressionBase, IHasArgumentsExpression, IIndexedPropertyReferenceExpression { private readonly Lazy _lazyInstance; + private readonly Lazy> _lazyArgumentsInParameterOrder; - public LazyIndexedPropertyReferenceExpression(IPropertySymbol property, Lazy instance, ISymbol member, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(property, member, OperationKind.IndexedPropertyReferenceExpression, isInvalid, syntax, type, constantValue) + public LazyIndexedPropertyReferenceExpression(IPropertySymbol property, Lazy instance, ISymbol member, Lazy> argumentsInParameterOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(property, member, OperationKind.IndexedPropertyReferenceExpression, isInvalid, syntax, type, constantValue) { + _lazyArgumentsInParameterOrder = argumentsInParameterOrder; _lazyInstance = instance ?? throw new System.ArgumentNullException("instance"); } + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public ImmutableArray ArgumentsInParameterOrder => _lazyArgumentsInParameterOrder.Value; + /// /// Instance of the type. Null if the reference is to a static/shared member. /// @@ -2051,6 +2067,12 @@ internal abstract partial class InvocationExpressionBase : Operation, IHasArgume /// unless supplied in source. /// public abstract ImmutableArray ArgumentsInSourceOrder { get; } + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public abstract ImmutableArray ArgumentsInParameterOrder { get; } public override void Accept(OperationVisitor visitor) { visitor.VisitInvocationExpression(this); @@ -2066,11 +2088,12 @@ public override void Accept(OperationVisitor visitor) /// internal sealed partial class InvocationExpression : InvocationExpressionBase, IHasArgumentsExpression, IInvocationExpression { - public InvocationExpression(IMethodSymbol targetMethod, IOperation instance, bool isVirtual, ImmutableArray argumentsInSourceOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : + public InvocationExpression(IMethodSymbol targetMethod, IOperation instance, bool isVirtual, ImmutableArray argumentsInSourceOrder, ImmutableArray argumentsInParameterOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(targetMethod, isVirtual, isInvalid, syntax, type, constantValue) { Instance = instance ?? throw new System.ArgumentNullException("instance"); ArgumentsInSourceOrder = argumentsInSourceOrder; + ArgumentsInParameterOrder = argumentsInParameterOrder; } /// /// 'This' or 'Me' instance to be supplied to the method, or null if the method is static. @@ -2082,6 +2105,12 @@ internal sealed partial class InvocationExpression : InvocationExpressionBase, I /// unless supplied in source. /// public override ImmutableArray ArgumentsInSourceOrder { get; } + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public override ImmutableArray ArgumentsInParameterOrder { get; } } /// @@ -2091,11 +2120,13 @@ internal sealed partial class LazyInvocationExpression : InvocationExpressionBas { private readonly Lazy _lazyInstance; private readonly Lazy> _lazyArgumentsInSourceOrder; + private readonly Lazy> _lazyArgumentsInParameterOrder; - public LazyInvocationExpression(IMethodSymbol targetMethod, Lazy instance, bool isVirtual, Lazy> argumentsInSourceOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(targetMethod, isVirtual, isInvalid, syntax, type, constantValue) + public LazyInvocationExpression(IMethodSymbol targetMethod, Lazy instance, bool isVirtual, Lazy> argumentsInSourceOrder, Lazy> argumentsInParameterOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(targetMethod, isVirtual, isInvalid, syntax, type, constantValue) { _lazyInstance = instance ?? throw new System.ArgumentNullException("instance"); _lazyArgumentsInSourceOrder = argumentsInSourceOrder; + _lazyArgumentsInParameterOrder = argumentsInParameterOrder; } /// /// 'This' or 'Me' instance to be supplied to the method, or null if the method is static. @@ -2108,6 +2139,13 @@ public LazyInvocationExpression(IMethodSymbol targetMethod, Lazy ins /// unless supplied in source. /// public override ImmutableArray ArgumentsInSourceOrder => _lazyArgumentsInSourceOrder.Value; + + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public override ImmutableArray ArgumentsInParameterOrder => _lazyArgumentsInParameterOrder.Value; } /// @@ -2677,6 +2715,12 @@ internal abstract partial class ObjectCreationExpressionBase : Operation, IHasAr /// Explicitly-specified member initializers. /// public abstract ImmutableArray MemberInitializers { get; } + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public abstract ImmutableArray ArgumentsInParameterOrder { get; } public override void Accept(OperationVisitor visitor) { visitor.VisitObjectCreationExpression(this); @@ -2692,15 +2736,22 @@ public override void Accept(OperationVisitor visitor) /// internal sealed partial class ObjectCreationExpression : ObjectCreationExpressionBase, IHasArgumentsExpression, IObjectCreationExpression { - public ObjectCreationExpression(IMethodSymbol constructor, ImmutableArray memberInitializers, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : + public ObjectCreationExpression(IMethodSymbol constructor, ImmutableArray memberInitializers, ImmutableArray argumentsInParameterOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(constructor, isInvalid, syntax, type, constantValue) { MemberInitializers = memberInitializers; + ArgumentsInParameterOrder = argumentsInParameterOrder; } /// /// Explicitly-specified member initializers. /// public override ImmutableArray MemberInitializers { get; } + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public override ImmutableArray ArgumentsInParameterOrder { get; } } /// @@ -2709,15 +2760,24 @@ internal sealed partial class ObjectCreationExpression : ObjectCreationExpressio internal sealed partial class LazyObjectCreationExpression : ObjectCreationExpressionBase, IHasArgumentsExpression, IObjectCreationExpression { private readonly Lazy> _lazyMemberInitializers; + private readonly Lazy> _lazyArgumentsInParameterOrder; - public LazyObjectCreationExpression(IMethodSymbol constructor, Lazy> memberInitializers, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(constructor, isInvalid, syntax, type, constantValue) + public LazyObjectCreationExpression(IMethodSymbol constructor, Lazy> memberInitializers, Lazy> argumentsInParameterOrder, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : base(constructor, isInvalid, syntax, type, constantValue) { _lazyMemberInitializers = memberInitializers; + _lazyArgumentsInParameterOrder = argumentsInParameterOrder; } /// /// Explicitly-specified member initializers. /// public override ImmutableArray MemberInitializers => _lazyMemberInitializers.Value; + + /// + /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, + /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for + /// optional arguments missing in source. + /// + public override ImmutableArray ArgumentsInParameterOrder => _lazyArgumentsInParameterOrder.Value; } /// diff --git a/src/Compilers/Core/Portable/Operations/Expressions.cs b/src/Compilers/Core/Portable/Operations/Expressions.cs deleted file mode 100644 index 0c58f4ded3a..00000000000 --- a/src/Compilers/Core/Portable/Operations/Expressions.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Immutable; -using System.Linq; - -namespace Microsoft.CodeAnalysis.Semantics -{ - internal sealed partial class ConditionalChoiceExpression : IConditionalChoiceExpression - { - public ConditionalChoiceExpression(IOperation condition, IOperation ifTrue, IOperation ifFalse, ITypeSymbol resultType, SyntaxNode syntax) : - this(condition, - ifTrue, - ifFalse, - IsInvalidOperation(condition, ifTrue, ifFalse, resultType), - syntax, - resultType, - default(Optional)) - { - } - - private static bool IsInvalidOperation(IOperation condition, IOperation ifTrue, IOperation ifFalse, ITypeSymbol resultType) - { - return (condition == null || condition.IsInvalid || ifTrue == null || ifTrue.IsInvalid || ifFalse == null || ifFalse.IsInvalid || resultType == null); - } - } - - internal sealed partial class ExpressionStatement : IExpressionStatement - { - public ExpressionStatement(IOperation target, IOperation value, SyntaxNode syntax) : - this(new AssignmentExpression(target, value, IsInvalidOperation(target, value), syntax, target.Type, default(Optional)), - syntax) - { - } - - public ExpressionStatement(IOperation target, IOperation value, BinaryOperationKind binaryOperationKind, IMethodSymbol operatorMethod, SyntaxNode syntax) : - this(new CompoundAssignmentExpression( - binaryOperationKind, - target, - value, - operatorMethod != null, - operatorMethod, - IsInvalidOperation(target, value), - syntax, - target.Type, - default(Optional)), - syntax) - { - } - - private ExpressionStatement(IOperation expression, SyntaxNode syntax) : - this(expression, expression.IsInvalid, syntax, type: null, constantValue: default(Optional)) - { - } - - private static bool IsInvalidOperation(IOperation target, IOperation value) - { - return target == null || target.IsInvalid || value == null || value.IsInvalid; - } - } - - internal sealed partial class LiteralExpression : ILiteralExpression - { - public LiteralExpression(long value, ITypeSymbol resultType, SyntaxNode syntax) : - this(value.ToString(), isInvalid: false, syntax: syntax, type: resultType, constantValue: new Optional(value)) - { - } - - public LiteralExpression(ConstantValue value, ITypeSymbol resultType, SyntaxNode syntax) : - this(value.GetValueToDisplay(), value.IsBad, syntax, resultType, new Optional(value.Value)) - { - } - } - - internal sealed partial class BinaryOperatorExpression : IBinaryOperatorExpression - { - public BinaryOperatorExpression(BinaryOperationKind binaryOperationKind, IOperation left, IOperation right, ITypeSymbol resultType, SyntaxNode syntax) : - this(binaryOperationKind, left, right, - usesOperatorMethod: false, operatorMethod: null, - isInvalid: IsInvalidOperation(binaryOperationKind, left, right, resultType), - syntax: syntax, type: resultType, constantValue: default(Optional)) - { - } - - private static bool IsInvalidOperation(BinaryOperationKind binaryOperationKind, IOperation left, IOperation right, ITypeSymbol type) - { - return left == null || left.IsInvalid || right == null - || right.IsInvalid || binaryOperationKind == BinaryOperationKind.Invalid || type == null; - } - } - - internal sealed partial class ArrayCreationExpression : IArrayCreationExpression - { - public ArrayCreationExpression(IArrayTypeSymbol arrayType, ImmutableArray elementValues, SyntaxNode syntax) : - this(arrayType.ElementType, - ImmutableArray.Create(new LiteralExpression(elementValues.Count(), resultType: null, syntax: syntax)), - new ArrayInitializer(elementValues, elementValues.Any(v => v.IsInvalid), syntax, arrayType, default(Optional)), - syntax, - arrayType, - default(Optional)) - { - } - - private ArrayCreationExpression(ITypeSymbol elementType, ImmutableArray dimensionSizes, IArrayInitializer initializer, SyntaxNode syntax, ITypeSymbol type, Optional constantValue) : - this(elementType, dimensionSizes, initializer, initializer.IsInvalid, syntax, type, constantValue) - { - } - } - - internal partial class InvalidExpression : IInvalidExpression - { - public InvalidExpression(SyntaxNode syntax) : - this(isInvalid: true, syntax: syntax, type: null, constantValue: default(Optional)) - { - } - } -} diff --git a/src/Compilers/Core/Portable/Operations/IndexedPropertyReferenceExpression_IHasArgumentsExpression.cs b/src/Compilers/Core/Portable/Operations/IndexedPropertyReferenceExpression_IHasArgumentsExpression.cs index 3f855b2ea8f..31d6e967adb 100644 --- a/src/Compilers/Core/Portable/Operations/IndexedPropertyReferenceExpression_IHasArgumentsExpression.cs +++ b/src/Compilers/Core/Portable/Operations/IndexedPropertyReferenceExpression_IHasArgumentsExpression.cs @@ -6,12 +6,6 @@ namespace Microsoft.CodeAnalysis.Semantics { internal partial class IndexedPropertyReferenceExpression : IHasArgumentsExpression { - /// - /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, - /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for - /// optional arguments missing in source. - /// - public ImmutableArray ArgumentsInParameterOrder { get; } /// /// Find the argument supplied for a given parameter of the target method. /// @@ -19,18 +13,12 @@ internal partial class IndexedPropertyReferenceExpression : IHasArgumentsExpress /// Argument corresponding to the parameter. public IArgument GetArgumentMatchingParameter(IParameterSymbol parameter) { - throw new System.NotImplementedException(); + return this.ArgumentsInParameterOrder[parameter.Ordinal]; } } internal partial class LazyIndexedPropertyReferenceExpression : IHasArgumentsExpression { - /// - /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, - /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for - /// optional arguments missing in source. - /// - public ImmutableArray ArgumentsInParameterOrder { get; } /// /// Find the argument supplied for a given parameter of the target method. /// @@ -38,7 +26,7 @@ internal partial class LazyIndexedPropertyReferenceExpression : IHasArgumentsExp /// Argument corresponding to the parameter. public IArgument GetArgumentMatchingParameter(IParameterSymbol parameter) { - throw new System.NotImplementedException(); + return this.ArgumentsInParameterOrder[parameter.Ordinal]; } } } diff --git a/src/Compilers/Core/Portable/Operations/InvocationExpression_IHasArgumentsExpression.cs b/src/Compilers/Core/Portable/Operations/InvocationExpression_IHasArgumentsExpression.cs index 214939410d9..f13f57e2410 100644 --- a/src/Compilers/Core/Portable/Operations/InvocationExpression_IHasArgumentsExpression.cs +++ b/src/Compilers/Core/Portable/Operations/InvocationExpression_IHasArgumentsExpression.cs @@ -6,12 +6,6 @@ namespace Microsoft.CodeAnalysis.Semantics { internal partial class InvocationExpressionBase : IHasArgumentsExpression { - /// - /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, - /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for - /// optional arguments missing in source. - /// - public ImmutableArray ArgumentsInParameterOrder { get; } /// /// Find the argument supplied for a given parameter of the target method. /// @@ -19,7 +13,7 @@ internal partial class InvocationExpressionBase : IHasArgumentsExpression /// Argument corresponding to the parameter. public IArgument GetArgumentMatchingParameter(IParameterSymbol parameter) { - throw new System.NotImplementedException(); + return this.ArgumentsInParameterOrder[parameter.Ordinal]; } } } diff --git a/src/Compilers/Core/Portable/Operations/ObjectCreationExpression_IHasArgumentsExpression.cs b/src/Compilers/Core/Portable/Operations/ObjectCreationExpression_IHasArgumentsExpression.cs index df7b66726ed..b578c20250e 100644 --- a/src/Compilers/Core/Portable/Operations/ObjectCreationExpression_IHasArgumentsExpression.cs +++ b/src/Compilers/Core/Portable/Operations/ObjectCreationExpression_IHasArgumentsExpression.cs @@ -6,12 +6,6 @@ namespace Microsoft.CodeAnalysis.Semantics { internal partial class ObjectCreationExpressionBase : IHasArgumentsExpression { - /// - /// Arguments of the invocation, excluding the instance argument. Arguments are in parameter order, - /// and params/ParamArray arguments have been collected into arrays. Default values are supplied for - /// optional arguments missing in source. - /// - public ImmutableArray ArgumentsInParameterOrder { get; } /// /// Find the argument supplied for a given parameter of the target method. /// @@ -19,7 +13,7 @@ internal partial class ObjectCreationExpressionBase : IHasArgumentsExpression /// Argument corresponding to the parameter. public IArgument GetArgumentMatchingParameter(IParameterSymbol parameter) { - throw new System.NotImplementedException(); + return this.ArgumentsInParameterOrder[parameter.Ordinal]; } } } diff --git a/src/Compilers/Core/Portable/Operations/OperationFactory.cs b/src/Compilers/Core/Portable/Operations/OperationFactory.cs new file mode 100644 index 00000000000..d93a368cad9 --- /dev/null +++ b/src/Compilers/Core/Portable/Operations/OperationFactory.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Linq; + +namespace Microsoft.CodeAnalysis.Semantics +{ + internal static class OperationFactory + { + public static VariableDeclaration CreateVariableDeclaration(ILocalSymbol variable, IOperation initialValue, SyntaxNode syntax) + { + return new VariableDeclaration( + variable, + initialValue, + variable == null || (initialValue != null && initialValue.IsInvalid), + syntax, + type: null, + constantValue: default(Optional)); + } + + public static ConditionalChoiceExpression CreateConditionalChoiceExpression(IOperation condition, IOperation ifTrue, IOperation ifFalse, ITypeSymbol resultType, SyntaxNode syntax) + { + var isInvalid = (condition == null || condition.IsInvalid || ifTrue == null || ifTrue.IsInvalid || ifFalse == null || ifFalse.IsInvalid || resultType == null); + + return new ConditionalChoiceExpression( + condition, + ifTrue, + ifFalse, + isInvalid, + syntax, + resultType, + default(Optional)); + } + + public static ExpressionStatement CreateAssignmentExpressionStatement(IOperation target, IOperation value, SyntaxNode syntax) + { + var isInvalid = target == null || target.IsInvalid || value == null || value.IsInvalid; + var expression = new AssignmentExpression(target, value, isInvalid, syntax, target.Type, default(Optional)); + return new ExpressionStatement(expression, expression.IsInvalid, syntax, type: null, constantValue: default(Optional)); + } + + public static ExpressionStatement CreateCompoundAssignmentExpressionStatement( + IOperation target, IOperation value, BinaryOperationKind binaryOperationKind, IMethodSymbol operatorMethod, SyntaxNode syntax) + { + var isInvalid = target == null || target.IsInvalid || value == null || value.IsInvalid; + var expression = new CompoundAssignmentExpression( + binaryOperationKind, + target, + value, + operatorMethod != null, + operatorMethod, + isInvalid, + syntax, + target.Type, + default(Optional)); + + return new ExpressionStatement(expression, expression.IsInvalid, syntax, type: null, constantValue: default(Optional)); + } + + public static LiteralExpression CreateLiteralExpression(long value, ITypeSymbol resultType, SyntaxNode syntax) + { + return new LiteralExpression(value.ToString(), isInvalid: false, syntax: syntax, type: resultType, constantValue: new Optional(value)); + } + + public static LiteralExpression CreateLiteralExpression(ConstantValue value, ITypeSymbol resultType, SyntaxNode syntax) + { + return new LiteralExpression(value.GetValueToDisplay(), value.IsBad, syntax, resultType, new Optional(value.Value)); + } + + public static BinaryOperatorExpression CreateBinaryOperatorExpression( + BinaryOperationKind binaryOperationKind, IOperation left, IOperation right, ITypeSymbol resultType, SyntaxNode syntax) + { + var isInvalid = left == null || left.IsInvalid || right == null || right.IsInvalid || binaryOperationKind == BinaryOperationKind.Invalid || resultType == null; + return new BinaryOperatorExpression( + binaryOperationKind, left, right, + usesOperatorMethod: false, operatorMethod: null, + isInvalid: isInvalid, syntax: syntax, type: resultType, constantValue: default(Optional)); + } + + public static ArrayCreationExpression CreateArrayCreationExpression( + IArrayTypeSymbol arrayType, ImmutableArray elementValues, SyntaxNode syntax) + { + var initializer = new ArrayInitializer(elementValues, elementValues.Any(v => v.IsInvalid), syntax, arrayType, default(Optional)); + return new ArrayCreationExpression( + arrayType.ElementType, + ImmutableArray.Create(CreateLiteralExpression(elementValues.Count(), resultType: null, syntax: syntax)), + initializer, + initializer.IsInvalid, + syntax, + arrayType, + default(Optional)); + } + + public static InvalidExpression CreateInvalidExpression(SyntaxNode syntax) + { + return new InvalidExpression(isInvalid: true, syntax: syntax, type: null, constantValue: default(Optional)); + } + } +} \ No newline at end of file diff --git a/src/Compilers/Core/Portable/Operations/Statement.cs b/src/Compilers/Core/Portable/Operations/Statement.cs deleted file mode 100644 index 68aca0c59f5..00000000000 --- a/src/Compilers/Core/Portable/Operations/Statement.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.CodeAnalysis.Semantics -{ - internal partial class VariableDeclaration : IVariableDeclaration - { - public VariableDeclaration(ILocalSymbol variable, IOperation initialValue, SyntaxNode syntax) : - this(variable, - initialValue, - variable == null || (initialValue != null && initialValue.IsInvalid), - syntax, - type: null, - constantValue: default(Optional)) - { - } - } -} \ No newline at end of file diff --git a/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb b/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb index 614c4a8be34..2ac3c7e3ef9 100644 --- a/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb +++ b/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb @@ -58,7 +58,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If End If - Return New InvalidExpression(parent.Syntax) + Return OperationFactory.CreateInvalidExpression(parent.Syntax) End Function End Class diff --git a/src/Compilers/VisualBasic/Portable/BoundTree/Statement.vb b/src/Compilers/VisualBasic/Portable/BoundTree/Statement.vb index 0639f4d7ef7..159adcc6274 100644 --- a/src/Compilers/VisualBasic/Portable/BoundTree/Statement.vb +++ b/src/Compilers/VisualBasic/Portable/BoundTree/Statement.vb @@ -569,7 +569,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If Dim stepOperand As IOperation = If(stepValue.IsConstant, DirectCast(stepValue, IOperation), New Temporary(SyntheticLocalKind.ForLoopStepValue, BoundFor, stepValue)) - statements.Add(New ExpressionStatement(controlReference, stepOperand, Semantics.Expression.DeriveAdditionKind(controlType), Nothing, stepValue.Syntax)) + statements.Add(OperationFactory.CreateCompoundAssignmentExpressionStatement(controlReference, stepOperand, Semantics.Expression.DeriveAdditionKind(controlType), Nothing, stepValue.Syntax)) End If End If @@ -592,17 +592,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' ControlVariable = InitialValue Dim controlReference As IOperation = BoundFor.ControlVariable If controlReference IsNot Nothing Then - statements.Add(New ExpressionStatement(controlReference, BoundFor.InitialValue, BoundFor.InitialValue.Syntax)) + statements.Add(OperationFactory.CreateAssignmentExpressionStatement(controlReference, BoundFor.InitialValue, BoundFor.InitialValue.Syntax)) End If ' T0 = LimitValue If Not Me.LimitValue.IsConstant Then - statements.Add(New ExpressionStatement(New Temporary(SyntheticLocalKind.ForLoopLimitValue, BoundFor, BoundFor.LimitValue), BoundFor.LimitValue, BoundFor.LimitValue.Syntax)) + statements.Add(OperationFactory.CreateAssignmentExpressionStatement(New Temporary(SyntheticLocalKind.ForLoopLimitValue, BoundFor, BoundFor.LimitValue), BoundFor.LimitValue, BoundFor.LimitValue.Syntax)) End If ' T1 = StepValue If BoundFor.StepValue IsNot Nothing AndAlso Not BoundFor.StepValue.IsConstant Then - statements.Add(New ExpressionStatement(New Temporary(SyntheticLocalKind.ForLoopStepValue, BoundFor, BoundFor.StepValue), BoundFor.StepValue, BoundFor.StepValue.Syntax)) + statements.Add(OperationFactory.CreateAssignmentExpressionStatement(New Temporary(SyntheticLocalKind.ForLoopStepValue, BoundFor, BoundFor.StepValue), BoundFor.StepValue, BoundFor.StepValue.Syntax)) End If Return statements.ToImmutableAndFree() @@ -640,25 +640,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' Either ControlVariable <= LimitValue or ControlVariable >= LimitValue, depending on whether the step value is negative. Dim relationalCode As BinaryOperationKind = DeriveBinaryOperationKind(If(BoundFor.StepValue IsNot Nothing AndAlso BoundFor.StepValue.ConstantValueOpt.IsNegativeNumeric, BinaryOperatorKind.GreaterThanOrEqual, BinaryOperatorKind.LessThanOrEqual), controlVariable) - Return New BinaryOperatorExpression(relationalCode, controlVariable, limitValue, booleanType, limitValue.Syntax) + Return OperationFactory.CreateBinaryOperatorExpression(relationalCode, controlVariable, limitValue, booleanType, limitValue.Syntax) Else ' If(StepValue >= 0, ControlVariable <= LimitValue, ControlVariable >= LimitValue) Dim stepValue As IOperation = New Temporary(SyntheticLocalKind.ForLoopStepValue, BoundFor, BoundFor.StepValue) Dim stepRelationalCode As BinaryOperationKind = DeriveBinaryOperationKind(BinaryOperatorKind.GreaterThanOrEqual, BoundFor.StepValue) - Dim stepCondition As IOperation = New BinaryOperatorExpression(stepRelationalCode, + Dim stepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(stepRelationalCode, stepValue, - New LiteralExpression(Semantics.Expression.SynthesizeNumeric(stepValue.Type, 0), BoundFor.StepValue.Type, BoundFor.StepValue.Syntax), + OperationFactory.CreateLiteralExpression(Semantics.Expression.SynthesizeNumeric(stepValue.Type, 0), BoundFor.StepValue.Type, BoundFor.StepValue.Syntax), booleanType, BoundFor.StepValue.Syntax) Dim positiveStepRelationalCode As BinaryOperationKind = DeriveBinaryOperationKind(BinaryOperatorKind.LessThanOrEqual, controlVariable) - Dim positiveStepCondition As IOperation = New BinaryOperatorExpression(positiveStepRelationalCode, controlVariable, limitValue, booleanType, limitValue.Syntax) + Dim positiveStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(positiveStepRelationalCode, controlVariable, limitValue, booleanType, limitValue.Syntax) Dim negativeStepRelationalCode As BinaryOperationKind = DeriveBinaryOperationKind(BinaryOperatorKind.GreaterThanOrEqual, controlVariable) - Dim negativeStepCondition As IOperation = New BinaryOperatorExpression(negativeStepRelationalCode, controlVariable, limitValue, booleanType, limitValue.Syntax) + Dim negativeStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(negativeStepRelationalCode, controlVariable, limitValue, booleanType, limitValue.Syntax) - Return New ConditionalChoiceExpression(stepCondition, positiveStepCondition, negativeStepCondition, booleanType, limitValue.Syntax) + Return OperationFactory.CreateConditionalChoiceExpression(stepCondition, positiveStepCondition, negativeStepCondition, booleanType, limitValue.Syntax) End If End If End Function) @@ -1058,11 +1058,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic For Each base In dimStatement.LocalDeclarations If base.Kind = BoundKind.LocalDeclaration Then Dim declaration = DirectCast(base, BoundLocalDeclaration) - builder.Add(New VariableDeclaration(declaration.LocalSymbol, declaration.InitializerOpt, declaration.Syntax)) + builder.Add(OperationFactory.CreateVariableDeclaration(declaration.LocalSymbol, declaration.InitializerOpt, declaration.Syntax)) ElseIf base.Kind = BoundKind.AsNewLocalDeclarations Then Dim asNewDeclarations = DirectCast(base, BoundAsNewLocalDeclarations) For Each asNewDeclaration In asNewDeclarations.LocalDeclarations - builder.Add(New VariableDeclaration(asNewDeclaration.LocalSymbol, asNewDeclarations.Initializer, asNewDeclaration.Syntax)) + builder.Add(OperationFactory.CreateVariableDeclaration(asNewDeclaration.LocalSymbol, asNewDeclarations.Initializer, asNewDeclaration.Syntax)) Next End If Next -- GitLab