diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 534ce82d634bc2120c81f8de7ab87bbf173e8092..f09e82a09501ebcaeda2d63a23fed4f5158482d2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -4580,9 +4580,9 @@ private BoundExpression BindUnexpectedComplexElementInitializer(InitializerExpre return new BoundDynamicCollectionElementInitializer( elementInitializer, - arguments: boundElementInitializerExpressions, - implicitReceiver, applicableMethods: ImmutableArray.Empty, + implicitReceiver, + arguments: boundElementInitializerExpressions, type: GetSpecialType(SpecialType.System_Void, diagnostics, elementInitializer), hasErrors: hasErrors); } @@ -4601,9 +4601,9 @@ private BoundExpression BindUnexpectedComplexElementInitializer(InitializerExpre var dynamicInvocation = (BoundDynamicInvocation)addMethodInvocation; return new BoundDynamicCollectionElementInitializer( elementInitializer, - dynamicInvocation.Arguments, - implicitReceiver, dynamicInvocation.ApplicableMethods, + implicitReceiver, + dynamicInvocation.Arguments, dynamicInvocation.Type, hasErrors: dynamicInvocation.HasAnyErrors); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index 8d4f33f35803f646a6324a5796aa480d59e35565..c3f8685dcade6d4daded95e40b8ad0c4d734eb31 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -347,11 +347,11 @@ private BoundExpression BindArgListOperator(InvocationExpressionSyntax node, Dia return new BoundDynamicInvocation( node, - expression, - argArray, arguments.GetNames(), refKindsArray, applicableMethods, + expression, + argArray, type: Compilation.DynamicType, hasErrors: hasErrors); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs index fac79146f0a33ea18c4249e0e6ab936b9c92c63b..5e4ed63f49625e7d307c6ccef057b6ba9c1cf8b4 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs @@ -460,7 +460,7 @@ private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, Di if (left.HasAnyErrors || right.HasAnyErrors) { // NOTE: no user-defined conversion candidates - return new BoundBinaryOperator(node, kind, left, right, ConstantValue.NotAvailable, null, LookupResultKind.Empty, GetBinaryOperatorErrorType(kind, diagnostics, node), true); + return new BoundBinaryOperator(node, kind, ConstantValue.NotAvailable, null, LookupResultKind.Empty, left, right, GetBinaryOperatorErrorType(kind, diagnostics, node), true); } TypeSymbol leftType = left.Type; @@ -733,8 +733,8 @@ private BoundExpression BindConditionalLogicalOperator(BinaryExpressionSyntax no if (left.HasAnyErrors || right.HasAnyErrors) { // NOTE: no candidate user-defined operators. - return new BoundBinaryOperator(node, kind, left, right, ConstantValue.NotAvailable, methodOpt: null, - resultKind: LookupResultKind.Empty, type: GetBinaryOperatorErrorType(kind, diagnostics, node), hasErrors: true); + return new BoundBinaryOperator(node, kind, ConstantValue.NotAvailable, methodOpt: null, + resultKind: LookupResultKind.Empty, left, right, type: GetBinaryOperatorErrorType(kind, diagnostics, node), hasErrors: true); } // Let's take an easy out here. The vast majority of the time the operands will @@ -747,8 +747,8 @@ private BoundExpression BindConditionalLogicalOperator(BinaryExpressionSyntax no var constantValue = FoldBinaryOperator(node, kind | BinaryOperatorKind.Bool, left, right, SpecialType.System_Boolean, diagnostics); // NOTE: no candidate user-defined operators. - return new BoundBinaryOperator(node, kind | BinaryOperatorKind.Bool, left, right, constantValue, methodOpt: null, - resultKind: LookupResultKind.Viable, type: left.Type, hasErrors: constantValue != null && constantValue.IsBad); + return new BoundBinaryOperator(node, kind | BinaryOperatorKind.Bool, constantValue, methodOpt: null, + resultKind: LookupResultKind.Viable, left, right, type: left.Type, hasErrors: constantValue != null && constantValue.IsBad); } if (left.HasDynamicType() || right.HasDynamicType()) diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundAnonymousObjectCreationExpression.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundAnonymousObjectCreationExpression.cs new file mode 100644 index 0000000000000000000000000000000000000000..0577c039d88d866ac3044c357ea40863c4780930 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundAnonymousObjectCreationExpression.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundAnonymousObjectCreationExpression : IBoundAnonymousObjectCreation + { + ImmutableArray IBoundAnonymousObjectCreation.Arguments => this.Arguments; + ImmutableArray IBoundAnonymousObjectCreation.PropertyDeclarationsOpt => this.Declarations; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundCall.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundCall.cs new file mode 100644 index 0000000000000000000000000000000000000000..05b52d2cc61a1818f77e65adde6aee0039df9402 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundCall.cs @@ -0,0 +1,10 @@ +// 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.CSharp +{ + internal partial class BoundCall : IBoundInvocableExpression + { + BoundExpression IBoundInvocableExpression.GetAsBoundNode() => this; + BoundExpression IBoundInvocableExpression.ReceiverOpt => this.ReceiverOpt; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundCollectionElementInitializer.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundCollectionElementInitializer.cs new file mode 100644 index 0000000000000000000000000000000000000000..d2d7099c93ff4dcd2df61881f8f670f69a71f737 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundCollectionElementInitializer.cs @@ -0,0 +1,10 @@ +// 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.CSharp +{ + internal partial class BoundCollectionElementInitializer : IBoundInvocableExpression + { + BoundExpression IBoundInvocableExpression.GetAsBoundNode() => this; + BoundExpression IBoundInvocableExpression.ReceiverOpt => this.ImplicitReceiverOpt; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundConditionalOperator.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundConditionalOperator.cs new file mode 100644 index 0000000000000000000000000000000000000000..76aab6bf5faea2d4b36ef4c8616dc44f9a2b3b40 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundConditionalOperator.cs @@ -0,0 +1,13 @@ +// 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.CSharp +{ + internal partial class BoundConditionalOperator : IBoundConditional + { + BoundNode IBoundConditional.AlternativeOpt => this.Alternative; + + BoundNode IBoundConditional.Condition => this.Condition; + + BoundNode IBoundConditional.Consequence => this.Consequence; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundDynamicCollectionElementInitializer.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundDynamicCollectionElementInitializer.cs new file mode 100644 index 0000000000000000000000000000000000000000..c94c347c0625309acb90a04053c473fa0b65f2a9 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundDynamicCollectionElementInitializer.cs @@ -0,0 +1,6 @@ +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundDynamicCollectionElementInitializer + { + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundIfStatement.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundIfStatement.cs new file mode 100644 index 0000000000000000000000000000000000000000..3ece69cc4a9e9ba26977784b6015b267d27f7c9b --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundIfStatement.cs @@ -0,0 +1,13 @@ +// 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.CSharp +{ + internal partial class BoundIfStatement : IBoundConditional + { + BoundNode IBoundConditional.Condition => this.Condition; + + BoundNode IBoundConditional.Consequence => this.Consequence; + + BoundNode IBoundConditional.AlternativeOpt => this.AlternativeOpt; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml index 74b636d5ce66d8dc0afa6750a22fa6751643cd6e..d9305d59b262f00e8f7462da949ea413260db62f 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml @@ -340,13 +340,15 @@ - + - - + + + + @@ -367,13 +369,8 @@ - - - - + - - @@ -920,16 +917,16 @@ - + + + + - - - - + @@ -1209,11 +1206,14 @@ - - - + + + + + + @@ -1460,14 +1460,11 @@ - + - - - diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundObjectCreationExpression.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundObjectCreationExpression.cs index cabfbf3d65ba50b8cba4f548a05a5962585eaae9..68bcdcb42ca188d306a7665ece11aa1806352d5b 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundObjectCreationExpression.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundObjectCreationExpression.cs @@ -5,7 +5,7 @@ namespace Microsoft.CodeAnalysis.CSharp { - internal partial class BoundObjectCreationExpression + internal partial class BoundObjectCreationExpression : IBoundAnonymousObjectCreation { public BoundObjectCreationExpression(SyntaxNode syntax, MethodSymbol constructor, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, bool expanded, ImmutableArray argsToParamsOpt, ConstantValue constantValueOpt, @@ -13,6 +13,10 @@ internal partial class BoundObjectCreationExpression : this(syntax, constructor, ImmutableArray.Empty, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, constantValueOpt, initializerExpressionOpt, binderOpt, type, hasErrors) { } + ImmutableArray IBoundAnonymousObjectCreation.Arguments => this.Arguments; + + ImmutableArray IBoundAnonymousObjectCreation.PropertyDeclarationsOpt => ImmutableArray.Empty; + public BoundObjectCreationExpression Update(MethodSymbol constructor, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, bool expanded, ImmutableArray argsToParamsOpt, ConstantValue constantValueOpt, BoundObjectInitializerExpressionBase initializerExpressionOpt, Binder binderOpt, TypeSymbol type) { diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundPatternSwitchSection.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundPatternSwitchSection.cs new file mode 100644 index 0000000000000000000000000000000000000000..8c43fed523cdccfc0fc70e0a42aade3cd196f84e --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundPatternSwitchSection.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundPatternSwitchSection : IBoundSwitchSection + { + ImmutableArray IBoundSwitchSection.SwitchLabels => this.SwitchLabels.CastArray(); + ImmutableArray IBoundSwitchSection.Statements => this.Statements; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundPatternSwitchStatement.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundPatternSwitchStatement.cs new file mode 100644 index 0000000000000000000000000000000000000000..11133dbe84da39cc399d568268d71105d77a1e6f --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundPatternSwitchStatement.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundPatternSwitchStatement : IBoundSwitchStatement + { + BoundNode IBoundSwitchStatement.Value => this.Expression; + ImmutableArray IBoundSwitchStatement.Cases => this.SwitchSections.CastArray(); + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundSwitchSection.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundSwitchSection.cs new file mode 100644 index 0000000000000000000000000000000000000000..d3df166c73ef687d626796cf1a086385edd58984 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundSwitchSection.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundSwitchSection : IBoundSwitchSection + { + ImmutableArray IBoundSwitchSection.SwitchLabels => this.SwitchLabels.CastArray(); + ImmutableArray IBoundSwitchSection.Statements => this.Statements; + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundSwitchStatement.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundSwitchStatement.cs new file mode 100644 index 0000000000000000000000000000000000000000..25b3c342d3c976b9b6f2566229d9978589e1df6e --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundSwitchStatement.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundSwitchStatement : IBoundSwitchStatement + { + BoundNode IBoundSwitchStatement.Value => this.Expression; + ImmutableArray IBoundSwitchStatement.Cases => this.SwitchSections.CastArray(); + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundTreeRewriter.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundTreeRewriter.cs index 3d5a4068422b204d45d58bf2af964a42e391ca45..29d36046253ce6f7664d2325df9f174b970ef32f 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundTreeRewriter.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundTreeRewriter.cs @@ -141,7 +141,7 @@ public sealed override BoundNode VisitBinaryOperator(BoundBinaryOperator node) binary = stack.Pop(); var right = (BoundExpression)this.Visit(binary.Right); var type = this.VisitType(binary.Type); - left = binary.Update(binary.OperatorKind, left, right, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, type); + left = binary.Update(binary.OperatorKind, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, left, right, type); } while (stack.Count > 0); diff --git a/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs b/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs index 499cffa26c8591f65f6a30435d3bc90095d264ad..c685bb993d8437ae5db2ecd6fa91e16c167109d4 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs @@ -336,11 +336,11 @@ internal sealed partial class BoundBinaryOperator : this( syntax, operatorKind, - left, - right, constantValueOpt, methodOpt, resultKind, + left, + right, type, hasErrors) { @@ -365,12 +365,12 @@ internal sealed partial class BoundUserDefinedConditionalLogicalOperator : this( syntax, operatorKind, - left, - right, logicalOperator, trueOperator, falseOperator, resultKind, + left, + right, type, hasErrors) { diff --git a/src/Compilers/CSharp/Portable/BoundTree/IBoundAnonymousObjectCreation.cs b/src/Compilers/CSharp/Portable/BoundTree/IBoundAnonymousObjectCreation.cs new file mode 100644 index 0000000000000000000000000000000000000000..72987d5921fcb150799665b8f43718e5734a9a36 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/IBoundAnonymousObjectCreation.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal interface IBoundAnonymousObjectCreation + { + ImmutableArray Arguments { get; } + ImmutableArray PropertyDeclarationsOpt { get; } + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/IBoundConditional.cs b/src/Compilers/CSharp/Portable/BoundTree/IBoundConditional.cs new file mode 100644 index 0000000000000000000000000000000000000000..979ae4a7564cedcb82467e9f945bb25de7545af3 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/IBoundConditional.cs @@ -0,0 +1,11 @@ +// 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.CSharp +{ + interface IBoundConditional + { + BoundNode Condition { get; } + BoundNode Consequence { get; } + BoundNode AlternativeOpt { get; } + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/IBoundInvocableExpression.cs b/src/Compilers/CSharp/Portable/BoundTree/IBoundInvocableExpression.cs new file mode 100644 index 0000000000000000000000000000000000000000..43470579a6fb2b9b01e4b7489c6003a74111d2f0 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/IBoundInvocableExpression.cs @@ -0,0 +1,10 @@ +// 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.CSharp +{ + internal interface IBoundInvocableExpression + { + BoundExpression GetAsBoundNode(); + BoundExpression ReceiverOpt { get; } + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/IBoundSwitchSection.cs b/src/Compilers/CSharp/Portable/BoundTree/IBoundSwitchSection.cs new file mode 100644 index 0000000000000000000000000000000000000000..94b5bff42931608d6b8d963c00e691b1ae46e3c1 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/IBoundSwitchSection.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal interface IBoundSwitchSection + { + ImmutableArray SwitchLabels { get; } + ImmutableArray Statements { get; } + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/IBoundSwitchStatement.cs b/src/Compilers/CSharp/Portable/BoundTree/IBoundSwitchStatement.cs new file mode 100644 index 0000000000000000000000000000000000000000..07ab222fa829d9bf8bd65c3c552342ae3e4f1869 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/IBoundSwitchStatement.cs @@ -0,0 +1,12 @@ +// 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; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal interface IBoundSwitchStatement + { + BoundNode Value { get; } + ImmutableArray Cases { get; } + } +} diff --git a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs index aabfdffc21c4c1788899fe2c1f33dfe724095f5f..e812f20da4498a5b2a7b7cc3afc479db6e36b93e 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs @@ -1388,7 +1388,7 @@ public override BoundNode VisitBinaryOperator(BoundBinaryOperator node) } var type = this.VisitType(binary.Type); - left = binary.Update(binary.OperatorKind, left, right, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, type); + left = binary.Update(binary.OperatorKind, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, left, right, type); if (stack.Count == 0) { @@ -1422,7 +1422,7 @@ private BoundNode VisitBinaryOperatorSimple(BoundBinaryOperator node) EnsureStackState(cookie); // implicit label here - return node.Update(node.OperatorKind, left, right, node.ConstantValueOpt, node.MethodOpt, node.ResultKind, node.Type); + return node.Update(node.OperatorKind, node.ConstantValueOpt, node.MethodOpt, node.ResultKind, left, right, node.Type); } return base.VisitBinaryOperator(node); @@ -1997,7 +1997,7 @@ public override BoundNode VisitBinaryOperator(BoundBinaryOperator node) binary = stack.Pop(); var right = (BoundExpression)this.Visit(binary.Right); var type = this.VisitType(binary.Type); - left = binary.Update(binary.OperatorKind, left, right, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, type); + left = binary.Update(binary.OperatorKind, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, left, right, type); if (stack.Count == 0) { diff --git a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs index 80426be4a10a617852162697b3d8d65756b7adbc..514ff2f1e59598f89dae4f5d16a62057991bc65e 100644 --- a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs @@ -1162,19 +1162,37 @@ public BoundRangeExpression Update(BoundExpression leftOperand, BoundExpression } } - internal sealed partial class BoundBinaryOperator : BoundExpression + internal abstract partial class BoundBinaryOperatorBase : BoundExpression { - public BoundBinaryOperator(SyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression left, BoundExpression right, ConstantValue constantValueOpt, MethodSymbol methodOpt, LookupResultKind resultKind, TypeSymbol type, bool hasErrors = false) - : base(BoundKind.BinaryOperator, syntax, type, hasErrors || left.HasErrors() || right.HasErrors()) + protected BoundBinaryOperatorBase(BoundKind kind, SyntaxNode syntax, BoundExpression left, BoundExpression right, TypeSymbol type, bool hasErrors = false) + : base(kind, syntax, type, hasErrors) { Debug.Assert(left != null, "Field 'left' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(right != null, "Field 'right' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(type != null, "Field 'type' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - this.OperatorKind = operatorKind; this.Left = left; this.Right = right; + } + + + public BoundExpression Left { get; } + + public BoundExpression Right { get; } + } + + internal sealed partial class BoundBinaryOperator : BoundBinaryOperatorBase + { + public BoundBinaryOperator(SyntaxNode syntax, BinaryOperatorKind operatorKind, ConstantValue constantValueOpt, MethodSymbol methodOpt, LookupResultKind resultKind, BoundExpression left, BoundExpression right, TypeSymbol type, bool hasErrors = false) + : base(BoundKind.BinaryOperator, syntax, left, right, type, hasErrors || left.HasErrors() || right.HasErrors()) + { + + Debug.Assert(left != null, "Field 'left' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(right != null, "Field 'right' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(type != null, "Field 'type' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + + this.OperatorKind = operatorKind; this.ConstantValueOpt = constantValueOpt; this.MethodOpt = methodOpt; this._ResultKind = resultKind; @@ -1183,10 +1201,6 @@ public BoundBinaryOperator(SyntaxNode syntax, BinaryOperatorKind operatorKind, B public BinaryOperatorKind OperatorKind { get; } - public BoundExpression Left { get; } - - public BoundExpression Right { get; } - public ConstantValue ConstantValueOpt { get; } public MethodSymbol MethodOpt { get; } @@ -1199,11 +1213,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor) return visitor.VisitBinaryOperator(this); } - public BoundBinaryOperator Update(BinaryOperatorKind operatorKind, BoundExpression left, BoundExpression right, ConstantValue constantValueOpt, MethodSymbol methodOpt, LookupResultKind resultKind, TypeSymbol type) + public BoundBinaryOperator Update(BinaryOperatorKind operatorKind, ConstantValue constantValueOpt, MethodSymbol methodOpt, LookupResultKind resultKind, BoundExpression left, BoundExpression right, TypeSymbol type) { - if (operatorKind != this.OperatorKind || left != this.Left || right != this.Right || constantValueOpt != this.ConstantValueOpt || methodOpt != this.MethodOpt || resultKind != this.ResultKind || type != this.Type) + if (operatorKind != this.OperatorKind || constantValueOpt != this.ConstantValueOpt || methodOpt != this.MethodOpt || resultKind != this.ResultKind || left != this.Left || right != this.Right || type != this.Type) { - var result = new BoundBinaryOperator(this.Syntax, operatorKind, left, right, constantValueOpt, methodOpt, resultKind, type, this.HasErrors); + var result = new BoundBinaryOperator(this.Syntax, operatorKind, constantValueOpt, methodOpt, resultKind, left, right, type, this.HasErrors); result.WasCompilerGenerated = this.WasCompilerGenerated; return result; } @@ -1262,22 +1276,20 @@ public BoundTupleBinaryOperator Update(BoundExpression left, BoundExpression rig } } - internal sealed partial class BoundUserDefinedConditionalLogicalOperator : BoundExpression + internal sealed partial class BoundUserDefinedConditionalLogicalOperator : BoundBinaryOperatorBase { - public BoundUserDefinedConditionalLogicalOperator(SyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression left, BoundExpression right, MethodSymbol logicalOperator, MethodSymbol trueOperator, MethodSymbol falseOperator, LookupResultKind resultKind, TypeSymbol type, bool hasErrors = false) - : base(BoundKind.UserDefinedConditionalLogicalOperator, syntax, type, hasErrors || left.HasErrors() || right.HasErrors()) + public BoundUserDefinedConditionalLogicalOperator(SyntaxNode syntax, BinaryOperatorKind operatorKind, MethodSymbol logicalOperator, MethodSymbol trueOperator, MethodSymbol falseOperator, LookupResultKind resultKind, BoundExpression left, BoundExpression right, TypeSymbol type, bool hasErrors = false) + : base(BoundKind.UserDefinedConditionalLogicalOperator, syntax, left, right, type, hasErrors || left.HasErrors() || right.HasErrors()) { - Debug.Assert(left != null, "Field 'left' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - Debug.Assert(right != null, "Field 'right' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(logicalOperator != null, "Field 'logicalOperator' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(trueOperator != null, "Field 'trueOperator' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(falseOperator != null, "Field 'falseOperator' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(left != null, "Field 'left' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(right != null, "Field 'right' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(type != null, "Field 'type' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); this.OperatorKind = operatorKind; - this.Left = left; - this.Right = right; this.LogicalOperator = logicalOperator; this.TrueOperator = trueOperator; this.FalseOperator = falseOperator; @@ -1287,10 +1299,6 @@ public BoundUserDefinedConditionalLogicalOperator(SyntaxNode syntax, BinaryOpera public BinaryOperatorKind OperatorKind { get; } - public BoundExpression Left { get; } - - public BoundExpression Right { get; } - public MethodSymbol LogicalOperator { get; } public MethodSymbol TrueOperator { get; } @@ -1305,11 +1313,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor) return visitor.VisitUserDefinedConditionalLogicalOperator(this); } - public BoundUserDefinedConditionalLogicalOperator Update(BinaryOperatorKind operatorKind, BoundExpression left, BoundExpression right, MethodSymbol logicalOperator, MethodSymbol trueOperator, MethodSymbol falseOperator, LookupResultKind resultKind, TypeSymbol type) + public BoundUserDefinedConditionalLogicalOperator Update(BinaryOperatorKind operatorKind, MethodSymbol logicalOperator, MethodSymbol trueOperator, MethodSymbol falseOperator, LookupResultKind resultKind, BoundExpression left, BoundExpression right, TypeSymbol type) { - if (operatorKind != this.OperatorKind || left != this.Left || right != this.Right || logicalOperator != this.LogicalOperator || trueOperator != this.TrueOperator || falseOperator != this.FalseOperator || resultKind != this.ResultKind || type != this.Type) + if (operatorKind != this.OperatorKind || logicalOperator != this.LogicalOperator || trueOperator != this.TrueOperator || falseOperator != this.FalseOperator || resultKind != this.ResultKind || left != this.Left || right != this.Right || type != this.Type) { - var result = new BoundUserDefinedConditionalLogicalOperator(this.Syntax, operatorKind, left, right, logicalOperator, trueOperator, falseOperator, resultKind, type, this.HasErrors); + var result = new BoundUserDefinedConditionalLogicalOperator(this.Syntax, operatorKind, logicalOperator, trueOperator, falseOperator, resultKind, left, right, type, this.HasErrors); result.WasCompilerGenerated = this.WasCompilerGenerated; return result; } @@ -3301,10 +3309,10 @@ protected BoundLoopStatement(BoundKind kind, SyntaxNode syntax, GeneratedLabelSy public GeneratedLabelSymbol ContinueLabel { get; } } - internal sealed partial class BoundDoStatement : BoundLoopStatement + internal abstract partial class BoundConditionalLoopStatement : BoundLoopStatement { - public BoundDoStatement(SyntaxNode syntax, ImmutableArray locals, BoundExpression condition, BoundStatement body, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors = false) - : base(BoundKind.DoStatement, syntax, breakLabel, continueLabel, hasErrors || condition.HasErrors() || body.HasErrors()) + protected BoundConditionalLoopStatement(BoundKind kind, SyntaxNode syntax, ImmutableArray locals, BoundExpression condition, BoundStatement body, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors = false) + : base(kind, syntax, breakLabel, continueLabel, hasErrors) { Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); @@ -3324,6 +3332,22 @@ public BoundDoStatement(SyntaxNode syntax, ImmutableArray locals, B public BoundExpression Condition { get; } public BoundStatement Body { get; } + } + + internal sealed partial class BoundDoStatement : BoundConditionalLoopStatement + { + public BoundDoStatement(SyntaxNode syntax, ImmutableArray locals, BoundExpression condition, BoundStatement body, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors = false) + : base(BoundKind.DoStatement, syntax, locals, condition, body, breakLabel, continueLabel, hasErrors || condition.HasErrors() || body.HasErrors()) + { + + Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(condition != null, "Field 'condition' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(body != null, "Field 'body' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(breakLabel != null, "Field 'breakLabel' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(continueLabel != null, "Field 'continueLabel' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + + } + public override BoundNode Accept(BoundTreeVisitor visitor) { @@ -3342,10 +3366,10 @@ public BoundDoStatement Update(ImmutableArray locals, BoundExpressi } } - internal sealed partial class BoundWhileStatement : BoundLoopStatement + internal sealed partial class BoundWhileStatement : BoundConditionalLoopStatement { public BoundWhileStatement(SyntaxNode syntax, ImmutableArray locals, BoundExpression condition, BoundStatement body, GeneratedLabelSymbol breakLabel, GeneratedLabelSymbol continueLabel, bool hasErrors = false) - : base(BoundKind.WhileStatement, syntax, breakLabel, continueLabel, hasErrors || condition.HasErrors() || body.HasErrors()) + : base(BoundKind.WhileStatement, syntax, locals, condition, body, breakLabel, continueLabel, hasErrors || condition.HasErrors() || body.HasErrors()) { Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); @@ -3354,18 +3378,9 @@ public BoundWhileStatement(SyntaxNode syntax, ImmutableArray locals Debug.Assert(breakLabel != null, "Field 'breakLabel' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(continueLabel != null, "Field 'continueLabel' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - this.Locals = locals; - this.Condition = condition; - this.Body = body; } - public ImmutableArray Locals { get; } - - public BoundExpression Condition { get; } - - public BoundStatement Body { get; } - public override BoundNode Accept(BoundTreeVisitor visitor) { return visitor.VisitWhileStatement(this); @@ -4383,28 +4398,41 @@ public BoundDynamicMemberAccess Update(BoundExpression receiver, ImmutableArray< } } - internal sealed partial class BoundDynamicInvocation : BoundExpression + internal abstract partial class BoundDynamicInvocableBase : BoundExpression { - public BoundDynamicInvocation(SyntaxNode syntax, BoundExpression expression, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray applicableMethods, TypeSymbol type, bool hasErrors = false) - : base(BoundKind.DynamicInvocation, syntax, type, hasErrors || expression.HasErrors() || arguments.HasErrors()) + protected BoundDynamicInvocableBase(BoundKind kind, SyntaxNode syntax, BoundExpression expression, ImmutableArray arguments, TypeSymbol type, bool hasErrors = false) + : base(kind, syntax, type, hasErrors) { Debug.Assert(expression != null, "Field 'expression' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(!arguments.IsDefault, "Field 'arguments' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - Debug.Assert(!applicableMethods.IsDefault, "Field 'applicableMethods' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - Debug.Assert(type != null, "Field 'type' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); this.Expression = expression; this.Arguments = arguments; - this.ArgumentNamesOpt = argumentNamesOpt; - this.ArgumentRefKindsOpt = argumentRefKindsOpt; - this.ApplicableMethods = applicableMethods; } public BoundExpression Expression { get; } public ImmutableArray Arguments { get; } + } + + internal sealed partial class BoundDynamicInvocation : BoundDynamicInvocableBase + { + public BoundDynamicInvocation(SyntaxNode syntax, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray applicableMethods, BoundExpression expression, ImmutableArray arguments, TypeSymbol type, bool hasErrors = false) + : base(BoundKind.DynamicInvocation, syntax, expression, arguments, type, hasErrors || expression.HasErrors() || arguments.HasErrors()) + { + + Debug.Assert(!applicableMethods.IsDefault, "Field 'applicableMethods' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(expression != null, "Field 'expression' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(!arguments.IsDefault, "Field 'arguments' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(type != null, "Field 'type' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + + this.ArgumentNamesOpt = argumentNamesOpt; + this.ArgumentRefKindsOpt = argumentRefKindsOpt; + this.ApplicableMethods = applicableMethods; + } + public ImmutableArray ArgumentNamesOpt { get; } @@ -4417,11 +4445,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor) return visitor.VisitDynamicInvocation(this); } - public BoundDynamicInvocation Update(BoundExpression expression, ImmutableArray arguments, ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray applicableMethods, TypeSymbol type) + public BoundDynamicInvocation Update(ImmutableArray argumentNamesOpt, ImmutableArray argumentRefKindsOpt, ImmutableArray applicableMethods, BoundExpression expression, ImmutableArray arguments, TypeSymbol type) { - if (expression != this.Expression || arguments != this.Arguments || argumentNamesOpt != this.ArgumentNamesOpt || argumentRefKindsOpt != this.ArgumentRefKindsOpt || applicableMethods != this.ApplicableMethods || type != this.Type) + if (argumentNamesOpt != this.ArgumentNamesOpt || argumentRefKindsOpt != this.ArgumentRefKindsOpt || applicableMethods != this.ApplicableMethods || expression != this.Expression || arguments != this.Arguments || type != this.Type) { - var result = new BoundDynamicInvocation(this.Syntax, expression, arguments, argumentNamesOpt, argumentRefKindsOpt, applicableMethods, type, this.HasErrors); + var result = new BoundDynamicInvocation(this.Syntax, argumentNamesOpt, argumentRefKindsOpt, applicableMethods, expression, arguments, type, this.HasErrors); result.WasCompilerGenerated = this.WasCompilerGenerated; return result; } @@ -5279,27 +5307,21 @@ public BoundCollectionElementInitializer Update(MethodSymbol addMethod, Immutabl } } - internal sealed partial class BoundDynamicCollectionElementInitializer : BoundExpression + internal sealed partial class BoundDynamicCollectionElementInitializer : BoundDynamicInvocableBase { - public BoundDynamicCollectionElementInitializer(SyntaxNode syntax, ImmutableArray arguments, BoundImplicitReceiver implicitReceiver, ImmutableArray applicableMethods, TypeSymbol type, bool hasErrors = false) - : base(BoundKind.DynamicCollectionElementInitializer, syntax, type, hasErrors || arguments.HasErrors() || implicitReceiver.HasErrors()) + public BoundDynamicCollectionElementInitializer(SyntaxNode syntax, ImmutableArray applicableMethods, BoundExpression expression, ImmutableArray arguments, TypeSymbol type, bool hasErrors = false) + : base(BoundKind.DynamicCollectionElementInitializer, syntax, expression, arguments, type, hasErrors || expression.HasErrors() || arguments.HasErrors()) { - Debug.Assert(!arguments.IsDefault, "Field 'arguments' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - Debug.Assert(implicitReceiver != null, "Field 'implicitReceiver' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(!applicableMethods.IsDefault, "Field 'applicableMethods' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(expression != null, "Field 'expression' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); + Debug.Assert(!arguments.IsDefault, "Field 'arguments' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); Debug.Assert(type != null, "Field 'type' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - this.Arguments = arguments; - this.ImplicitReceiver = implicitReceiver; this.ApplicableMethods = applicableMethods; } - public ImmutableArray Arguments { get; } - - public BoundImplicitReceiver ImplicitReceiver { get; } - public ImmutableArray ApplicableMethods { get; } public override BoundNode Accept(BoundTreeVisitor visitor) @@ -5307,11 +5329,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor) return visitor.VisitDynamicCollectionElementInitializer(this); } - public BoundDynamicCollectionElementInitializer Update(ImmutableArray arguments, BoundImplicitReceiver implicitReceiver, ImmutableArray applicableMethods, TypeSymbol type) + public BoundDynamicCollectionElementInitializer Update(ImmutableArray applicableMethods, BoundExpression expression, ImmutableArray arguments, TypeSymbol type) { - if (arguments != this.Arguments || implicitReceiver != this.ImplicitReceiver || applicableMethods != this.ApplicableMethods || type != this.Type) + if (applicableMethods != this.ApplicableMethods || expression != this.Expression || arguments != this.Arguments || type != this.Type) { - var result = new BoundDynamicCollectionElementInitializer(this.Syntax, arguments, implicitReceiver, applicableMethods, type, this.HasErrors); + var result = new BoundDynamicCollectionElementInitializer(this.Syntax, applicableMethods, expression, arguments, type, this.HasErrors); result.WasCompilerGenerated = this.WasCompilerGenerated; return result; } @@ -8869,8 +8891,8 @@ public override BoundNode VisitCollectionElementInitializer(BoundCollectionEleme } public override BoundNode VisitDynamicCollectionElementInitializer(BoundDynamicCollectionElementInitializer node) { + this.Visit(node.Expression); this.VisitList(node.Arguments); - this.Visit(node.ImplicitReceiver); return null; } public override BoundNode VisitImplicitReceiver(BoundImplicitReceiver node) @@ -9199,7 +9221,7 @@ public override BoundNode VisitBinaryOperator(BoundBinaryOperator node) BoundExpression left = (BoundExpression)this.Visit(node.Left); BoundExpression right = (BoundExpression)this.Visit(node.Right); TypeSymbol type = this.VisitType(node.Type); - return node.Update(node.OperatorKind, left, right, node.ConstantValueOpt, node.MethodOpt, node.ResultKind, type); + return node.Update(node.OperatorKind, node.ConstantValueOpt, node.MethodOpt, node.ResultKind, left, right, type); } public override BoundNode VisitTupleBinaryOperator(BoundTupleBinaryOperator node) { @@ -9215,7 +9237,7 @@ public override BoundNode VisitUserDefinedConditionalLogicalOperator(BoundUserDe BoundExpression left = (BoundExpression)this.Visit(node.Left); BoundExpression right = (BoundExpression)this.Visit(node.Right); TypeSymbol type = this.VisitType(node.Type); - return node.Update(node.OperatorKind, left, right, node.LogicalOperator, node.TrueOperator, node.FalseOperator, node.ResultKind, type); + return node.Update(node.OperatorKind, node.LogicalOperator, node.TrueOperator, node.FalseOperator, node.ResultKind, left, right, type); } public override BoundNode VisitCompoundAssignmentOperator(BoundCompoundAssignmentOperator node) { @@ -9666,7 +9688,7 @@ public override BoundNode VisitDynamicInvocation(BoundDynamicInvocation node) BoundExpression expression = (BoundExpression)this.Visit(node.Expression); ImmutableArray arguments = (ImmutableArray)this.VisitList(node.Arguments); TypeSymbol type = this.VisitType(node.Type); - return node.Update(expression, arguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.ApplicableMethods, type); + return node.Update(node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.ApplicableMethods, expression, arguments, type); } public override BoundNode VisitConditionalAccess(BoundConditionalAccess node) { @@ -9795,10 +9817,10 @@ public override BoundNode VisitCollectionElementInitializer(BoundCollectionEleme } public override BoundNode VisitDynamicCollectionElementInitializer(BoundDynamicCollectionElementInitializer node) { + BoundExpression expression = (BoundExpression)this.Visit(node.Expression); ImmutableArray arguments = (ImmutableArray)this.VisitList(node.Arguments); - BoundImplicitReceiver implicitReceiver = (BoundImplicitReceiver)this.Visit(node.ImplicitReceiver); TypeSymbol type = this.VisitType(node.Type); - return node.Update(arguments, implicitReceiver, node.ApplicableMethods, type); + return node.Update(node.ApplicableMethods, expression, arguments, type); } public override BoundNode VisitImplicitReceiver(BoundImplicitReceiver node) { @@ -10268,11 +10290,11 @@ public override TreeDumperNode VisitBinaryOperator(BoundBinaryOperator node, obj return new TreeDumperNode("binaryOperator", null, new TreeDumperNode[] { new TreeDumperNode("operatorKind", node.OperatorKind, null), - new TreeDumperNode("left", null, new TreeDumperNode[] { Visit(node.Left, null) }), - new TreeDumperNode("right", null, new TreeDumperNode[] { Visit(node.Right, null) }), new TreeDumperNode("constantValueOpt", node.ConstantValueOpt, null), new TreeDumperNode("methodOpt", node.MethodOpt, null), new TreeDumperNode("resultKind", node.ResultKind, null), + new TreeDumperNode("left", null, new TreeDumperNode[] { Visit(node.Left, null) }), + new TreeDumperNode("right", null, new TreeDumperNode[] { Visit(node.Right, null) }), new TreeDumperNode("type", node.Type, null) } ); @@ -10296,12 +10318,12 @@ public override TreeDumperNode VisitUserDefinedConditionalLogicalOperator(BoundU return new TreeDumperNode("userDefinedConditionalLogicalOperator", null, new TreeDumperNode[] { new TreeDumperNode("operatorKind", node.OperatorKind, null), - new TreeDumperNode("left", null, new TreeDumperNode[] { Visit(node.Left, null) }), - new TreeDumperNode("right", null, new TreeDumperNode[] { Visit(node.Right, null) }), new TreeDumperNode("logicalOperator", node.LogicalOperator, null), new TreeDumperNode("trueOperator", node.TrueOperator, null), new TreeDumperNode("falseOperator", node.FalseOperator, null), new TreeDumperNode("resultKind", node.ResultKind, null), + new TreeDumperNode("left", null, new TreeDumperNode[] { Visit(node.Left, null) }), + new TreeDumperNode("right", null, new TreeDumperNode[] { Visit(node.Right, null) }), new TreeDumperNode("type", node.Type, null) } ); @@ -11087,11 +11109,11 @@ public override TreeDumperNode VisitDynamicInvocation(BoundDynamicInvocation nod { return new TreeDumperNode("dynamicInvocation", null, new TreeDumperNode[] { - new TreeDumperNode("expression", null, new TreeDumperNode[] { Visit(node.Expression, null) }), - new TreeDumperNode("arguments", null, from x in node.Arguments select Visit(x, null)), new TreeDumperNode("argumentNamesOpt", node.ArgumentNamesOpt, null), new TreeDumperNode("argumentRefKindsOpt", node.ArgumentRefKindsOpt, null), new TreeDumperNode("applicableMethods", node.ApplicableMethods, null), + new TreeDumperNode("expression", null, new TreeDumperNode[] { Visit(node.Expression, null) }), + new TreeDumperNode("arguments", null, from x in node.Arguments select Visit(x, null)), new TreeDumperNode("type", node.Type, null) } ); @@ -11338,9 +11360,9 @@ public override TreeDumperNode VisitDynamicCollectionElementInitializer(BoundDyn { return new TreeDumperNode("dynamicCollectionElementInitializer", null, new TreeDumperNode[] { - new TreeDumperNode("arguments", null, from x in node.Arguments select Visit(x, null)), - new TreeDumperNode("implicitReceiver", null, new TreeDumperNode[] { Visit(node.ImplicitReceiver, null) }), new TreeDumperNode("applicableMethods", node.ApplicableMethods, null), + new TreeDumperNode("expression", null, new TreeDumperNode[] { Visit(node.Expression, null) }), + new TreeDumperNode("arguments", null, from x in node.Arguments select Visit(x, null)), new TreeDumperNode("type", node.Type, null) } ); diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs index a5c7ec109a01089599b219ffa57fafffcda0598e..c627f21506adf4ab61e0187bb5adfc9ed1daa8d8 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs @@ -809,7 +809,7 @@ public override BoundNode VisitBinaryOperator(BoundBinaryOperator node) } } - return UpdateExpression(builder, node.Update(node.OperatorKind, left, right, node.ConstantValue, node.MethodOpt, node.ResultKind, node.Type)); + return UpdateExpression(builder, node.Update(node.OperatorKind, node.ConstantValue, node.MethodOpt, node.ResultKind, left, right, node.Type)); } public override BoundNode VisitCall(BoundCall node) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs index 3eef39ec473d905d4d55888e8f7dcde5ce0296b7..3573f38e9cc04d324d68893214b0c3ee3d56e043 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs @@ -79,7 +79,7 @@ public override BoundNode VisitUserDefinedConditionalLogicalOperator(BoundUserDe if (_inExpressionLambda) { - return node.Update(operatorKind, loweredLeft, loweredRight, node.LogicalOperator, node.TrueOperator, node.FalseOperator, node.ResultKind, type); + return node.Update(operatorKind, node.LogicalOperator, node.TrueOperator, node.FalseOperator, node.ResultKind, loweredLeft, loweredRight, type); } BoundAssignmentOperator tempAssignment; @@ -473,8 +473,8 @@ public BoundExpression VisitBinaryOperator(BoundBinaryOperator node, BoundUnaryO } return (oldNode != null) ? - oldNode.Update(operatorKind, loweredLeft, loweredRight, oldNode.ConstantValueOpt, oldNode.MethodOpt, oldNode.ResultKind, type) : - new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, null, null, LookupResultKind.Viable, type); + oldNode.Update(operatorKind, oldNode.ConstantValueOpt, oldNode.MethodOpt, oldNode.ResultKind, loweredLeft, loweredRight, type) : + new BoundBinaryOperator(syntax, operatorKind, null, null, LookupResultKind.Viable, loweredLeft, loweredRight, type); } private BoundExpression RewriteLiftedBinaryOperator(SyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type, MethodSymbol method) @@ -1832,7 +1832,7 @@ private BoundExpression RewriteStringEquality(BoundBinaryOperator oldNode, Synta { if (oldNode != null && (loweredLeft.ConstantValue == ConstantValue.Null || loweredRight.ConstantValue == ConstantValue.Null)) { - return oldNode.Update(operatorKind, loweredLeft, loweredRight, oldNode.ConstantValueOpt, oldNode.MethodOpt, oldNode.ResultKind, type); + return oldNode.Update(operatorKind, oldNode.ConstantValueOpt, oldNode.MethodOpt, oldNode.ResultKind, loweredLeft, loweredRight, type); } var method = UnsafeGetSpecialTypeMethod(syntax, member); @@ -1853,7 +1853,7 @@ private BoundExpression RewriteDelegateOperation(SyntaxNode syntax, BinaryOperat { // use reference equality in the absence of overloaded operators for System.Delegate. operatorKind = (operatorKind & (~BinaryOperatorKind.Delegate)) | BinaryOperatorKind.Object; - return new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, default(ConstantValue), null, LookupResultKind.Empty, type); + return new BoundBinaryOperator(syntax, operatorKind, default(ConstantValue), null, LookupResultKind.Empty, loweredLeft, loweredRight, type); } } else @@ -1863,7 +1863,7 @@ private BoundExpression RewriteDelegateOperation(SyntaxNode syntax, BinaryOperat Debug.Assert((object)method != null); BoundExpression call = _inExpressionLambda - ? new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, null, method, default(LookupResultKind), method.ReturnType.TypeSymbol) + ? new BoundBinaryOperator(syntax, operatorKind, null, method, default(LookupResultKind), loweredLeft, loweredRight, method.ReturnType.TypeSymbol) : (BoundExpression)BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight); BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ? MakeConversionNode(syntax, call, Conversion.ExplicitReference, type, @checked: false) : @@ -1988,11 +1988,11 @@ private BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewritt loweredRight = new BoundBinaryOperator( rightSyntax, andOperatorKind, - loweredRight, - MakeLiteral(rightSyntax, ConstantValue.Create(rightMask), rightType), null, null, LookupResultKind.Viable, + loweredRight, + MakeLiteral(rightSyntax, ConstantValue.Create(rightMask), rightType), rightType); } @@ -2000,19 +2000,19 @@ private BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewritt ? new BoundBinaryOperator( syntax, operatorKind, - loweredLeft, - loweredRight, null, null, LookupResultKind.Viable, + loweredLeft, + loweredRight, type) : oldNode.Update( operatorKind, - loweredLeft, - loweredRight, null, null, oldNode.ResultKind, + loweredLeft, + loweredRight, type); } @@ -2047,11 +2047,11 @@ private BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewritt return new BoundBinaryOperator( syntax, kind, - loweredLeft, - loweredRight, ConstantValue.NotAvailable, null, LookupResultKind.Viable, + loweredLeft, + loweredRight, returnType); } diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index 2ca681c7ec5a3eea043d5b7ea62aae64a7b769f9..77d946e2b8744ad5c5c11d2bfcb4b801a57276cb 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -213,11 +213,11 @@ public override BoundNode VisitCall(BoundCall node) rewrittenBoundCall = new BoundBinaryOperator( syntax, BinaryOperatorKind.ObjectEqual, - rewrittenArguments[0], - rewrittenArguments[1], null, null, resultKind, + rewrittenArguments[0], + rewrittenArguments[1], type); } else if (node == null) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs index 24f6f15c2b48b94c4fa6b8158ff420e22578598b..e50924118fdbbdd619dd36c9e246db4cda6e104e 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs @@ -349,7 +349,7 @@ private BoundExpression RewriteStringConcatInExpressionLambda(SyntaxNode syntax, var method = UnsafeGetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); - return new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, default(ConstantValue), method, default(LookupResultKind), type); + return new BoundBinaryOperator(syntax, operatorKind, default(ConstantValue), method, default(LookupResultKind), loweredLeft, loweredRight, type); } /// diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs index 80ec461ae385054b7c93dad427712f446c0bcfa9..ef24d4af30d9096500f551debcd2a73faa2b7304 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs @@ -497,7 +497,7 @@ public ParameterSymbol SynthesizedParameter(TypeSymbol type, string name, Method public BoundBinaryOperator Binary(BinaryOperatorKind kind, TypeSymbol type, BoundExpression left, BoundExpression right) { - return new BoundBinaryOperator(this.Syntax, kind, left, right, ConstantValue.NotAvailable, null, LookupResultKind.Viable, type) { WasCompilerGenerated = true }; + return new BoundBinaryOperator(this.Syntax, kind, ConstantValue.NotAvailable, null, LookupResultKind.Viable, left, right, type) { WasCompilerGenerated = true }; } public BoundAsOperator As(BoundExpression operand, TypeSymbol type) diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index 9e7895e607fae988ced77f4002f7c91076136a13..f329ea46cb0cb11172ea6c3aef73f7496d438cec 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -60,7 +60,7 @@ public IOperation Create(BoundNode boundNode) return builder.ToImmutableAndFree(); } - private IOperation CreateInternal(BoundNode boundNode) + internal IOperation CreateInternal(BoundNode boundNode) { switch (boundNode.Kind) { @@ -324,12 +324,12 @@ private IOperation CreateInternal(BoundNode boundNode) private IMethodBodyOperation CreateMethodBodyOperation(BoundNonConstructorMethodBody boundNode) { - return new CSharpLazyMethodBodyOperation(this, boundNode.BlockBody, boundNode.ExpressionBody, _semanticModel, boundNode.Syntax); + return new CSharpLazyMethodBodyOperation(this, boundNode, _semanticModel, boundNode.Syntax); } private IConstructorBodyOperation CreateConstructorBodyOperation(BoundConstructorMethodBody boundNode) { - return new CSharpLazyConstructorBodyOperation(this, boundNode.Initializer, boundNode.BlockBody, boundNode.ExpressionBody, boundNode.Locals.As(), _semanticModel, boundNode.Syntax); + return new CSharpLazyConstructorBodyOperation(this, boundNode, boundNode.Locals.As(), _semanticModel, boundNode.Syntax); } private ImmutableArray GetIOperationChildren(BoundNode boundNode) @@ -390,14 +390,11 @@ private IPlaceholderOperation CreateBoundDeconstructValuePlaceholderOperation(Bo private IDeconstructionAssignmentOperation CreateBoundDeconstructionAssignmentOperator(BoundDeconstructionAssignmentOperator boundDeconstructionAssignmentOperator) { - BoundNode target = boundDeconstructionAssignmentOperator.Left; - // Skip the synthetic deconstruction conversion wrapping the right operand. - BoundNode value = boundDeconstructionAssignmentOperator.Right.Operand; SyntaxNode syntax = boundDeconstructionAssignmentOperator.Syntax; ITypeSymbol type = boundDeconstructionAssignmentOperator.Type; Optional constantValue = ConvertToOptional(boundDeconstructionAssignmentOperator.ConstantValue); bool isImplicit = boundDeconstructionAssignmentOperator.WasCompilerGenerated; - return new CSharpLazyDeconstructionAssignmentOperation(this, target, value, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyDeconstructionAssignmentOperation(this, boundDeconstructionAssignmentOperator, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundCallOperation(BoundCall boundCall) @@ -414,7 +411,7 @@ private IOperation CreateBoundCallOperation(BoundCall boundCall) } bool isVirtual = IsCallVirtual(targetMethod, boundCall.ReceiverOpt); - return new CSharpLazyInvocationOperation(this, boundCall.ReceiverOpt, boundCall, targetMethod, isVirtual, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyInvocationOperation(this, boundCall, targetMethod, isVirtual, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundLocalOperation(BoundLocal boundLocal) @@ -573,7 +570,7 @@ private IAnonymousObjectCreationOperation CreateBoundAnonymousObjectCreationExpr ITypeSymbol type = boundAnonymousObjectCreationExpression.Type; Optional constantValue = ConvertToOptional(boundAnonymousObjectCreationExpression.ConstantValue); bool isImplicit = boundAnonymousObjectCreationExpression.WasCompilerGenerated; - return new CSharpLazyAnonymousObjectCreationOperation(this, boundAnonymousObjectCreationExpression.Arguments, boundAnonymousObjectCreationExpression.Declarations, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyAnonymousObjectCreationOperation(this, boundAnonymousObjectCreationExpression, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundObjectCreationExpressionOperation(BoundObjectCreationExpression boundObjectCreationExpression) @@ -592,9 +589,7 @@ private IOperation CreateBoundObjectCreationExpressionOperation(BoundObjectCreat { // Workaround for https://github.com/dotnet/roslyn/issues/28157 Debug.Assert(isImplicit); - ImmutableArray memberInitializers = boundObjectCreationExpression.Arguments; - ImmutableArray declarations = ImmutableArray.Empty; - return new CSharpLazyAnonymousObjectCreationOperation(this, memberInitializers, declarations, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyAnonymousObjectCreationOperation(this, boundObjectCreationExpression, _semanticModel, syntax, type, constantValue, isImplicit); } return new CSharpLazyObjectCreationOperation(this, boundObjectCreationExpression, constructor, _semanticModel, syntax, type, constantValue, isImplicit); @@ -602,15 +597,13 @@ private IOperation CreateBoundObjectCreationExpressionOperation(BoundObjectCreat private IDynamicObjectCreationOperation CreateBoundDynamicObjectCreationExpressionOperation(BoundDynamicObjectCreationExpression boundDynamicObjectCreationExpression) { - ImmutableArray arguments = boundDynamicObjectCreationExpression.Arguments; ImmutableArray argumentNames = boundDynamicObjectCreationExpression.ArgumentNamesOpt.NullToEmpty(); ImmutableArray argumentRefKinds = boundDynamicObjectCreationExpression.ArgumentRefKindsOpt.NullToEmpty(); - BoundNode initializer = boundDynamicObjectCreationExpression.InitializerExpressionOpt; SyntaxNode syntax = boundDynamicObjectCreationExpression.Syntax; ITypeSymbol type = boundDynamicObjectCreationExpression.Type; Optional constantValue = ConvertToOptional(boundDynamicObjectCreationExpression.ConstantValue); bool isImplicit = boundDynamicObjectCreationExpression.WasCompilerGenerated; - return new CSharpLazyDynamicObjectCreationOperation(this, arguments, initializer, argumentNames, argumentRefKinds, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyDynamicObjectCreationOperation(this, boundDynamicObjectCreationExpression, argumentNames, argumentRefKinds, _semanticModel, syntax, type, constantValue, isImplicit); } internal IOperation CreateBoundDynamicInvocationExpressionReceiver(BoundNode receiver) @@ -632,15 +625,13 @@ internal IOperation CreateBoundDynamicInvocationExpressionReceiver(BoundNode rec private IDynamicInvocationOperation CreateBoundDynamicInvocationExpressionOperation(BoundDynamicInvocation boundDynamicInvocation) { - BoundNode operation = boundDynamicInvocation.Expression; - ImmutableArray arguments = boundDynamicInvocation.Arguments; ImmutableArray argumentNames = boundDynamicInvocation.ArgumentNamesOpt.NullToEmpty(); ImmutableArray argumentRefKinds = boundDynamicInvocation.ArgumentRefKindsOpt.NullToEmpty(); SyntaxNode syntax = boundDynamicInvocation.Syntax; ITypeSymbol type = boundDynamicInvocation.Type; Optional constantValue = ConvertToOptional(boundDynamicInvocation.ConstantValue); bool isImplicit = boundDynamicInvocation.WasCompilerGenerated; - return new CSharpLazyDynamicInvocationOperation(this, operation, arguments, argumentNames, argumentRefKinds, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyDynamicInvocationOperation(this, boundDynamicInvocation, argumentNames, argumentRefKinds, _semanticModel, syntax, type, constantValue, isImplicit); } internal IOperation CreateBoundDynamicIndexerAccessExpressionReceiver(BoundExpression indexer) @@ -686,22 +677,20 @@ private IDynamicIndexerAccessOperation CreateBoundDynamicIndexerAccessExpression private IObjectOrCollectionInitializerOperation CreateBoundObjectInitializerExpressionOperation(BoundObjectInitializerExpression boundObjectInitializerExpression) { - ImmutableArray initializers = BoundObjectCreationExpression.GetChildInitializers(boundObjectInitializerExpression); SyntaxNode syntax = boundObjectInitializerExpression.Syntax; ITypeSymbol type = boundObjectInitializerExpression.Type; Optional constantValue = ConvertToOptional(boundObjectInitializerExpression.ConstantValue); bool isImplicit = boundObjectInitializerExpression.WasCompilerGenerated; - return new CSharpLazyObjectOrCollectionInitializerOperation(this, initializers, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyObjectOrCollectionInitializerOperation(this, boundObjectInitializerExpression, _semanticModel, syntax, type, constantValue, isImplicit); } private IObjectOrCollectionInitializerOperation CreateBoundCollectionInitializerExpressionOperation(BoundCollectionInitializerExpression boundCollectionInitializerExpression) { - ImmutableArray initializers = BoundObjectCreationExpression.GetChildInitializers(boundCollectionInitializerExpression); SyntaxNode syntax = boundCollectionInitializerExpression.Syntax; ITypeSymbol type = boundCollectionInitializerExpression.Type; Optional constantValue = ConvertToOptional(boundCollectionInitializerExpression.ConstantValue); bool isImplicit = boundCollectionInitializerExpression.WasCompilerGenerated; - return new CSharpLazyObjectOrCollectionInitializerOperation(this, initializers, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyObjectOrCollectionInitializerOperation(this, boundCollectionInitializerExpression, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitializerMember boundObjectInitializerMember, bool isObjectOrCollectionInitializer = false) @@ -782,10 +771,8 @@ private IOperation CreateBoundCollectionElementInitializerOperation(BoundCollect return CreateInvalidExpressionForHasArgumentsExpression(boundCollectionElementInitializer.ImplicitReceiverOpt, boundCollectionElementInitializer.Arguments, null, syntax, type, constantValue, isImplicit); } - BoundExpression instance = boundCollectionElementInitializer.ImplicitReceiverOpt; - bool isVirtual = IsCallVirtual(addMethod, boundCollectionElementInitializer.ImplicitReceiverOpt); - return new CSharpLazyInvocationOperation(this, instance, boundCollectionElementInitializer, addMethod, isVirtual, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyInvocationOperation(this, boundCollectionElementInitializer, addMethod, isVirtual, _semanticModel, syntax, type, constantValue, isImplicit); } private IDynamicMemberReferenceOperation CreateBoundDynamicMemberAccessOperation(BoundDynamicMemberAccess boundDynamicMemberAccess) @@ -821,13 +808,11 @@ private IDynamicMemberReferenceOperation CreateBoundDynamicMemberAccessOperation private IDynamicInvocationOperation CreateBoundDynamicCollectionElementInitializerOperation(BoundDynamicCollectionElementInitializer boundCollectionElementInitializer) { - ImmutableArray arguments = boundCollectionElementInitializer.Arguments; SyntaxNode syntax = boundCollectionElementInitializer.Syntax; ITypeSymbol type = boundCollectionElementInitializer.Type; Optional constantValue = ConvertToOptional(boundCollectionElementInitializer.ConstantValue); bool isImplicit = boundCollectionElementInitializer.WasCompilerGenerated; - BoundImplicitReceiver implicitReceiver = boundCollectionElementInitializer.ImplicitReceiver; - return new CSharpLazyDynamicInvocationOperation(this, implicitReceiver, arguments, argumentNames: ImmutableArray.Empty, argumentRefKinds: ImmutableArray.Empty, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyDynamicInvocationOperation(this, boundCollectionElementInitializer, argumentNames: ImmutableArray.Empty, argumentRefKinds: ImmutableArray.Empty, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateUnboundLambdaOperation(UnboundLambda unboundLambda) @@ -858,13 +843,11 @@ private IAnonymousFunctionOperation CreateBoundLambdaOperation(BoundLambda bound private ILocalFunctionOperation CreateBoundLocalFunctionStatementOperation(BoundLocalFunctionStatement boundLocalFunctionStatement) { IMethodSymbol symbol = boundLocalFunctionStatement.Symbol; - BoundNode body = boundLocalFunctionStatement.Body; - BoundNode ignoredBody = boundLocalFunctionStatement.BlockBody != null && boundLocalFunctionStatement.ExpressionBody != null ? boundLocalFunctionStatement.ExpressionBody : null; SyntaxNode syntax = boundLocalFunctionStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundLocalFunctionStatement.WasCompilerGenerated; - return new CSharpLazyLocalFunctionOperation(this, body, ignoredBody, symbol, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyLocalFunctionOperation(this, boundLocalFunctionStatement, symbol, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundConversionOperation(BoundConversion boundConversion) @@ -1025,23 +1008,20 @@ private ITypeOfOperation CreateBoundTypeOfOperatorOperation(BoundTypeOfOperator private IArrayCreationOperation CreateBoundArrayCreationOperation(BoundArrayCreation boundArrayCreation) { - ImmutableArray dimensionSizes = boundArrayCreation.Bounds; - BoundNode initializer = boundArrayCreation.InitializerOpt; SyntaxNode syntax = boundArrayCreation.Syntax; ITypeSymbol type = boundArrayCreation.Type; Optional constantValue = ConvertToOptional(boundArrayCreation.ConstantValue); bool isImplicit = boundArrayCreation.WasCompilerGenerated || (boundArrayCreation.InitializerOpt?.Syntax == syntax && !boundArrayCreation.InitializerOpt.WasCompilerGenerated); - return new CSharpLazyArrayCreationOperation(this, dimensionSizes, initializer, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyArrayCreationOperation(this, boundArrayCreation, _semanticModel, syntax, type, constantValue, isImplicit); } private IArrayInitializerOperation CreateBoundArrayInitializationOperation(BoundArrayInitialization boundArrayInitialization) { - ImmutableArray elementValues = boundArrayInitialization.Initializers; SyntaxNode syntax = boundArrayInitialization.Syntax; Optional constantValue = ConvertToOptional(boundArrayInitialization.ConstantValue); bool isImplicit = boundArrayInitialization.WasCompilerGenerated; - return new CSharpLazyArrayInitializerOperation(this, elementValues, _semanticModel, syntax, constantValue, isImplicit); + return new CSharpLazyArrayInitializerOperation(this, boundArrayInitialization, _semanticModel, syntax, constantValue, isImplicit); } private IDefaultValueOperation CreateBoundDefaultExpressionOperation(BoundDefaultExpression boundDefaultExpression) @@ -1088,34 +1068,28 @@ private ISimpleAssignmentOperation CreateBoundAssignmentOperatorOperation(BoundA { Debug.Assert(!IsMemberInitializer(boundAssignmentOperator)); - BoundNode target = boundAssignmentOperator.Left; - BoundNode value = boundAssignmentOperator.Right; bool isRef = boundAssignmentOperator.IsRef; SyntaxNode syntax = boundAssignmentOperator.Syntax; ITypeSymbol type = boundAssignmentOperator.Type; Optional constantValue = ConvertToOptional(boundAssignmentOperator.ConstantValue); bool isImplicit = boundAssignmentOperator.WasCompilerGenerated; - return new CSharpLazySimpleAssignmentOperation(this, target, value, isRef, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazySimpleAssignmentOperation(this, boundAssignmentOperator, isRef, _semanticModel, syntax, type, constantValue, isImplicit); } private IMemberInitializerOperation CreateBoundMemberInitializerOperation(BoundAssignmentOperator boundAssignmentOperator) { Debug.Assert(IsMemberInitializer(boundAssignmentOperator)); - BoundNode initializedMember = boundAssignmentOperator.Left; - BoundNode initializer = boundAssignmentOperator.Right; SyntaxNode syntax = boundAssignmentOperator.Syntax; ITypeSymbol type = boundAssignmentOperator.Type; Optional constantValue = ConvertToOptional(boundAssignmentOperator.ConstantValue); bool isImplicit = boundAssignmentOperator.WasCompilerGenerated; - return new CSharpLazyMemberInitializerOperation(this, initializedMember, initializer, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyMemberInitializerOperation(this, boundAssignmentOperator, _semanticModel, syntax, type, constantValue, isImplicit); } private ICompoundAssignmentOperation CreateBoundCompoundAssignmentOperatorOperation(BoundCompoundAssignmentOperator boundCompoundAssignmentOperator) { BinaryOperatorKind operatorKind = Helper.DeriveBinaryOperatorKind(boundCompoundAssignmentOperator.Operator.Kind); - BoundNode target = boundCompoundAssignmentOperator.Left; - BoundNode value = boundCompoundAssignmentOperator.Right; Conversion inConversion = boundCompoundAssignmentOperator.LeftConversion; Conversion outConversion = boundCompoundAssignmentOperator.FinalConversion; bool isLifted = boundCompoundAssignmentOperator.Operator.Kind.IsLifted(); @@ -1125,7 +1099,7 @@ private ICompoundAssignmentOperation CreateBoundCompoundAssignmentOperatorOperat ITypeSymbol type = boundCompoundAssignmentOperator.Type; Optional constantValue = ConvertToOptional(boundCompoundAssignmentOperator.ConstantValue); bool isImplicit = boundCompoundAssignmentOperator.WasCompilerGenerated; - return new CSharpLazyCompoundAssignmentOperation(this, target, value, inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyCompoundAssignmentOperation(this, boundCompoundAssignmentOperator, inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit); } private IIncrementOrDecrementOperation CreateBoundIncrementOperatorOperation(BoundIncrementOperator boundIncrementOperator) @@ -1193,8 +1167,6 @@ private IUnaryOperation CreateBoundUnaryOperatorOperation(BoundUnaryOperator bou private IBinaryOperation CreateBoundBinaryOperatorOperation(BoundBinaryOperator boundBinaryOperator) { BinaryOperatorKind operatorKind = Helper.DeriveBinaryOperatorKind(boundBinaryOperator.OperatorKind); - BoundNode leftOperand = boundBinaryOperator.Left; - BoundNode rightOperand = boundBinaryOperator.Right; IMethodSymbol operatorMethod = boundBinaryOperator.MethodOpt; IMethodSymbol unaryOperatorMethod = null; @@ -1214,15 +1186,13 @@ private IBinaryOperation CreateBoundBinaryOperatorOperation(BoundBinaryOperator bool isChecked = boundBinaryOperator.OperatorKind.IsChecked(); bool isCompareText = false; bool isImplicit = boundBinaryOperator.WasCompilerGenerated; - return new CSharpLazyBinaryOperation(this, leftOperand, rightOperand, operatorKind, isLifted, isChecked, isCompareText, operatorMethod, unaryOperatorMethod, + return new CSharpLazyBinaryOperation(this, boundBinaryOperator, operatorKind, isLifted, isChecked, isCompareText, operatorMethod, unaryOperatorMethod, _semanticModel, syntax, type, constantValue, isImplicit); } private IBinaryOperation CreateBoundUserDefinedConditionalLogicalOperator(BoundUserDefinedConditionalLogicalOperator boundBinaryOperator) { BinaryOperatorKind operatorKind = Helper.DeriveBinaryOperatorKind(boundBinaryOperator.OperatorKind); - BoundNode leftOperand = boundBinaryOperator.Left; - BoundNode rightOperand = boundBinaryOperator.Right; IMethodSymbol operatorMethod = boundBinaryOperator.LogicalOperator; IMethodSymbol unaryOperatorMethod = boundBinaryOperator.OperatorKind.Operator() == CSharp.BinaryOperatorKind.And ? boundBinaryOperator.FalseOperator : @@ -1234,39 +1204,32 @@ private IBinaryOperation CreateBoundUserDefinedConditionalLogicalOperator(BoundU bool isChecked = boundBinaryOperator.OperatorKind.IsChecked(); bool isCompareText = false; bool isImplicit = boundBinaryOperator.WasCompilerGenerated; - return new CSharpLazyBinaryOperation(this, leftOperand, rightOperand, operatorKind, isLifted, isChecked, isCompareText, operatorMethod, unaryOperatorMethod, + return new CSharpLazyBinaryOperation(this, boundBinaryOperator, operatorKind, isLifted, isChecked, isCompareText, operatorMethod, unaryOperatorMethod, _semanticModel, syntax, type, constantValue, isImplicit); } private ITupleBinaryOperation CreateBoundTupleBinaryOperatorOperation(BoundTupleBinaryOperator boundTupleBinaryOperator) { BinaryOperatorKind operatorKind = Helper.DeriveBinaryOperatorKind(boundTupleBinaryOperator.OperatorKind); - BoundNode leftOperand = boundTupleBinaryOperator.ConvertedLeft; - BoundNode rightOperand = boundTupleBinaryOperator.ConvertedRight; SyntaxNode syntax = boundTupleBinaryOperator.Syntax; ITypeSymbol type = boundTupleBinaryOperator.Type; Optional constantValue = ConvertToOptional(boundTupleBinaryOperator.ConstantValue); bool isImplicit = boundTupleBinaryOperator.WasCompilerGenerated; - return new CSharpLazyTupleBinaryOperation(this, leftOperand, rightOperand, operatorKind, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyTupleBinaryOperation(this, boundTupleBinaryOperator, operatorKind, _semanticModel, syntax, type, constantValue, isImplicit); } private IConditionalOperation CreateBoundConditionalOperatorOperation(BoundConditionalOperator boundConditionalOperator) { - BoundNode condition = boundConditionalOperator.Condition; - BoundNode whenTrue = boundConditionalOperator.Consequence; - BoundNode whenFalse = boundConditionalOperator.Alternative; bool isRef = boundConditionalOperator.IsRef; SyntaxNode syntax = boundConditionalOperator.Syntax; ITypeSymbol type = boundConditionalOperator.Type; Optional constantValue = ConvertToOptional(boundConditionalOperator.ConstantValue); bool isImplicit = boundConditionalOperator.WasCompilerGenerated; - return new CSharpLazyConditionalOperation(this, condition, whenTrue, whenFalse, isRef, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyConditionalOperation(this, boundConditionalOperator, isRef, _semanticModel, syntax, type, constantValue, isImplicit); } private ICoalesceOperation CreateBoundNullCoalescingOperatorOperation(BoundNullCoalescingOperator boundNullCoalescingOperator) { - BoundNode expression = boundNullCoalescingOperator.LeftOperand; - BoundNode whenNull = boundNullCoalescingOperator.RightOperand; SyntaxNode syntax = boundNullCoalescingOperator.Syntax; ITypeSymbol type = boundNullCoalescingOperator.Type; Optional constantValue = ConvertToOptional(boundNullCoalescingOperator.ConstantValue); @@ -1279,19 +1242,17 @@ private ICoalesceOperation CreateBoundNullCoalescingOperatorOperation(BoundNullC valueConversion = Conversion.Identity; } - return new CSharpLazyCoalesceOperation(this, expression, whenNull, valueConversion, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyCoalesceOperation(this, boundNullCoalescingOperator, valueConversion, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundNullCoalescingAssignmentOperatorOperation(BoundNullCoalescingAssignmentOperator boundNode) { - BoundNode target = boundNode.LeftOperand; - BoundNode value = boundNode.RightOperand; SyntaxNode syntax = boundNode.Syntax; ITypeSymbol type = boundNode.Type; Optional constantValue = ConvertToOptional(boundNode.ConstantValue); bool isImplicit = boundNode.WasCompilerGenerated; - return new CSharpLazyCoalesceAssignmentOperation(this, target, value, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyCoalesceAssignmentOperation(this, boundNode, _semanticModel, syntax, type, constantValue, isImplicit); } private IAwaitOperation CreateBoundAwaitExpressionOperation(BoundAwaitExpression boundAwaitExpression) @@ -1306,31 +1267,12 @@ private IAwaitOperation CreateBoundAwaitExpressionOperation(BoundAwaitExpression private IArrayElementReferenceOperation CreateBoundArrayAccessOperation(BoundArrayAccess boundArrayAccess) { - // The compiler will dedupe the boundArrayAccess.Expression between different array references. Some example code: - // - // class C - // { - // int[] a; - - // static void Main() - // { - // // Compiler dedupes the array access receiver for [0] and [1] - // var a = new C { a = { [0] = 1, [1] = 2 } }; - // } - // } - // - // In order to prevent parent pointer from having an issue with this, we intentionally create a new IOperation node every time - // we encounter an array access. Since we create from the top down, it should be impossible for us to see the node in - // boundArrayAccess.Expression before seeing the boundArrayAccess itself, so this should not create any other parent pointer - // issues. - BoundNode arrayReference = boundArrayAccess.Expression; - ImmutableArray indices = boundArrayAccess.Indices; SyntaxNode syntax = boundArrayAccess.Syntax; ITypeSymbol type = boundArrayAccess.Type; Optional constantValue = ConvertToOptional(boundArrayAccess.ConstantValue); bool isImplicit = boundArrayAccess.WasCompilerGenerated; - return new CSharpLazyArrayElementReferenceOperation(this, arrayReference, indices, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyArrayElementReferenceOperation(this, boundArrayAccess, _semanticModel, syntax, type, constantValue, isImplicit); } private INameOfOperation CreateBoundNameOfOperatorOperation(BoundNameOfOperator boundNameOfOperator) @@ -1375,14 +1317,12 @@ private IInstanceReferenceOperation CreateBoundImplicitReceiverOperation(BoundIm private IConditionalAccessOperation CreateBoundConditionalAccessOperation(BoundConditionalAccess boundConditionalAccess) { - BoundNode expression = boundConditionalAccess.Receiver; - BoundNode whenNotNull = boundConditionalAccess.AccessExpression; SyntaxNode syntax = boundConditionalAccess.Syntax; ITypeSymbol type = boundConditionalAccess.Type; Optional constantValue = ConvertToOptional(boundConditionalAccess.ConstantValue); bool isImplicit = boundConditionalAccess.WasCompilerGenerated; - return new CSharpLazyConditionalAccessOperation(this, expression, whenNotNull, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyConditionalAccessOperation(this, boundConditionalAccess, _semanticModel, syntax, type, constantValue, isImplicit); } private IConditionalAccessInstanceOperation CreateBoundConditionalReceiverOperation(BoundConditionalReceiver boundConditionalReceiver) @@ -1432,13 +1372,12 @@ private IParameterInitializerOperation CreateBoundParameterEqualsValueOperation( private IBlockOperation CreateBoundBlockOperation(BoundBlock boundBlock) { - ImmutableArray statements = boundBlock.Statements; ImmutableArray locals = boundBlock.Locals.As(); SyntaxNode syntax = boundBlock.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundBlock.WasCompilerGenerated; - return new CSharpLazyBlockOperation(this, statements, locals, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyBlockOperation(this, boundBlock, locals, _semanticModel, syntax, type, constantValue, isImplicit); } private IBranchOperation CreateBoundContinueStatementOperation(BoundContinueStatement boundContinueStatement) @@ -1495,22 +1434,16 @@ private IEmptyOperation CreateBoundNoOpStatementOperation(BoundNoOpStatement bou private IConditionalOperation CreateBoundIfStatementOperation(BoundIfStatement boundIfStatement) { - BoundNode condition = boundIfStatement.Condition; - BoundNode ifTrueStatement = boundIfStatement.Consequence; - BoundNode ifFalseStatement = boundIfStatement.AlternativeOpt; bool isRef = false; SyntaxNode syntax = boundIfStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundIfStatement.WasCompilerGenerated; - return new CSharpLazyConditionalOperation(this, condition, ifTrueStatement, ifFalseStatement, isRef, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyConditionalOperation(this, boundIfStatement, isRef, _semanticModel, syntax, type, constantValue, isImplicit); } private IWhileLoopOperation CreateBoundWhileStatementOperation(BoundWhileStatement boundWhileStatement) { - BoundNode condition = boundWhileStatement.Condition; - BoundNode body = boundWhileStatement.Body; - BoundNode ignoredCondition = null; ImmutableArray locals = boundWhileStatement.Locals.As(); ILabelSymbol continueLabel = boundWhileStatement.ContinueLabel; ILabelSymbol exitLabel = boundWhileStatement.BreakLabel; @@ -1520,14 +1453,11 @@ private IWhileLoopOperation CreateBoundWhileStatementOperation(BoundWhileStateme ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundWhileStatement.WasCompilerGenerated; - return new CSharpLazyWhileLoopOperation(this, condition, body, ignoredCondition, locals, continueLabel, exitLabel, conditionIsTop, conditionIsUntil, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyWhileLoopOperation(this, boundWhileStatement, locals, continueLabel, exitLabel, conditionIsTop, conditionIsUntil, _semanticModel, syntax, type, constantValue, isImplicit); } private IWhileLoopOperation CreateBoundDoStatementOperation(BoundDoStatement boundDoStatement) { - BoundNode condition = boundDoStatement.Condition; - BoundNode body = boundDoStatement.Body; - BoundNode ignoredCondition = null; ILabelSymbol continueLabel = boundDoStatement.ContinueLabel; ILabelSymbol exitLabel = boundDoStatement.BreakLabel; bool conditionIsTop = false; @@ -1537,24 +1467,20 @@ private IWhileLoopOperation CreateBoundDoStatementOperation(BoundDoStatement bou ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundDoStatement.WasCompilerGenerated; - return new CSharpLazyWhileLoopOperation(this, condition, body, ignoredCondition, locals, continueLabel, exitLabel, conditionIsTop, conditionIsUntil, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyWhileLoopOperation(this, boundDoStatement, locals, continueLabel, exitLabel, conditionIsTop, conditionIsUntil, _semanticModel, syntax, type, constantValue, isImplicit); } private IForLoopOperation CreateBoundForStatementOperation(BoundForStatement boundForStatement) { - ImmutableArray before = ToStatements(boundForStatement.Initializer); - BoundNode condition = boundForStatement.Condition; - ImmutableArray atLoopBottom = ToStatements(boundForStatement.Increment); ImmutableArray locals = boundForStatement.OuterLocals.As(); ImmutableArray conditionLocals = boundForStatement.InnerLocals.As(); - BoundNode body = boundForStatement.Body; ILabelSymbol continueLabel = boundForStatement.ContinueLabel; ILabelSymbol exitLabel = boundForStatement.BreakLabel; SyntaxNode syntax = boundForStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundForStatement.WasCompilerGenerated; - return new CSharpLazyForLoopOperation(this, before, condition, atLoopBottom, body, locals, conditionLocals, continueLabel, exitLabel, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyForLoopOperation(this, boundForStatement, locals, conditionLocals, continueLabel, exitLabel, _semanticModel, syntax, type, constantValue, isImplicit); } internal ForEachLoopOperationInfo GetForEachLoopOperatorInfo(BoundForEachStatement boundForEachStatement) @@ -1624,15 +1550,13 @@ private IForEachLoopOperation CreateBoundForEachStatementOperation(BoundForEachS private ISwitchOperation CreateBoundSwitchStatementOperation(BoundSwitchStatement boundSwitchStatement) { - BoundNode value = boundSwitchStatement.Expression; - ImmutableArray cases = boundSwitchStatement.SwitchSections.CastArray(); ImmutableArray locals = boundSwitchStatement.InnerLocals.As(); ILabelSymbol exitLabel = boundSwitchStatement.BreakLabel; SyntaxNode syntax = boundSwitchStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundSwitchStatement.WasCompilerGenerated; - return new CSharpLazySwitchOperation(this, value, cases, locals, exitLabel, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazySwitchOperation(this, boundSwitchStatement, locals, exitLabel, _semanticModel, syntax, type, constantValue, isImplicit); } private ICaseClauseOperation CreateBoundSwitchLabelOperation(BoundSwitchLabel boundSwitchLabel) @@ -1655,62 +1579,49 @@ private ICaseClauseOperation CreateBoundSwitchLabelOperation(BoundSwitchLabel bo private ISwitchCaseOperation CreateBoundSwitchSectionOperation(BoundSwitchSection boundSwitchSection) { - ImmutableArray clauses = boundSwitchSection.SwitchLabels.CastArray(); - BoundNode condition = null; - ImmutableArray body = boundSwitchSection.Statements; ImmutableArray locals = boundSwitchSection.Locals.CastArray(); - return new CSharpLazySwitchCaseOperation(this, clauses, condition, body, locals, _semanticModel, boundSwitchSection.Syntax, type: null, constantValue: default, isImplicit: boundSwitchSection.WasCompilerGenerated); + return new CSharpLazySwitchCaseOperation(this, boundSwitchSection, locals, _semanticModel, boundSwitchSection.Syntax, type: null, constantValue: default, isImplicit: boundSwitchSection.WasCompilerGenerated); } private ITryOperation CreateBoundTryStatementOperation(BoundTryStatement boundTryStatement) { - BoundNode body = boundTryStatement.TryBlock; - ImmutableArray catches = boundTryStatement.CatchBlocks; - BoundNode finallyHandler = boundTryStatement.FinallyBlockOpt; SyntaxNode syntax = boundTryStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundTryStatement.WasCompilerGenerated; - return new CSharpLazyTryOperation(this, body, catches, finallyHandler, exitLabel: null, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyTryOperation(this, boundTryStatement, exitLabel: null, _semanticModel, syntax, type, constantValue, isImplicit); } private ICatchClauseOperation CreateBoundCatchBlockOperation(BoundCatchBlock boundCatchBlock) { - BoundLocal expressionDeclarationOrExpression = (BoundLocal)boundCatchBlock.ExceptionSourceOpt; ITypeSymbol exceptionType = boundCatchBlock.ExceptionTypeOpt ?? (ITypeSymbol)_semanticModel.Compilation.ObjectType; ImmutableArray locals = boundCatchBlock.Locals.As(); - BoundNode filter = boundCatchBlock.ExceptionFilterOpt; - BoundNode handler = boundCatchBlock.Body; SyntaxNode syntax = boundCatchBlock.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundCatchBlock.WasCompilerGenerated; - return new CSharpLazyCatchClauseOperation(this, expressionDeclarationOrExpression, filter, handler, exceptionType, locals, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyCatchClauseOperation(this, boundCatchBlock, exceptionType, locals, _semanticModel, syntax, type, constantValue, isImplicit); } private IFixedOperation CreateBoundFixedStatementOperation(BoundFixedStatement boundFixedStatement) { ImmutableArray locals = boundFixedStatement.Locals.As(); - BoundNode variables = boundFixedStatement.Declarations; - BoundNode body = boundFixedStatement.Body; SyntaxNode syntax = boundFixedStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundFixedStatement.WasCompilerGenerated; - return new CSharpLazyFixedOperation(this, variables, body, locals, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyFixedOperation(this, boundFixedStatement, locals, _semanticModel, syntax, type, constantValue, isImplicit); } private IUsingOperation CreateBoundUsingStatementOperation(BoundUsingStatement boundUsingStatement) { - BoundNode resources = (BoundNode)boundUsingStatement.DeclarationsOpt ?? boundUsingStatement.ExpressionOpt; - BoundNode body = boundUsingStatement.Body; ImmutableArray locals = ImmutableArray.CastUp(boundUsingStatement.Locals); SyntaxNode syntax = boundUsingStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundUsingStatement.WasCompilerGenerated; - return new CSharpLazyUsingOperation(this, resources, body, locals, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyUsingOperation(this, boundUsingStatement, locals, _semanticModel, syntax, type, constantValue, isImplicit); } private IThrowOperation CreateBoundThrowStatementOperation(BoundThrowStatement boundThrowStatement) @@ -1745,8 +1656,6 @@ private IReturnOperation CreateBoundYieldReturnStatementOperation(BoundYieldRetu private ILockOperation CreateBoundLockStatementOperation(BoundLockStatement boundLockStatement) { - BoundNode expression = boundLockStatement.Argument; - BoundNode body = boundLockStatement.Body; // If there is no Enter2 method, then there will be no lock taken reference bool legacyMode = _semanticModel.Compilation.CommonGetWellKnownTypeMember(WellKnownMember.System_Threading_Monitor__Enter2) == null; ILocalSymbol lockTakenSymbol = @@ -1759,7 +1668,7 @@ private ILockOperation CreateBoundLockStatementOperation(BoundLockStatement boun Optional constantValue = default(Optional); bool isImplicit = boundLockStatement.WasCompilerGenerated; - return new CSharpLazyLockOperation(this, expression, body, lockTakenSymbol, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyLockOperation(this, boundLockStatement, lockTakenSymbol, _semanticModel, syntax, type, constantValue, isImplicit); } private IInvalidOperation CreateBoundBadStatementOperation(BoundBadStatement boundBadStatement) @@ -1815,8 +1724,7 @@ private IOperation CreateBoundLocalDeclarationOperation(BoundLocalDeclaration bo } bool multiVariableImplicit = boundLocalDeclaration.WasCompilerGenerated; - BoundNode initializer = null; - IVariableDeclarationOperation multiVariableDeclaration = new CSharpLazyVariableDeclarationOperation(this, boundLocalDeclaration, initializer, _semanticModel, varDeclaration, null, default, multiVariableImplicit); + IVariableDeclarationOperation multiVariableDeclaration = new CSharpLazyVariableDeclarationOperation(this, boundLocalDeclaration, _semanticModel, varDeclaration, null, default, multiVariableImplicit); ITypeSymbol type = null; Optional constantValue = default(Optional); // In the case of a for loop, varStatement and varDeclaration will be the same syntax node. @@ -1827,8 +1735,6 @@ private IOperation CreateBoundLocalDeclarationOperation(BoundLocalDeclaration bo private IVariableDeclarationGroupOperation CreateBoundMultipleLocalDeclarationsOperation(BoundMultipleLocalDeclarations boundMultipleLocalDeclarations) { - BoundNode initializer = null; - // The syntax for the boundMultipleLocalDeclarations can either be a LocalDeclarationStatement or a VariableDeclaration, depending on the context // (using/fixed statements vs variable declaration) // We generate a DeclarationGroup for these scenarios (using/fixed) to maintain tree shape consistency across IOperation. @@ -1837,7 +1743,7 @@ private IVariableDeclarationGroupOperation CreateBoundMultipleLocalDeclarationsO ((LocalDeclarationStatementSyntax)declarationGroupSyntax).Declaration : declarationGroupSyntax; bool declarationIsImplicit = boundMultipleLocalDeclarations.WasCompilerGenerated; - IVariableDeclarationOperation multiVariableDeclaration = new CSharpLazyVariableDeclarationOperation(this, boundMultipleLocalDeclarations, initializer, _semanticModel, declarationSyntax, null, default, declarationIsImplicit); + IVariableDeclarationOperation multiVariableDeclaration = new CSharpLazyVariableDeclarationOperation(this, boundMultipleLocalDeclarations, _semanticModel, declarationSyntax, null, default, declarationIsImplicit); ITypeSymbol type = null; Optional constantValue = default(Optional); @@ -1895,7 +1801,6 @@ private IOperation CreateBoundConvertedTupleLiteralOperation(BoundConvertedTuple private IOperation CreateTupleOperation(BoundTupleExpression boundTupleExpression, ITypeSymbol naturalType) { - ImmutableArray elements = boundTupleExpression.Arguments; SyntaxNode syntax = boundTupleExpression.Syntax; bool isImplicit = boundTupleExpression.WasCompilerGenerated; ITypeSymbol type = boundTupleExpression.Type; @@ -1903,21 +1808,20 @@ private IOperation CreateTupleOperation(BoundTupleExpression boundTupleExpressio if (syntax is DeclarationExpressionSyntax declarationExpressionSyntax) { var tupleSyntax = declarationExpressionSyntax.Designation; - var tuple = new CSharpLazyTupleOperation(this, elements, _semanticModel, tupleSyntax, type, naturalType, constantValue, isImplicit); + var tuple = new CSharpLazyTupleOperation(this, boundTupleExpression, _semanticModel, tupleSyntax, type, naturalType, constantValue, isImplicit); return new DeclarationExpressionOperation(tuple, _semanticModel, declarationExpressionSyntax, type, constantValue: default, isImplicit: false); } - return new CSharpLazyTupleOperation(this, elements, _semanticModel, syntax, type, naturalType, constantValue, isImplicit); + return new CSharpLazyTupleOperation(this, boundTupleExpression, _semanticModel, syntax, type, naturalType, constantValue, isImplicit); } private IInterpolatedStringOperation CreateBoundInterpolatedStringExpressionOperation(BoundInterpolatedString boundInterpolatedString) { - ImmutableArray parts = boundInterpolatedString.Parts; SyntaxNode syntax = boundInterpolatedString.Syntax; ITypeSymbol type = boundInterpolatedString.Type; Optional constantValue = ConvertToOptional(boundInterpolatedString.ConstantValue); bool isImplicit = boundInterpolatedString.WasCompilerGenerated; - return new CSharpLazyInterpolatedStringOperation(this, parts, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyInterpolatedStringOperation(this, boundInterpolatedString, _semanticModel, syntax, type, constantValue, isImplicit); } internal ImmutableArray CreateBoundInterpolatedStringContentOperation(ImmutableArray parts) @@ -1939,14 +1843,11 @@ internal ImmutableArray CreateBoundInterpol private IInterpolationOperation CreateBoundInterpolationOperation(BoundStringInsert boundStringInsert) { - BoundNode expression = boundStringInsert.Value; - BoundNode alignment = boundStringInsert.Alignment; - BoundNode format = boundStringInsert.Format; SyntaxNode syntax = boundStringInsert.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundStringInsert.WasCompilerGenerated; - return new CSharpLazyInterpolationOperation(this, expression, alignment, format, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyInterpolationOperation(this, boundStringInsert, _semanticModel, syntax, type, constantValue, isImplicit); } private IInterpolatedStringTextOperation CreateBoundInterpolatedStringTextOperation(BoundLiteral boundNode) @@ -1985,25 +1886,20 @@ private IDeclarationPatternOperation CreateBoundDeclarationPatternOperation(Boun private ISwitchOperation CreateBoundPatternSwitchStatementOperation(BoundPatternSwitchStatement boundPatternSwitchStatement) { - BoundNode value = boundPatternSwitchStatement.Expression; - ImmutableArray cases = boundPatternSwitchStatement.SwitchSections.CastArray(); ImmutableArray locals = boundPatternSwitchStatement.InnerLocals.As(); ILabelSymbol exitLabel = boundPatternSwitchStatement.BreakLabel; SyntaxNode syntax = boundPatternSwitchStatement.Syntax; ITypeSymbol type = null; Optional constantValue = default(Optional); bool isImplicit = boundPatternSwitchStatement.WasCompilerGenerated; - return new CSharpLazySwitchOperation(this, value, cases, locals, exitLabel, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazySwitchOperation(this, boundPatternSwitchStatement, locals, exitLabel, _semanticModel, syntax, type, constantValue, isImplicit); } private ISwitchCaseOperation CreateBoundPatternSwitchSectionOperation(BoundPatternSwitchSection boundPatternSwitchSection) { - ImmutableArray clauses = boundPatternSwitchSection.SwitchLabels.CastArray(); - BoundNode condition = null; - ImmutableArray body = boundPatternSwitchSection.Statements; ImmutableArray locals = boundPatternSwitchSection.Locals.CastArray(); - return new CSharpLazySwitchCaseOperation(this, clauses, condition, body, locals, _semanticModel, boundPatternSwitchSection.Syntax, type: null, constantValue: default, isImplicit: boundPatternSwitchSection.WasCompilerGenerated); + return new CSharpLazySwitchCaseOperation(this, boundPatternSwitchSection, locals, _semanticModel, boundPatternSwitchSection.Syntax, type: null, constantValue: default, isImplicit: boundPatternSwitchSection.WasCompilerGenerated); } private ICaseClauseOperation CreateBoundPatternSwitchLabelOperation(BoundPatternSwitchLabel boundPatternSwitchLabel) @@ -2021,21 +1917,17 @@ private ICaseClauseOperation CreateBoundPatternSwitchLabelOperation(BoundPattern } else { - BoundNode pattern = boundPatternSwitchLabel.Pattern; - BoundNode guardExpression = boundPatternSwitchLabel.Guard; - return new CSharpLazyPatternCaseClauseOperation(this, pattern, guardExpression, label, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyPatternCaseClauseOperation(this, boundPatternSwitchLabel, label, _semanticModel, syntax, type, constantValue, isImplicit); } } private IIsPatternOperation CreateBoundIsPatternExpressionOperation(BoundIsPatternExpression boundIsPatternExpression) { - BoundNode expression = boundIsPatternExpression.Expression; - BoundNode pattern = boundIsPatternExpression.Pattern; SyntaxNode syntax = boundIsPatternExpression.Syntax; ITypeSymbol type = boundIsPatternExpression.Type; Optional constantValue = ConvertToOptional(boundIsPatternExpression.ConstantValue); bool isImplicit = boundIsPatternExpression.WasCompilerGenerated; - return new CSharpLazyIsPatternOperation(this, expression, pattern, _semanticModel, syntax, type, constantValue, isImplicit); + return new CSharpLazyIsPatternOperation(this, boundIsPatternExpression, _semanticModel, syntax, type, constantValue, isImplicit); } private IOperation CreateBoundQueryClauseOperation(BoundQueryClause boundQueryClause) @@ -2087,8 +1979,7 @@ private IOperation CreateRangeExpressionOperation(BoundRangeExpression boundRang { return new CSharpLazyRangeOperation( operationFactory: this, - leftOperand: boundRange.LeftOperand, - rightOperand: boundRange.RightOperand, + boundRange, isLifted: boundRange.Type.IsNullableType(), isImplicit: boundRange.WasCompilerGenerated, _semanticModel, diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs index a4a62e8238c8a4788c597b7384d3d636068ea719..61a621547b61be4bbf7631f781b1cfa97150e906 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs @@ -19,7 +19,7 @@ private static Optional ConvertToOptional(ConstantValue value) return value != null && !value.IsBad ? new Optional(value.Value) : default(Optional); } - private ImmutableArray ToStatements(BoundStatement statement) + internal ImmutableArray ToStatements(BoundStatement statement) { if (statement == null) { @@ -350,13 +350,14 @@ private IInvalidOperation CreateInvalidExpressionForHasArgumentsExpression(Bound } internal ImmutableArray GetAnonymousObjectCreationInitializers( - ImmutableArray arguments, - ImmutableArray declarations, + IBoundAnonymousObjectCreation anonymousObjectCreation, SyntaxNode syntax, ITypeSymbol type, bool isImplicit) { // For error cases and non-assignment initializers, the binder generates only the argument. + ImmutableArray arguments = anonymousObjectCreation.Arguments; + ImmutableArray declarations = anonymousObjectCreation.PropertyDeclarationsOpt; Debug.Assert(arguments.Length >= declarations.Length); var builder = ArrayBuilder.GetInstance(arguments.Length); diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs index e8f252c391f26285aed168532895081e583b2eb1..2efe7d14e72d571868d3dfb79ebade44ae892b70 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs @@ -80,118 +80,128 @@ protected override IOperation CreateValue() internal sealed class CSharpLazyArrayCreationOperation : LazyArrayCreationOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _dimensionSizes; - private readonly BoundNode _initializer; + private readonly BoundArrayCreation _arrayCreation; - internal CSharpLazyArrayCreationOperation(CSharpOperationFactory operationFactory, ImmutableArray dimensionSizes, BoundNode initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyArrayCreationOperation(CSharpOperationFactory operationFactory, BoundArrayCreation arrayCreation, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _dimensionSizes = dimensionSizes; - _initializer = initializer; + _arrayCreation = arrayCreation; } protected override ImmutableArray CreateDimensionSizes() { - return _operationFactory.CreateFromArray(_dimensionSizes); + return _operationFactory.CreateFromArray(_arrayCreation.Bounds); } protected override IArrayInitializerOperation CreateInitializer() { - return (IArrayInitializerOperation)_operationFactory.Create(_initializer); + return (IArrayInitializerOperation)_operationFactory.Create(_arrayCreation.InitializerOpt); } } internal sealed class CSharpLazyArrayElementReferenceOperation : LazyArrayElementReferenceOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _arrayReference; - private readonly ImmutableArray _indices; + private readonly BoundArrayAccess _arrayAccess; - internal CSharpLazyArrayElementReferenceOperation(CSharpOperationFactory operationFactory, BoundNode arrayReference, ImmutableArray indices, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyArrayElementReferenceOperation(CSharpOperationFactory operationFactory, BoundArrayAccess arrayAccess, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _arrayReference = arrayReference; - _indices = indices; + _arrayAccess = arrayAccess; } protected override IOperation CreateArrayReference() { - return _operationFactory.Create(_arrayReference); + // The compiler will dedupe the _arrayAccess.Expression between different array references. Some example code: + // + // class C + // { + // int[] a; + + // static void Main() + // { + // // Compiler dedupes the array access receiver for [0] and [1] + // var a = new C { a = { [0] = 1, [1] = 2 } }; + // } + // } + // + // In order to prevent parent pointer from having an issue with this, we intentionally create a new IOperation node every time + // we encounter an array access. Since we create from the top down, it should be impossible for us to see the node in + // boundArrayAccess.Expression before seeing the boundArrayAccess itself, so this should not create any other parent pointer + // issues. + return _operationFactory.CreateInternal(_arrayAccess.Expression); } protected override ImmutableArray CreateIndices() { - return _operationFactory.CreateFromArray(_indices); + return _operationFactory.CreateFromArray(_arrayAccess.Indices); } } internal sealed class CSharpLazyArrayInitializerOperation : LazyArrayInitializerOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _elementValues; + private readonly BoundArrayInitialization _arrayInitialization; - internal CSharpLazyArrayInitializerOperation(CSharpOperationFactory operationFactory, ImmutableArray elementValues, SemanticModel semanticModel, SyntaxNode syntax, Optional constantValue, bool isImplicit) : + internal CSharpLazyArrayInitializerOperation(CSharpOperationFactory operationFactory, BoundArrayInitialization arrayInitialization, SemanticModel semanticModel, SyntaxNode syntax, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, constantValue, isImplicit) { _operationFactory = operationFactory; - _elementValues = elementValues; + _arrayInitialization = arrayInitialization; } protected override ImmutableArray CreateElementValues() { - return _operationFactory.CreateFromArray(_elementValues); + return _operationFactory.CreateFromArray(_arrayInitialization.Initializers); } } internal sealed class CSharpLazySimpleAssignmentOperation : LazySimpleAssignmentOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _target; - private readonly BoundNode _value; + private readonly BoundAssignmentOperator _assignmentOperator; - internal CSharpLazySimpleAssignmentOperation(CSharpOperationFactory operationFactory, BoundNode target, BoundNode value, bool isRef, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazySimpleAssignmentOperation(CSharpOperationFactory operationFactory, BoundAssignmentOperator assignment, bool isRef, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(isRef, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _target = target; - _value = value; + _assignmentOperator = assignment; } protected override IOperation CreateTarget() { - return _operationFactory.Create(_target); + return _operationFactory.Create(_assignmentOperator.Left); } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + return _operationFactory.Create(_assignmentOperator.Right); } } internal sealed class CSharpLazyDeconstructionAssignmentOperation : LazyDeconstructionAssignmentOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _target; - private readonly BoundNode _value; + private readonly BoundDeconstructionAssignmentOperator _deconstructionAssignment; - internal CSharpLazyDeconstructionAssignmentOperation(CSharpOperationFactory operationFactory, BoundNode target, BoundNode value, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyDeconstructionAssignmentOperation(CSharpOperationFactory operationFactory, BoundDeconstructionAssignmentOperator deconstructionAssignment,SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _target = target; - _value = value; + _deconstructionAssignment = deconstructionAssignment; } protected override IOperation CreateTarget() { - return _operationFactory.Create(_target); + return _operationFactory.Create(_deconstructionAssignment.Left); } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + // Skip the synthetic deconstruction conversion wrapping the right operand. + return _operationFactory.Create(_deconstructionAssignment.Right.Operand); } } @@ -216,182 +226,166 @@ protected override IOperation CreateOperation() internal sealed class CSharpLazyBinaryOperation : LazyBinaryOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _leftOperand; - private readonly BoundNode _rightOperand; + private readonly BoundBinaryOperatorBase _binaryOperator; - internal CSharpLazyBinaryOperation(CSharpOperationFactory operationFactory, BoundNode leftOperand, BoundNode rightOperand, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, bool isCompareText, IMethodSymbol operatorMethod, IMethodSymbol unaryOperatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyBinaryOperation(CSharpOperationFactory operationFactory, BoundBinaryOperatorBase binaryOperator, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, bool isCompareText, IMethodSymbol operatorMethod, IMethodSymbol unaryOperatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(operatorKind, isLifted, isChecked, isCompareText, operatorMethod, unaryOperatorMethod, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _leftOperand = leftOperand; - _rightOperand = rightOperand; + _binaryOperator = binaryOperator; } protected override IOperation CreateLeftOperand() { - return _operationFactory.Create(_leftOperand); + return _operationFactory.Create(_binaryOperator.Left); } protected override IOperation CreateRightOperand() { - return _operationFactory.Create(_rightOperand); + return _operationFactory.Create(_binaryOperator.Right); } } internal sealed class CSharpLazyTupleBinaryOperation : LazyTupleBinaryOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _leftOperand; - private readonly BoundNode _rightOperand; + private readonly BoundTupleBinaryOperator _tupleBinaryOperator; - internal CSharpLazyTupleBinaryOperation(CSharpOperationFactory operationFactory, BoundNode leftOperand, BoundNode rightOperand, BinaryOperatorKind operatorKind, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyTupleBinaryOperation(CSharpOperationFactory operationFactory, BoundTupleBinaryOperator tupleBinaryOperator, BinaryOperatorKind operatorKind, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(operatorKind, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _leftOperand = leftOperand; - _rightOperand = rightOperand; + _tupleBinaryOperator = tupleBinaryOperator; } protected override IOperation CreateLeftOperand() { - return _operationFactory.Create(_leftOperand); + return _operationFactory.Create(_tupleBinaryOperator.ConvertedLeft); } protected override IOperation CreateRightOperand() { - return _operationFactory.Create(_rightOperand); + return _operationFactory.Create(_tupleBinaryOperator.ConvertedRight); } } internal sealed class CSharpLazyBlockOperation : LazyBlockOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _operations; + private readonly BoundBlock _block; - internal CSharpLazyBlockOperation(CSharpOperationFactory operationFactory, ImmutableArray operations, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyBlockOperation(CSharpOperationFactory operationFactory, BoundBlock block, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _operations = operations; + _block = block; } protected override ImmutableArray CreateOperations() { - return _operationFactory.CreateFromArray(_operations); + return _operationFactory.CreateFromArray(_block.Statements); } } internal sealed class CSharpLazyCatchClauseOperation : LazyCatchClauseOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundLocal _exceptionDeclarationOrExpression; - private readonly BoundNode _filter; - private readonly BoundNode _handler; + private readonly BoundCatchBlock _catchBlock; - internal CSharpLazyCatchClauseOperation(CSharpOperationFactory operationFactory, BoundLocal exceptionDeclarationOrExpression, BoundNode filter, BoundNode handler, ITypeSymbol exceptionType, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyCatchClauseOperation(CSharpOperationFactory operationFactory, BoundCatchBlock catchBlock, ITypeSymbol exceptionType, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(exceptionType, locals, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _exceptionDeclarationOrExpression = exceptionDeclarationOrExpression; - _filter = filter; - _handler = handler; + _catchBlock = catchBlock; } protected override IOperation CreateExceptionDeclarationOrExpression() { - return _operationFactory.CreateVariableDeclarator(_exceptionDeclarationOrExpression); + return _operationFactory.CreateVariableDeclarator((BoundLocal)_catchBlock.ExceptionSourceOpt); } protected override IOperation CreateFilter() { - return _operationFactory.Create(_filter); + return _operationFactory.Create(_catchBlock.ExceptionFilterOpt); } protected override IBlockOperation CreateHandler() { - return (IBlockOperation)_operationFactory.Create(_handler); + return (IBlockOperation)_operationFactory.Create(_catchBlock.Body); } } internal sealed class CSharpLazyCompoundAssignmentOperation : LazyCompoundAssignmentOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _target; - private readonly BoundNode _value; + private readonly BoundCompoundAssignmentOperator _compoundAssignmentOperator; - internal CSharpLazyCompoundAssignmentOperation(CSharpOperationFactory operationFactory, BoundNode target, BoundNode value, IConvertibleConversion inConversionConvertible, IConvertibleConversion outConversionConvertible, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyCompoundAssignmentOperation(CSharpOperationFactory operationFactory, BoundCompoundAssignmentOperator compoundAssignmentOperator, IConvertibleConversion inConversionConvertible, IConvertibleConversion outConversionConvertible, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(inConversionConvertible, outConversionConvertible, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _target = target; - _value = value; + _compoundAssignmentOperator = compoundAssignmentOperator; } protected override IOperation CreateTarget() { - return _operationFactory.Create(_target); + return _operationFactory.Create(_compoundAssignmentOperator.Left); } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + return _operationFactory.Create(_compoundAssignmentOperator.Right); } } internal sealed class CSharpLazyConditionalAccessOperation : LazyConditionalAccessOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _operation; - private readonly BoundNode _whenNotNull; + private readonly BoundConditionalAccess _conditionalAccess; - internal CSharpLazyConditionalAccessOperation(CSharpOperationFactory operationFactory, BoundNode operation, BoundNode whenNotNull, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyConditionalAccessOperation(CSharpOperationFactory operationFactory, BoundConditionalAccess conditionalAccess, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _operation = operation; - _whenNotNull = whenNotNull; + _conditionalAccess = conditionalAccess; } protected override IOperation CreateOperation() { - return _operationFactory.Create(_operation); + return _operationFactory.Create(_conditionalAccess.Receiver); } protected override IOperation CreateWhenNotNull() { - return _operationFactory.Create(_whenNotNull); + return _operationFactory.Create(_conditionalAccess.AccessExpression); } } internal sealed class CSharpLazyConditionalOperation : LazyConditionalOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _condition; - private readonly BoundNode _whenTrue; - private readonly BoundNode _whenFalse; + private readonly IBoundConditional _boundConditional; - internal CSharpLazyConditionalOperation(CSharpOperationFactory operationFactory, BoundNode condition, BoundNode whenTrue, BoundNode whenFalse, bool isRef, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyConditionalOperation(CSharpOperationFactory operationFactory, IBoundConditional boundConditional, bool isRef, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(isRef, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _condition = condition; - _whenTrue = whenTrue; - _whenFalse = whenFalse; + _boundConditional = boundConditional; } protected override IOperation CreateCondition() { - return _operationFactory.Create(_condition); + return _operationFactory.Create(_boundConditional.Condition); } protected override IOperation CreateWhenTrue() { - return _operationFactory.Create(_whenTrue); + return _operationFactory.Create(_boundConditional.Consequence); } protected override IOperation CreateWhenFalse() { - return _operationFactory.Create(_whenFalse); + return _operationFactory.Create(_boundConditional.AlternativeOpt); } } @@ -529,25 +523,23 @@ protected override IOperation CreateInstance() internal sealed class CSharpLazyFixedOperation : LazyFixedOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _variables; - private readonly BoundNode _body; + private readonly BoundFixedStatement _fixedStatement; - internal CSharpLazyFixedOperation(CSharpOperationFactory operationFactory, BoundNode variables, BoundNode body, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyFixedOperation(CSharpOperationFactory operationFactory, BoundFixedStatement fixedStatement, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _variables = variables; - _body = body; + _fixedStatement = fixedStatement; } protected override IVariableDeclarationGroupOperation CreateVariables() { - return (IVariableDeclarationGroupOperation)_operationFactory.Create(_variables); + return (IVariableDeclarationGroupOperation)_operationFactory.Create(_fixedStatement.Declarations); } protected override IOperation CreateBody() { - return _operationFactory.Create(_body); + return _operationFactory.Create(_fixedStatement.Body); } } @@ -592,39 +584,33 @@ protected override ForEachLoopOperationInfo CreateLoopInfo() internal sealed class CSharpLazyForLoopOperation : LazyForLoopOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _before; - private readonly BoundNode _condition; - private readonly ImmutableArray _atLoopBottom; - private readonly BoundNode _body; + private readonly BoundForStatement _forStatement; - internal CSharpLazyForLoopOperation(CSharpOperationFactory operationFactory, ImmutableArray before, BoundNode condition, ImmutableArray atLoopBottom, BoundNode body, ImmutableArray locals, ImmutableArray conditionLocals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyForLoopOperation(CSharpOperationFactory operationFactory, BoundForStatement forStatement, ImmutableArray locals, ImmutableArray conditionLocals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, conditionLocals, continueLabel, exitLabel, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _before = before; - _condition = condition; - _atLoopBottom = atLoopBottom; - _body = body; + _forStatement = forStatement; } protected override ImmutableArray CreateBefore() { - return _operationFactory.CreateFromArray(_before); + return _operationFactory.CreateFromArray(_operationFactory.ToStatements(_forStatement.Initializer)); } protected override IOperation CreateCondition() { - return _operationFactory.Create(_condition); + return _operationFactory.Create(_forStatement.Condition); } protected override ImmutableArray CreateAtLoopBottom() { - return _operationFactory.CreateFromArray(_atLoopBottom); + return _operationFactory.CreateFromArray(_operationFactory.ToStatements(_forStatement.Increment)); } protected override IOperation CreateBody() { - return _operationFactory.Create(_body); + return _operationFactory.Create(_forStatement.Body); } } @@ -649,18 +635,18 @@ protected override IOperation CreateTarget() internal sealed class CSharpLazyInterpolatedStringOperation : LazyInterpolatedStringOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _parts; + private readonly BoundInterpolatedString _interpolatedString; - internal CSharpLazyInterpolatedStringOperation(CSharpOperationFactory operationFactory, ImmutableArray parts, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyInterpolatedStringOperation(CSharpOperationFactory operationFactory, BoundInterpolatedString interpolatedString, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _parts = parts; + _interpolatedString = interpolatedString; } protected override ImmutableArray CreateParts() { - return _operationFactory.CreateBoundInterpolatedStringContentOperation(_parts); + return _operationFactory.CreateBoundInterpolatedStringContentOperation(_interpolatedString.Parts); } } @@ -685,32 +671,28 @@ protected override IOperation CreateText() internal sealed class CSharpLazyInterpolationOperation : LazyInterpolationOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _expression; - private readonly BoundNode _alignment; - private readonly BoundNode _formatString; + private readonly BoundStringInsert _stringInsert; - internal CSharpLazyInterpolationOperation(CSharpOperationFactory operationFactory, BoundNode expression, BoundNode alignment, BoundNode formatString, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyInterpolationOperation(CSharpOperationFactory operationFactory, BoundStringInsert stringInsert, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _expression = expression; - _alignment = alignment; - _formatString = formatString; + _stringInsert = stringInsert; } protected override IOperation CreateExpression() { - return _operationFactory.Create(_expression); + return _operationFactory.Create(_stringInsert.Value); } protected override IOperation CreateAlignment() { - return _operationFactory.Create(_alignment); + return _operationFactory.Create(_stringInsert.Alignment); } protected override IOperation CreateFormatString() { - return _operationFactory.Create(_formatString); + return _operationFactory.Create(_stringInsert.Format); } } @@ -735,25 +717,23 @@ protected override ImmutableArray CreateChildren() internal sealed class CSharpLazyInvocationOperation : LazyInvocationOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundExpression _instance; - private readonly BoundNode _boundCall; + private readonly IBoundInvocableExpression _invocableExpression; - internal CSharpLazyInvocationOperation(CSharpOperationFactory operationFactory, BoundExpression instance, BoundNode boundNode, IMethodSymbol targetMethod, bool isVirtual, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyInvocationOperation(CSharpOperationFactory operationFactory, IBoundInvocableExpression invocableExpression, IMethodSymbol targetMethod, bool isVirtual, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(targetMethod, isVirtual, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _instance = instance; - _boundCall = boundNode; + _invocableExpression = invocableExpression; } protected override IOperation CreateInstance() { - return _operationFactory.CreateReceiverOperation(_instance, TargetMethod); + return _operationFactory.CreateReceiverOperation(_invocableExpression.ReceiverOpt, TargetMethod); } protected override ImmutableArray CreateArguments() { - return _operationFactory.DeriveArguments(_boundCall); + return _operationFactory.DeriveArguments(_invocableExpression.GetAsBoundNode()); } } @@ -850,25 +830,23 @@ protected override IOperation CreateInstance() internal sealed class CSharpLazyLockOperation : LazyLockOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _lockedValue; - private readonly BoundNode _body; + private readonly BoundLockStatement _lockStatement; - internal CSharpLazyLockOperation(CSharpOperationFactory operationFactory, BoundNode lockedValue, BoundNode body, ILocalSymbol lockTakenSymbol, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyLockOperation(CSharpOperationFactory operationFactory, BoundLockStatement lockStatement, ILocalSymbol lockTakenSymbol, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(lockTakenSymbol, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _lockedValue = lockedValue; - _body = body; + _lockStatement = lockStatement; } protected override IOperation CreateLockedValue() { - return _operationFactory.Create(_lockedValue); + return _operationFactory.Create(_lockStatement.Argument); } protected override IOperation CreateBody() { - return _operationFactory.Create(_body); + return _operationFactory.Create(_lockStatement.Body); } } @@ -893,50 +871,46 @@ protected override IOperation CreateInstance() internal sealed class CSharpLazyCoalesceOperation : LazyCoalesceOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _value; - private readonly BoundNode _whenNull; + private readonly BoundNullCoalescingOperator _nullCoalescingOperator; - internal CSharpLazyCoalesceOperation(CSharpOperationFactory operationFactory, BoundNode value, BoundNode whenNull, IConvertibleConversion convertibleValueConversion, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyCoalesceOperation(CSharpOperationFactory operationFactory, BoundNullCoalescingOperator nullCoalescingOperator, IConvertibleConversion convertibleValueConversion, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(convertibleValueConversion, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _value = value; - _whenNull = whenNull; + _nullCoalescingOperator = nullCoalescingOperator; } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + return _operationFactory.Create(_nullCoalescingOperator.LeftOperand); } protected override IOperation CreateWhenNull() { - return _operationFactory.Create(_whenNull); + return _operationFactory.Create(_nullCoalescingOperator.RightOperand); } } internal sealed class CSharpLazyCoalesceAssignmentOperation : LazyCoalesceAssignmentOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _target; - private readonly BoundNode _value; + private readonly BoundNullCoalescingAssignmentOperator _nullCoalescingAssignmentOperator; - internal CSharpLazyCoalesceAssignmentOperation(CSharpOperationFactory operationFactory, BoundNode target, BoundNode value, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyCoalesceAssignmentOperation(CSharpOperationFactory operationFactory, BoundNullCoalescingAssignmentOperator nullCoalescingAssignmentOperator, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _target = target; - _value = value; + _nullCoalescingAssignmentOperator = nullCoalescingAssignmentOperator; } protected override IOperation CreateTarget() { - return _operationFactory.Create(_target); + return _operationFactory.Create(_nullCoalescingAssignmentOperator.LeftOperand); } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + return _operationFactory.Create(_nullCoalescingAssignmentOperator.RightOperand); } } @@ -966,20 +940,18 @@ protected override ImmutableArray CreateArguments() internal sealed class CSharpLazyAnonymousObjectCreationOperation : LazyAnonymousObjectCreationOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _arguments; - private readonly ImmutableArray _declarations; + private readonly IBoundAnonymousObjectCreation _anonymousObjectCreation; - internal CSharpLazyAnonymousObjectCreationOperation(CSharpOperationFactory operationFactory, ImmutableArray arguments, ImmutableArray declarations, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyAnonymousObjectCreationOperation(CSharpOperationFactory operationFactory, IBoundAnonymousObjectCreation anonymousObjectCreation, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _arguments = arguments; - _declarations = declarations; + _anonymousObjectCreation = anonymousObjectCreation; } protected override ImmutableArray CreateInitializers() { - return _operationFactory.GetAnonymousObjectCreationInitializers(_arguments, _declarations, Syntax, Type, IsImplicit); + return _operationFactory.GetAnonymousObjectCreationInitializers(_anonymousObjectCreation, Syntax, Type, IsImplicit); } } @@ -1083,107 +1055,97 @@ protected override IOperation CreateValue() internal sealed class CSharpLazySwitchCaseOperation : LazySwitchCaseOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _clauses; - private readonly BoundNode _condition; - private readonly ImmutableArray _body; + private readonly IBoundSwitchSection _switchSection; - internal CSharpLazySwitchCaseOperation(CSharpOperationFactory operationFactory, ImmutableArray clauses, BoundNode condition, ImmutableArray body, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazySwitchCaseOperation(CSharpOperationFactory operationFactory, IBoundSwitchSection switchSection, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _clauses = clauses; - _condition = condition; - _body = body; + _switchSection = switchSection; } protected override ImmutableArray CreateClauses() { - return _operationFactory.CreateFromArray(_clauses); + return _operationFactory.CreateFromArray(_switchSection.SwitchLabels); } protected override IOperation CreateCondition() { - return _operationFactory.Create(_condition); + return null; } protected override ImmutableArray CreateBody() { - return _operationFactory.CreateFromArray(_body); + return _operationFactory.CreateFromArray(_switchSection.Statements); } } internal sealed class CSharpLazySwitchOperation : LazySwitchOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _value; - private readonly ImmutableArray _cases; + private readonly IBoundSwitchStatement _switchStatement; - internal CSharpLazySwitchOperation(CSharpOperationFactory operationFactory, BoundNode value, ImmutableArray cases, ImmutableArray locals, ILabelSymbol exitLabel, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazySwitchOperation(CSharpOperationFactory operationFactory, IBoundSwitchStatement switchStatement, ImmutableArray locals, ILabelSymbol exitLabel, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, exitLabel, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _value = value; - _cases = cases; + _switchStatement = switchStatement; } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + return _operationFactory.Create(_switchStatement.Value); } protected override ImmutableArray CreateCases() { - return _operationFactory.CreateFromArray(_cases); + return _operationFactory.CreateFromArray(_switchStatement.Cases); } } internal sealed class CSharpLazyTryOperation : LazyTryOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _body; - private readonly ImmutableArray _catches; - private readonly BoundNode _finally; + private readonly BoundTryStatement _tryStatement; - internal CSharpLazyTryOperation(CSharpOperationFactory operationFactory, BoundNode body, ImmutableArray catches, BoundNode @finally, ILabelSymbol exitLabel, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyTryOperation(CSharpOperationFactory operationFactory, BoundTryStatement tryStatement, ILabelSymbol exitLabel, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(exitLabel, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _body = body; - _catches = catches; - _finally = @finally; + _tryStatement = tryStatement; } protected override IBlockOperation CreateBody() { - return (IBlockOperation)_operationFactory.Create(_body); + return (IBlockOperation)_operationFactory.Create(_tryStatement.TryBlock); } protected override ImmutableArray CreateCatches() { - return _operationFactory.CreateFromArray(_catches); + return _operationFactory.CreateFromArray(_tryStatement.CatchBlocks); } protected override IBlockOperation CreateFinally() { - return (IBlockOperation)_operationFactory.Create(_finally); + return (IBlockOperation)_operationFactory.Create(_tryStatement.FinallyBlockOpt); } } internal sealed class CSharpLazyTupleOperation : LazyTupleOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _elements; + private readonly BoundTupleExpression _tupleExpression; - internal CSharpLazyTupleOperation(CSharpOperationFactory operationFactory, ImmutableArray elements, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, ITypeSymbol naturalType, Optional constantValue, bool isImplicit) : + internal CSharpLazyTupleOperation(CSharpOperationFactory operationFactory, BoundTupleExpression tupleExpression, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, ITypeSymbol naturalType, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, naturalType, constantValue, isImplicit) { _operationFactory = operationFactory; - _elements = elements; + _tupleExpression = tupleExpression; } protected override ImmutableArray CreateElements() { - return _operationFactory.CreateFromArray(_elements); + return _operationFactory.CreateFromArray(_tupleExpression.Arguments); } } @@ -1208,50 +1170,46 @@ protected override IObjectOrCollectionInitializerOperation CreateInitializer() internal sealed class CSharpLazyDynamicObjectCreationOperation : LazyDynamicObjectCreationOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _arguments; - private readonly BoundNode _initializer; + private readonly BoundDynamicObjectCreationExpression _dynamicObjectCreationExpression; - internal CSharpLazyDynamicObjectCreationOperation(CSharpOperationFactory operationFactory, ImmutableArray arguments, BoundNode initializer, ImmutableArray argumentNames, ImmutableArray argumentRefKinds, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyDynamicObjectCreationOperation(CSharpOperationFactory operationFactory, BoundDynamicObjectCreationExpression dynamicObjectCreationExpression, ImmutableArray argumentNames, ImmutableArray argumentRefKinds, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(argumentNames, argumentRefKinds, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _arguments = arguments; - _initializer = initializer; + _dynamicObjectCreationExpression = dynamicObjectCreationExpression; } protected override ImmutableArray CreateArguments() { - return _operationFactory.CreateFromArray(_arguments); + return _operationFactory.CreateFromArray(_dynamicObjectCreationExpression.Arguments); } protected override IObjectOrCollectionInitializerOperation CreateInitializer() { - return (IObjectOrCollectionInitializerOperation)_operationFactory.Create(_initializer); + return (IObjectOrCollectionInitializerOperation)_operationFactory.Create(_dynamicObjectCreationExpression.InitializerExpressionOpt); } } internal sealed class CSharpLazyDynamicInvocationOperation : LazyDynamicInvocationOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _operation; - private readonly ImmutableArray _arguments; + private readonly BoundDynamicInvocableBase _dynamicInvocable; - internal CSharpLazyDynamicInvocationOperation(CSharpOperationFactory operationFactory, BoundNode operation, ImmutableArray arguments, ImmutableArray argumentNames, ImmutableArray argumentRefKinds, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyDynamicInvocationOperation(CSharpOperationFactory operationFactory, BoundDynamicInvocableBase dynamicInvocable, ImmutableArray argumentNames, ImmutableArray argumentRefKinds, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(argumentNames, argumentRefKinds, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _operation = operation; - _arguments = arguments; + _dynamicInvocable = dynamicInvocable; } protected override IOperation CreateOperation() { - return _operationFactory.CreateBoundDynamicInvocationExpressionReceiver(_operation); + return _operationFactory.CreateBoundDynamicInvocationExpressionReceiver(_dynamicInvocable.Expression); } protected override ImmutableArray CreateArguments() { - return _operationFactory.CreateFromArray(_arguments); + return _operationFactory.CreateFromArray(_dynamicInvocable.Arguments); } } @@ -1299,25 +1257,23 @@ protected override IOperation CreateOperand() internal sealed class CSharpLazyUsingOperation : LazyUsingOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _resources; - private readonly BoundNode _body; + private readonly BoundUsingStatement _usingStatement; - internal CSharpLazyUsingOperation(CSharpOperationFactory operationFactory, BoundNode resources, BoundNode body, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyUsingOperation(CSharpOperationFactory operationFactory, BoundUsingStatement usingStatement, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _resources = resources; - _body = body; + _usingStatement = usingStatement; } protected override IOperation CreateResources() { - return _operationFactory.Create(_resources); + return _operationFactory.Create((BoundNode)_usingStatement.DeclarationsOpt ?? _usingStatement.ExpressionOpt); } protected override IOperation CreateBody() { - return _operationFactory.Create(_body); + return _operationFactory.Create(_usingStatement.Body); } } @@ -1348,14 +1304,12 @@ internal sealed class CSharpLazyVariableDeclarationOperation : LazyVariableDecla { private readonly CSharpOperationFactory _operationFactory; private readonly BoundNode _localDeclaration; - private readonly BoundNode _initializer; - internal CSharpLazyVariableDeclarationOperation(CSharpOperationFactory operationFactory, BoundNode localDeclaration, BoundNode initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyVariableDeclarationOperation(CSharpOperationFactory operationFactory, BoundNode localDeclaration, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; _localDeclaration = localDeclaration; - _initializer = initializer; } protected override ImmutableArray CreateDeclarators() @@ -1365,64 +1319,60 @@ protected override ImmutableArray CreateDeclarator protected override IVariableInitializerOperation CreateInitializer() { - return (IVariableInitializerOperation)_operationFactory.Create(_initializer); + return null; } } internal sealed class CSharpLazyWhileLoopOperation : LazyWhileLoopOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _condition; - private readonly BoundNode _body; - private readonly BoundNode _ignoredCondition; + private readonly BoundConditionalLoopStatement _conditionalLoopStatement; - internal CSharpLazyWhileLoopOperation(CSharpOperationFactory operationFactory, BoundNode condition, BoundNode body, BoundNode ignoredCondition, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, bool conditionIsTop, bool conditionIsUntil, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyWhileLoopOperation(CSharpOperationFactory operationFactory, BoundConditionalLoopStatement conditionalLoopStatement, ImmutableArray locals, ILabelSymbol continueLabel, ILabelSymbol exitLabel, bool conditionIsTop, bool conditionIsUntil, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(locals, continueLabel, exitLabel, conditionIsTop, conditionIsUntil, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _condition = condition; - _body = body; - _ignoredCondition = ignoredCondition; + _conditionalLoopStatement = conditionalLoopStatement; } protected override IOperation CreateCondition() { - return _operationFactory.Create(_condition); + return _operationFactory.Create(_conditionalLoopStatement.Condition); } protected override IOperation CreateBody() { - return _operationFactory.Create(_body); + return _operationFactory.Create(_conditionalLoopStatement.Body); } protected override IOperation CreateIgnoredCondition() { - return _operationFactory.Create(_ignoredCondition); + return null; } } internal sealed class CSharpLazyLocalFunctionOperation : LazyLocalFunctionOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _body; - private readonly BoundNode _ignoredBody; + private readonly BoundLocalFunctionStatement _localFunctionStatement; - internal CSharpLazyLocalFunctionOperation(CSharpOperationFactory operationFactory, BoundNode body, BoundNode ignoredBody, IMethodSymbol symbol, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyLocalFunctionOperation(CSharpOperationFactory operationFactory, BoundLocalFunctionStatement localFunctionStatement, IMethodSymbol symbol, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(symbol, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _body = body; - _ignoredBody = ignoredBody; + _localFunctionStatement = localFunctionStatement; } protected override IBlockOperation CreateBody() { - return (IBlockOperation)_operationFactory.Create(_body); + return (IBlockOperation)_operationFactory.Create(_localFunctionStatement.Body); } protected override IBlockOperation CreateIgnoredBody() { - return (IBlockOperation)_operationFactory.Create(_ignoredBody); + return _localFunctionStatement.BlockBody != null && _localFunctionStatement.ExpressionBody != null ? + (IBlockOperation)_operationFactory.Create(_localFunctionStatement.ExpressionBody) : + null; } } @@ -1447,93 +1397,87 @@ protected override IOperation CreateValue() internal sealed class CSharpLazyPatternCaseClauseOperation : LazyPatternCaseClauseOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _pattern; - private readonly BoundNode _guard; + private readonly BoundPatternSwitchLabel _patternSwitchLabel; - internal CSharpLazyPatternCaseClauseOperation(CSharpOperationFactory operationFactory, BoundNode pattern, BoundNode guard, ILabelSymbol label, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyPatternCaseClauseOperation(CSharpOperationFactory operationFactory, BoundPatternSwitchLabel patternSwitchLabel, ILabelSymbol label, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(label, semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _pattern = pattern; - _guard = guard; + _patternSwitchLabel = patternSwitchLabel; } protected override IPatternOperation CreatePattern() { - return (IPatternOperation)_operationFactory.Create(_pattern); + return (IPatternOperation)_operationFactory.Create(_patternSwitchLabel.Pattern); } protected override IOperation CreateGuard() { - return _operationFactory.Create(_guard); + return _operationFactory.Create(_patternSwitchLabel.Guard); } } internal sealed class CSharpLazyIsPatternOperation : LazyIsPatternOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _value; - private readonly BoundNode _pattern; + private readonly BoundIsPatternExpression _isPatternExpression; - internal CSharpLazyIsPatternOperation(CSharpOperationFactory operationFactory, BoundNode value, BoundNode pattern, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyIsPatternOperation(CSharpOperationFactory operationFactory, BoundIsPatternExpression isPatternExpression, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _value = value; - _pattern = pattern; + _isPatternExpression = isPatternExpression; } protected override IOperation CreateValue() { - return _operationFactory.Create(_value); + return _operationFactory.Create(_isPatternExpression.Expression); } protected override IPatternOperation CreatePattern() { - return (IPatternOperation)_operationFactory.Create(_pattern); + return (IPatternOperation)_operationFactory.Create(_isPatternExpression.Pattern); } } internal sealed class CSharpLazyObjectOrCollectionInitializerOperation : LazyObjectOrCollectionInitializerOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly ImmutableArray _initializers; + private readonly BoundExpression _initializer; - internal CSharpLazyObjectOrCollectionInitializerOperation(CSharpOperationFactory operationFactory, ImmutableArray initializers, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyObjectOrCollectionInitializerOperation(CSharpOperationFactory operationFactory, BoundExpression initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _initializers = initializers; + _initializer = initializer; } protected override ImmutableArray CreateInitializers() { - return _operationFactory.CreateFromArray(_initializers); + return _operationFactory.CreateFromArray(BoundObjectCreationExpression.GetChildInitializers(_initializer)); } } internal sealed class CSharpLazyMemberInitializerOperation : LazyMemberInitializerOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _initializedMember; - private readonly BoundNode _initializer; + private readonly BoundAssignmentOperator _assignmentOperator; - internal CSharpLazyMemberInitializerOperation(CSharpOperationFactory operationFactory, BoundNode initializedMember, BoundNode initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : + internal CSharpLazyMemberInitializerOperation(CSharpOperationFactory operationFactory, BoundAssignmentOperator assignmentOperator, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit) { _operationFactory = operationFactory; - _initializedMember = initializedMember; - _initializer = initializer; + _assignmentOperator = assignmentOperator; } protected override IOperation CreateInitializedMember() { - return _operationFactory.CreateMemberInitializerInitializedMember(_initializedMember); + return _operationFactory.CreateMemberInitializerInitializedMember(_assignmentOperator.Left); } protected override IObjectOrCollectionInitializerOperation CreateInitializer() { - return (IObjectOrCollectionInitializerOperation)_operationFactory.Create(_initializer); + return (IObjectOrCollectionInitializerOperation)_operationFactory.Create(_assignmentOperator.Right); } } @@ -1558,57 +1502,51 @@ protected override IOperation CreateOperation() internal sealed class CSharpLazyMethodBodyOperation : LazyMethodBodyOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _blockBody; - private readonly BoundNode _expressionBody; + private readonly BoundNonConstructorMethodBody _methodBody; - internal CSharpLazyMethodBodyOperation(CSharpOperationFactory operationFactory, BoundNode blockBody, BoundNode expressionBody, SemanticModel semanticModel, SyntaxNode syntax) : + internal CSharpLazyMethodBodyOperation(CSharpOperationFactory operationFactory, BoundNonConstructorMethodBody methodBody, SemanticModel semanticModel, SyntaxNode syntax) : base(semanticModel, syntax) { _operationFactory = operationFactory; - _blockBody = blockBody; - _expressionBody = expressionBody; + _methodBody = methodBody; } protected override IBlockOperation CreateBlockBody() { - return (IBlockOperation)_operationFactory.Create(_blockBody); + return (IBlockOperation)_operationFactory.Create(_methodBody.BlockBody); } protected override IBlockOperation CreateExpressionBody() { - return (IBlockOperation)_operationFactory.Create(_expressionBody); + return (IBlockOperation)_operationFactory.Create(_methodBody.ExpressionBody); } } internal sealed class CSharpLazyConstructorBodyOperation : LazyConstructorBodyOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _initializer; - private readonly BoundNode _blockBody; - private readonly BoundNode _expressionBody; + private readonly BoundConstructorMethodBody _constructorMethodBody; - internal CSharpLazyConstructorBodyOperation(CSharpOperationFactory operationFactory, BoundNode initializer, BoundNode blockBody, BoundNode expressionBody, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax) : + internal CSharpLazyConstructorBodyOperation(CSharpOperationFactory operationFactory, BoundConstructorMethodBody constructorMethodBody, ImmutableArray locals, SemanticModel semanticModel, SyntaxNode syntax) : base(locals, semanticModel, syntax) { _operationFactory = operationFactory; - _initializer = initializer; - _blockBody = blockBody; - _expressionBody = expressionBody; + _constructorMethodBody = constructorMethodBody; } protected override IOperation CreateInitializer() { - return _operationFactory.Create(_initializer); + return _operationFactory.Create(_constructorMethodBody.Initializer); } protected override IBlockOperation CreateBlockBody() { - return (IBlockOperation)_operationFactory.Create(_blockBody); + return (IBlockOperation)_operationFactory.Create(_constructorMethodBody.BlockBody); } protected override IBlockOperation CreateExpressionBody() { - return (IBlockOperation)_operationFactory.Create(_expressionBody); + return (IBlockOperation)_operationFactory.Create(_constructorMethodBody.ExpressionBody); } } @@ -1651,25 +1589,23 @@ protected override IOperation CreateOperand() internal sealed class CSharpLazyRangeOperation : LazyRangeOperation { private readonly CSharpOperationFactory _operationFactory; - private readonly BoundNode _leftOperand; - private readonly BoundNode _rightOperand; + private readonly BoundRangeExpression _rangeExpression; - internal CSharpLazyRangeOperation(CSharpOperationFactory operationFactory, BoundNode leftOperand, BoundNode rightOperand, bool isLifted, bool isImplicit, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, IMethodSymbol symbol) : + internal CSharpLazyRangeOperation(CSharpOperationFactory operationFactory, BoundRangeExpression rangeExpression, bool isLifted, bool isImplicit, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, IMethodSymbol symbol) : base(isLifted, isImplicit, semanticModel, syntax, type, symbol) { _operationFactory = operationFactory; - _leftOperand = leftOperand; - _rightOperand = rightOperand; + _rangeExpression = rangeExpression; } protected override IOperation CreateLeftOperand() { - return _operationFactory.Create(_leftOperand); + return _operationFactory.Create(_rangeExpression.LeftOperand); } protected override IOperation CreateRightOperand() { - return _operationFactory.Create(_rightOperand); + return _operationFactory.Create(_rangeExpression.RightOperand); } } }