diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
index a20aa39f78dc997f0c524c07e717410345d45e46..1a4e0b1daa30ef0a03cbf1414dc8568e1da3f3b4 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
@@ -236,35 +236,43 @@ internal BoundExpression BindValueAllowArgList(ExpressionSyntax node, Diagnostic
return CheckValue(result, valueKind, diagnostics);
}
- internal BoundExpression BindVariableOrAutoPropInitializer(
+ internal BoundFieldEqualsValue BindFieldInitializer(
+ FieldSymbol field,
EqualsValueClauseSyntax initializerOpt,
- RefKind refKind,
- TypeSymbol varType,
DiagnosticBag diagnostics)
{
+ Debug.Assert((object)this.ContainingMemberOrLambda == field);
+
if (initializerOpt == null)
{
return null;
}
- SymbolKind containingMemberOrLambdaKind = this.ContainingMemberOrLambda.Kind;
- Debug.Assert(containingMemberOrLambdaKind == SymbolKind.Field || containingMemberOrLambdaKind == SymbolKind.Method);
- bool isMemberInitializer = containingMemberOrLambdaKind == SymbolKind.Field;
- Binder initializerBinder = isMemberInitializer ? this.GetBinder(initializerOpt) : this;
-
+ Binder initializerBinder = this.GetBinder(initializerOpt);
Debug.Assert(initializerBinder != null);
- BindValueKind valueKind;
- ExpressionSyntax value;
- IsInitializerRefKindValid(initializerOpt, initializerOpt, refKind, diagnostics, out valueKind, out value);
- var initializer = initializerBinder.BindPossibleArrayInitializer(value, varType, valueKind, diagnostics);
- initializer = initializerBinder.GenerateConversionForAssignment(varType, initializer, diagnostics);
+ BoundExpression result = initializerBinder.BindVariableOrAutoPropInitializerValue(initializerOpt, RefKind.None,
+ field.GetFieldType(initializerBinder.FieldsBeingBound), diagnostics);
- if (isMemberInitializer)
+ return new BoundFieldEqualsValue(initializerOpt, field, initializerBinder.GetDeclaredLocalsForScope(initializerOpt), result);
+ }
+
+ internal BoundExpression BindVariableOrAutoPropInitializerValue(
+ EqualsValueClauseSyntax initializerOpt,
+ RefKind refKind,
+ TypeSymbol varType,
+ DiagnosticBag diagnostics)
+ {
+ if (initializerOpt == null)
{
- initializer = initializerBinder.WrapWithVariablesIfAny(initializerOpt, initializer);
+ return null;
}
+ BindValueKind valueKind;
+ ExpressionSyntax value;
+ IsInitializerRefKindValid(initializerOpt, initializerOpt, refKind, diagnostics, out valueKind, out value);
+ BoundExpression initializer = BindPossibleArrayInitializer(value, varType, valueKind, diagnostics);
+ initializer = GenerateConversionForAssignment(varType, initializer, diagnostics);
return initializer;
}
@@ -278,9 +286,9 @@ internal BoundExpression BindValueAllowArgList(ExpressionSyntax node, Diagnostic
binder);
}
- internal BoundExpression BindParameterDefaultValue(
+ internal BoundParameterEqualsValue BindParameterDefaultValue(
EqualsValueClauseSyntax defaultValueSyntax,
- TypeSymbol parameterType,
+ ParameterSymbol parameter,
DiagnosticBag diagnostics,
out BoundExpression valueBeforeConversion)
{
@@ -295,10 +303,11 @@ internal BoundExpression BindValueAllowArgList(ExpressionSyntax node, Diagnostic
// Always generate the conversion, even if the expression is not convertible to the given type.
// We want the erroneous conversion in the tree.
- return defaultValueBinder.WrapWithVariablesIfAny(defaultValueSyntax, defaultValueBinder.GenerateConversionForAssignment(parameterType, valueBeforeConversion, diagnostics, isDefaultParameter: true));
+ return new BoundParameterEqualsValue(defaultValueSyntax, parameter, defaultValueBinder.GetDeclaredLocalsForScope(defaultValueSyntax),
+ defaultValueBinder.GenerateConversionForAssignment(parameter.Type, valueBeforeConversion, diagnostics, isDefaultParameter: true));
}
- internal BoundExpression BindEnumConstantInitializer(
+ internal BoundFieldEqualsValue BindEnumConstantInitializer(
SourceEnumConstantSymbol symbol,
EqualsValueClauseSyntax equalsValueSyntax,
DiagnosticBag diagnostics)
@@ -308,7 +317,7 @@ internal BoundExpression BindValueAllowArgList(ExpressionSyntax node, Diagnostic
var initializer = initializerBinder.BindValue(equalsValueSyntax.Value, diagnostics, BindValueKind.RValue);
initializer = initializerBinder.GenerateConversionForAssignment(symbol.ContainingType.EnumUnderlyingType, initializer, diagnostics);
- return initializerBinder.WrapWithVariablesIfAny(equalsValueSyntax, initializer);
+ return new BoundFieldEqualsValue(equalsValueSyntax, symbol, initializerBinder.GetDeclaredLocalsForScope(equalsValueSyntax), initializer);
}
public BoundExpression BindExpression(ExpressionSyntax node, DiagnosticBag diagnostics)
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs
index 73b583d0d795495e4f591b8c827f350da36ab16c..6919314e1a887af6ca777827498c44f02d334677 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs
@@ -110,7 +110,7 @@ internal struct ProcessedFieldInitializers
parentBinder = new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.FieldInitializer, fieldSymbol);
- BoundFieldInitializer boundInitializer = BindFieldInitializer(parentBinder, fieldSymbol, initializerNode, diagnostics);
+ BoundFieldEqualsValue boundInitializer = BindFieldInitializer(parentBinder, fieldSymbol, initializerNode, diagnostics);
boundInitializers.Add(boundInitializer);
}
}
@@ -246,7 +246,7 @@ internal struct ProcessedFieldInitializers
return new BoundGlobalStatementInitializer(statementNode, statement);
}
- private static BoundFieldInitializer BindFieldInitializer(Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax equalsValueClauseNode,
+ private static BoundFieldEqualsValue BindFieldInitializer(Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax equalsValueClauseNode,
DiagnosticBag diagnostics)
{
Debug.Assert(!fieldSymbol.IsMetadataConstant);
@@ -269,17 +269,14 @@ internal struct ProcessedFieldInitializers
}
binder = new ExecutableCodeBinder(equalsValueClauseNode, fieldSymbol, new LocalScopeBinder(binder));
- var boundInitValue = binder.BindVariableOrAutoPropInitializer(equalsValueClauseNode, RefKind.None, fieldSymbol.GetFieldType(fieldsBeingBound), initializerDiagnostics);
+ BoundFieldEqualsValue boundInitValue = binder.BindFieldInitializer(fieldSymbol, equalsValueClauseNode, initializerDiagnostics);
if (isImplicitlyTypedField)
{
initializerDiagnostics.Free();
}
- return new BoundFieldInitializer(
- equalsValueClauseNode.Value, //we want the attached sequence point to indicate the value node
- fieldSymbol,
- boundInitValue);
+ return boundInitValue;
}
}
}
diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
index 4e1fe41bd8b6ce96687ae4ea8b566c9e936e990e..164e2585593f5349a16946bb743d393a65e8e711 100644
--- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
+++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
@@ -33,12 +33,8 @@
-
-
-
-
-
-
+
+
diff --git a/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
index 28ade0abe694227fad3c79fcad76fa20ab9043e3..e19182e7945317d6dabdb5eaf7ab5f42a869f2f5 100644
--- a/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
@@ -157,54 +157,36 @@ private BoundEqualsValue BindEqualsValue(Binder binder, EqualsValueClauseSyntax
{
var field = (FieldSymbol)this.MemberSymbol;
var enumField = field as SourceEnumConstantSymbol;
- BoundExpression result;
if ((object)enumField != null)
{
- result = binder.BindEnumConstantInitializer(enumField, equalsValue, diagnostics);
+ return binder.BindEnumConstantInitializer(enumField, equalsValue, diagnostics);
}
else
{
- result = binder.BindVariableOrAutoPropInitializer(equalsValue, RefKind.None, field.GetFieldType(binder.FieldsBeingBound), diagnostics);
+ return binder.BindFieldInitializer(field, equalsValue, diagnostics);
}
- if (result != null)
- {
- return new BoundFieldEqualsValue(equalsValue, field, result);
- }
- break;
}
case SymbolKind.Property:
{
- var property = (PropertySymbol)this.MemberSymbol;
- BoundExpression result = binder.BindVariableOrAutoPropInitializer(equalsValue, RefKind.None, property.Type, diagnostics);
- if (result != null)
- {
- return new BoundPropertyEqualsValue(equalsValue, property, result);
- }
- break;
+ var property = (SourcePropertySymbol)this.MemberSymbol;
+ BoundFieldEqualsValue result = binder.BindFieldInitializer(property.BackingField, equalsValue, diagnostics);
+ return new BoundPropertyEqualsValue(result.Syntax, property, result.Locals, result.Value);
}
case SymbolKind.Parameter:
{
- BoundExpression unusedValueBeforeConversion; // not needed.
var parameter = (ParameterSymbol)this.MemberSymbol;
- BoundExpression result = binder.BindParameterDefaultValue(
+ return binder.BindParameterDefaultValue(
equalsValue,
- parameter.Type,
+ parameter,
diagnostics,
- out unusedValueBeforeConversion);
- if (result != null)
- {
- return new BoundParameterEqualsValue(equalsValue, parameter, result);
- }
- break;
+ out _);
}
default:
throw ExceptionUtilities.UnexpectedValue(this.MemberSymbol.Kind);
}
-
- return null;
}
private bool IsBindableInitializer(CSharpSyntaxNode node)
diff --git a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
index 066889d35dddb1989811f165c268aaacab9df6b1..bc35982a12cb6328670eca39846fa06fe06a2ec0 100644
--- a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
+++ b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
@@ -565,7 +565,7 @@ private void CompileNamedType(NamedTypeSymbol containingType)
if (_moduleBeingBuiltOpt != null && !hasStaticConstructor && !processedStaticInitializers.BoundInitializers.IsDefaultOrEmpty)
{
Debug.Assert(processedStaticInitializers.BoundInitializers.All((init) =>
- (init.Kind == BoundKind.FieldInitializer) && !((BoundFieldInitializer)init).Field.IsMetadataConstant));
+ (init.Kind == BoundKind.FieldEqualsValue) && !((BoundFieldEqualsValue)init).Field.IsMetadataConstant));
MethodSymbol method = new SynthesizedStaticConstructor(sourceTypeSymbol);
if (PassesFilter(_filterOpt, method))
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs
index 58cf04f4b7830aa5a00af816cedec64bc3f5b324..8f5a6468620f1127d008089779bf8e0f11acc57e 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs
@@ -1169,12 +1169,6 @@ public override BoundNode VisitScope(BoundScope node)
return null;
}
- public override BoundNode VisitFieldInitializer(BoundFieldInitializer node)
- {
- Visit(node.InitialValue);
- return null;
- }
-
public override BoundNode VisitExpressionStatement(BoundExpressionStatement node)
{
VisitRvalue(node.Expression);
diff --git a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs
index 22510a5fc1e6436607dd7c0fc11fabb6b70d67c1..acf1504cef6c4b3b3ff3c639ff85eeb884b32a1d 100644
--- a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs
@@ -20,7 +20,6 @@ namespace Microsoft.CodeAnalysis.CSharp
{
internal enum BoundKind: byte
{
- FieldInitializer,
FieldEqualsValue,
PropertyEqualsValue,
ParameterEqualsValue,
@@ -197,63 +196,33 @@ protected BoundInitializer(BoundKind kind, SyntaxNode syntax)
}
- internal sealed partial class BoundFieldInitializer : BoundInitializer
+ internal abstract partial class BoundEqualsValue : BoundInitializer
{
- public BoundFieldInitializer(SyntaxNode syntax, FieldSymbol field, BoundExpression initialValue, bool hasErrors = false)
- : base(BoundKind.FieldInitializer, syntax, hasErrors || initialValue.HasErrors())
- {
-
- Debug.Assert(field != null, "Field 'field' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
- Debug.Assert(initialValue != null, "Field 'initialValue' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
-
- this.Field = field;
- this.InitialValue = initialValue;
- }
-
-
- public FieldSymbol Field { get; }
-
- public BoundExpression InitialValue { get; }
-
- public override BoundNode Accept(BoundTreeVisitor visitor)
- {
- return visitor.VisitFieldInitializer(this);
- }
-
- public BoundFieldInitializer Update(FieldSymbol field, BoundExpression initialValue)
- {
- if (field != this.Field || initialValue != this.InitialValue)
- {
- var result = new BoundFieldInitializer(this.Syntax, field, initialValue, this.HasErrors);
- result.WasCompilerGenerated = this.WasCompilerGenerated;
- return result;
- }
- return this;
- }
- }
-
- internal abstract partial class BoundEqualsValue : BoundNode
- {
- protected BoundEqualsValue(BoundKind kind, SyntaxNode syntax, BoundExpression value, bool hasErrors = false)
+ protected BoundEqualsValue(BoundKind kind, SyntaxNode syntax, ImmutableArray locals, BoundExpression value, bool hasErrors = false)
: base(kind, syntax, hasErrors)
{
+ Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
Debug.Assert(value != null, "Field 'value' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
+ this.Locals = locals;
this.Value = value;
}
+ public ImmutableArray Locals { get; }
+
public BoundExpression Value { get; }
}
internal sealed partial class BoundFieldEqualsValue : BoundEqualsValue
{
- public BoundFieldEqualsValue(SyntaxNode syntax, FieldSymbol field, BoundExpression value, bool hasErrors = false)
- : base(BoundKind.FieldEqualsValue, syntax, value, hasErrors || value.HasErrors())
+ public BoundFieldEqualsValue(SyntaxNode syntax, FieldSymbol field, ImmutableArray locals, BoundExpression value, bool hasErrors = false)
+ : base(BoundKind.FieldEqualsValue, syntax, locals, value, hasErrors || value.HasErrors())
{
Debug.Assert(field != null, "Field 'field' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
+ Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
Debug.Assert(value != null, "Field 'value' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
this.Field = field;
@@ -267,11 +236,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor)
return visitor.VisitFieldEqualsValue(this);
}
- public BoundFieldEqualsValue Update(FieldSymbol field, BoundExpression value)
+ public BoundFieldEqualsValue Update(FieldSymbol field, ImmutableArray locals, BoundExpression value)
{
- if (field != this.Field || value != this.Value)
+ if (field != this.Field || locals != this.Locals || value != this.Value)
{
- var result = new BoundFieldEqualsValue(this.Syntax, field, value, this.HasErrors);
+ var result = new BoundFieldEqualsValue(this.Syntax, field, locals, value, this.HasErrors);
result.WasCompilerGenerated = this.WasCompilerGenerated;
return result;
}
@@ -281,11 +250,12 @@ public BoundFieldEqualsValue Update(FieldSymbol field, BoundExpression value)
internal sealed partial class BoundPropertyEqualsValue : BoundEqualsValue
{
- public BoundPropertyEqualsValue(SyntaxNode syntax, PropertySymbol property, BoundExpression value, bool hasErrors = false)
- : base(BoundKind.PropertyEqualsValue, syntax, value, hasErrors || value.HasErrors())
+ public BoundPropertyEqualsValue(SyntaxNode syntax, PropertySymbol property, ImmutableArray locals, BoundExpression value, bool hasErrors = false)
+ : base(BoundKind.PropertyEqualsValue, syntax, locals, value, hasErrors || value.HasErrors())
{
Debug.Assert(property != null, "Field 'property' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
+ Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
Debug.Assert(value != null, "Field 'value' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
this.Property = property;
@@ -299,11 +269,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor)
return visitor.VisitPropertyEqualsValue(this);
}
- public BoundPropertyEqualsValue Update(PropertySymbol property, BoundExpression value)
+ public BoundPropertyEqualsValue Update(PropertySymbol property, ImmutableArray locals, BoundExpression value)
{
- if (property != this.Property || value != this.Value)
+ if (property != this.Property || locals != this.Locals || value != this.Value)
{
- var result = new BoundPropertyEqualsValue(this.Syntax, property, value, this.HasErrors);
+ var result = new BoundPropertyEqualsValue(this.Syntax, property, locals, value, this.HasErrors);
result.WasCompilerGenerated = this.WasCompilerGenerated;
return result;
}
@@ -313,11 +283,12 @@ public BoundPropertyEqualsValue Update(PropertySymbol property, BoundExpression
internal sealed partial class BoundParameterEqualsValue : BoundEqualsValue
{
- public BoundParameterEqualsValue(SyntaxNode syntax, ParameterSymbol parameter, BoundExpression value, bool hasErrors = false)
- : base(BoundKind.ParameterEqualsValue, syntax, value, hasErrors || value.HasErrors())
+ public BoundParameterEqualsValue(SyntaxNode syntax, ParameterSymbol parameter, ImmutableArray locals, BoundExpression value, bool hasErrors = false)
+ : base(BoundKind.ParameterEqualsValue, syntax, locals, value, hasErrors || value.HasErrors())
{
Debug.Assert(parameter != null, "Field 'parameter' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
+ Debug.Assert(!locals.IsDefault, "Field 'locals' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
Debug.Assert(value != null, "Field 'value' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)");
this.Parameter = parameter;
@@ -331,11 +302,11 @@ public override BoundNode Accept(BoundTreeVisitor visitor)
return visitor.VisitParameterEqualsValue(this);
}
- public BoundParameterEqualsValue Update(ParameterSymbol parameter, BoundExpression value)
+ public BoundParameterEqualsValue Update(ParameterSymbol parameter, ImmutableArray locals, BoundExpression value)
{
- if (parameter != this.Parameter || value != this.Value)
+ if (parameter != this.Parameter || locals != this.Locals || value != this.Value)
{
- var result = new BoundParameterEqualsValue(this.Syntax, parameter, value, this.HasErrors);
+ var result = new BoundParameterEqualsValue(this.Syntax, parameter, locals, value, this.HasErrors);
result.WasCompilerGenerated = this.WasCompilerGenerated;
return result;
}
@@ -6232,8 +6203,6 @@ internal R VisitInternal(BoundNode node, A arg)
{
switch (node.Kind)
{
- case BoundKind.FieldInitializer:
- return VisitFieldInitializer(node as BoundFieldInitializer, arg);
case BoundKind.FieldEqualsValue:
return VisitFieldEqualsValue(node as BoundFieldEqualsValue, arg);
case BoundKind.PropertyEqualsValue:
@@ -6544,10 +6513,6 @@ internal R VisitInternal(BoundNode node, A arg)
internal abstract partial class BoundTreeVisitor
{
- public virtual R VisitFieldInitializer(BoundFieldInitializer node, A arg)
- {
- return this.DefaultVisit(node, arg);
- }
public virtual R VisitFieldEqualsValue(BoundFieldEqualsValue node, A arg)
{
return this.DefaultVisit(node, arg);
@@ -7156,10 +7121,6 @@ public virtual R VisitConstructorMethodBody(BoundConstructorMethodBody node, A a
internal abstract partial class BoundTreeVisitor
{
- public virtual BoundNode VisitFieldInitializer(BoundFieldInitializer node)
- {
- return this.DefaultVisit(node);
- }
public virtual BoundNode VisitFieldEqualsValue(BoundFieldEqualsValue node)
{
return this.DefaultVisit(node);
@@ -7768,11 +7729,6 @@ public virtual BoundNode VisitConstructorMethodBody(BoundConstructorMethodBody n
internal abstract partial class BoundTreeWalker: BoundTreeVisitor
{
- public override BoundNode VisitFieldInitializer(BoundFieldInitializer node)
- {
- this.Visit(node.InitialValue);
- return null;
- }
public override BoundNode VisitFieldEqualsValue(BoundFieldEqualsValue node)
{
this.Visit(node.Value);
@@ -8558,25 +8514,20 @@ public override BoundNode VisitConstructorMethodBody(BoundConstructorMethodBody
internal abstract partial class BoundTreeRewriter : BoundTreeVisitor
{
- public override BoundNode VisitFieldInitializer(BoundFieldInitializer node)
- {
- BoundExpression initialValue = (BoundExpression)this.Visit(node.InitialValue);
- return node.Update(node.Field, initialValue);
- }
public override BoundNode VisitFieldEqualsValue(BoundFieldEqualsValue node)
{
BoundExpression value = (BoundExpression)this.Visit(node.Value);
- return node.Update(node.Field, value);
+ return node.Update(node.Field, node.Locals, value);
}
public override BoundNode VisitPropertyEqualsValue(BoundPropertyEqualsValue node)
{
BoundExpression value = (BoundExpression)this.Visit(node.Value);
- return node.Update(node.Property, value);
+ return node.Update(node.Property, node.Locals, value);
}
public override BoundNode VisitParameterEqualsValue(BoundParameterEqualsValue node)
{
BoundExpression value = (BoundExpression)this.Visit(node.Value);
- return node.Update(node.Parameter, value);
+ return node.Update(node.Parameter, node.Locals, value);
}
public override BoundNode VisitGlobalStatementInitializer(BoundGlobalStatementInitializer node)
{
@@ -9463,20 +9414,12 @@ public static TreeDumperNode MakeTree(BoundNode node)
{
return (new BoundTreeDumperNodeProducer()).Visit(node, null);
}
- public override TreeDumperNode VisitFieldInitializer(BoundFieldInitializer node, object arg)
- {
- return new TreeDumperNode("fieldInitializer", null, new TreeDumperNode[]
- {
- new TreeDumperNode("field", node.Field, null),
- new TreeDumperNode("initialValue", null, new TreeDumperNode[] { Visit(node.InitialValue, null) })
- }
- );
- }
public override TreeDumperNode VisitFieldEqualsValue(BoundFieldEqualsValue node, object arg)
{
return new TreeDumperNode("fieldEqualsValue", null, new TreeDumperNode[]
{
new TreeDumperNode("field", node.Field, null),
+ new TreeDumperNode("locals", node.Locals, null),
new TreeDumperNode("value", null, new TreeDumperNode[] { Visit(node.Value, null) })
}
);
@@ -9486,6 +9429,7 @@ public override TreeDumperNode VisitPropertyEqualsValue(BoundPropertyEqualsValue
return new TreeDumperNode("propertyEqualsValue", null, new TreeDumperNode[]
{
new TreeDumperNode("property", node.Property, null),
+ new TreeDumperNode("locals", node.Locals, null),
new TreeDumperNode("value", null, new TreeDumperNode[] { Visit(node.Value, null) })
}
);
@@ -9495,6 +9439,7 @@ public override TreeDumperNode VisitParameterEqualsValue(BoundParameterEqualsVal
return new TreeDumperNode("parameterEqualsValue", null, new TreeDumperNode[]
{
new TreeDumperNode("parameter", node.Parameter, null),
+ new TreeDumperNode("locals", node.Locals, null),
new TreeDumperNode("value", null, new TreeDumperNode[] { Visit(node.Value, null) })
}
);
diff --git a/src/Compilers/CSharp/Portable/Lowering/InitializerRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/InitializerRewriter.cs
index 6f4640d218a4382371cac64b6259e8f08e1fcc70..4c7c9374da3461f617ae9ca6aab9f54c68ce3ce8 100644
--- a/src/Compilers/CSharp/Portable/Lowering/InitializerRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/InitializerRewriter.cs
@@ -82,9 +82,10 @@ internal static BoundExpression GetTrailingScriptExpression(BoundStatement state
null;
}
- private static BoundStatement RewriteFieldInitializer(BoundFieldInitializer fieldInit)
+ private static BoundStatement RewriteFieldInitializer(BoundFieldEqualsValue fieldInit)
{
- var syntax = fieldInit.Syntax;
+ SyntaxNode syntax = fieldInit.Syntax;
+ syntax = (syntax as EqualsValueClauseSyntax)?.Value ?? syntax; //we want the attached sequence point to indicate the value node
var boundReceiver = fieldInit.Field.IsStatic ? null :
new BoundThisReference(syntax, fieldInit.Field.ContainingType);
@@ -95,7 +96,10 @@ private static BoundStatement RewriteFieldInitializer(BoundFieldInitializer fiel
boundReceiver,
fieldInit.Field,
constantValueOpt: null),
- fieldInit.InitialValue,
+ fieldInit.Locals.IsEmpty ?
+ fieldInit.Value :
+ new BoundSequence(fieldInit.Syntax, fieldInit.Locals, ImmutableArray.Empty, fieldInit.Value, fieldInit.Value.Type)
+ { WasCompilerGenerated = true },
fieldInit.Field.Type)
{ WasCompilerGenerated = true })
{ WasCompilerGenerated = fieldInit.WasCompilerGenerated };
@@ -108,8 +112,8 @@ private static BoundStatement RewriteInitializersAsStatements(BoundInitializer i
{
switch (initializer.Kind)
{
- case BoundKind.FieldInitializer:
- return RewriteFieldInitializer((BoundFieldInitializer)initializer);
+ case BoundKind.FieldEqualsValue:
+ return RewriteFieldInitializer((BoundFieldEqualsValue)initializer);
case BoundKind.GlobalStatementInitializer:
return ((BoundGlobalStatementInitializer)initializer).Statement;
default:
diff --git a/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.Analysis.cs b/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.Analysis.cs
index 216cca9ee6d9eaec7cbbf2fd93308e35657bc8d4..57b2704c05a6b831529e69ddb4cdefbd3a05a01f 100644
--- a/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.Analysis.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.Analysis.cs
@@ -111,7 +111,7 @@ private static BoundNode FindNodeToAnalyze(BoundNode node)
case BoundKind.Block:
case BoundKind.StatementList:
- case BoundKind.FieldInitializer:
+ case BoundKind.FieldEqualsValue:
return node;
case BoundKind.GlobalStatementInitializer:
diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
index 2a7fdec617bfa63b442e204785862ed7138e2cd1..be5e507d9668894d7e2dd730a28979972feff52f 100644
--- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
+++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
@@ -1254,7 +1254,7 @@ private IFieldInitializerOperation CreateBoundFieldEqualsValueOperation(BoundFie
ITypeSymbol type = null;
Optional