Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IObjectCreationExpression API Change #19278

Merged
merged 2 commits into from
May 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 1 addition & 37 deletions src/Compilers/CSharp/Portable/BoundTree/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -515,43 +515,7 @@ internal partial class BoundObjectCreationExpression : IObjectCreationExpression

ImmutableArray<IArgument> IHasArgumentsExpression.ArgumentsInEvaluationOrder => BoundCall.DeriveArguments(this.Arguments, this.ArgumentNamesOpt, this.ArgsToParamsOpt, this.ArgumentRefKindsOpt, this.Constructor.Parameters, this.Syntax);

ImmutableArray<ISymbolInitializer> IObjectCreationExpression.MemberInitializers
{
get
{
return (ImmutableArray<ISymbolInitializer>)s_memberInitializersMappings.GetValue(this,
objectCreationExpression =>
{
var objectInitializerExpression = this.InitializerExpressionOpt as BoundObjectInitializerExpression;
if (objectInitializerExpression != null)
{
var builder = ArrayBuilder<ISymbolInitializer>.GetInstance(objectInitializerExpression.Initializers.Length);
foreach (var memberAssignment in objectInitializerExpression.Initializers)
{
var assignment = memberAssignment as BoundAssignmentOperator;
var leftSymbol = (assignment?.Left as BoundObjectInitializerMember)?.MemberSymbol;

if ((object)leftSymbol == null)
{
continue;
}

switch (leftSymbol.Kind)
{
case SymbolKind.Field:
builder.Add(new FieldInitializer(assignment.Syntax, (IFieldSymbol)leftSymbol, assignment.Right));
break;
case SymbolKind.Property:
builder.Add(new PropertyInitializer(assignment.Syntax, (IPropertySymbol)leftSymbol, assignment.Right));
break;
}
}
return builder.ToImmutableAndFree();
}
return ImmutableArray<ISymbolInitializer>.Empty;
});
}
}
ImmutableArray<IOperation> IObjectCreationExpression.Initializers => GetChildInitializers(this.InitializerExpressionOpt).As<IOperation>();

internal static ImmutableArray<BoundExpression> GetChildInitializers(BoundExpression objectOrCollectionInitializer)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<Compile Include="IOperation\IOperationTests_IArgument.cs" />
<Compile Include="IOperation\IOperationTests_IIfStatement.cs" />
<Compile Include="IOperation\IOperationTests_IFieldReferenceExpression.cs" />
<Compile Include="IOperation\IOperationTests_IObjectCreationExpression.cs" />
<Compile Include="IOperation\IOperationTests_IParameterReferenceExpression.cs" />
<Compile Include="IOperation\IOperationTests_ISymbolInitializer.cs" />
<Compile Include="IOperation\IOperationTests_InvalidExpression.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ public void M3()
);
}

[Fact]
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/19300")]
public void MemberInitializerCSharp()
{
const string source = @"
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -165,26 +165,30 @@ public void M(int x, int y, int z)
";
string expectedOperationTree = @"
IObjectCreationExpression (Constructor: Class..ctor()) (OperationKind.ObjectCreationExpression, Type: Class) (Syntax: 'new Class() ... { X = z } }')
Member Initializers(4): IPropertyInitializer (Property: System.Int32 Class.X { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'X = x')
IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
IPropertyInitializer (Property: System.Collections.Generic.List<System.Int32> Class.Y { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'Y = { x, y, 3 }')
IOperation: (OperationKind.None) (Syntax: '{ x, y, 3 }')
Children(3): IOperation: (OperationKind.None) (Syntax: 'x')
Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
IOperation: (OperationKind.None) (Syntax: 'y')
Children(1): IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
IOperation: (OperationKind.None) (Syntax: '3')
Children(1): ILiteralExpression (Text: 3) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3')
IPropertyInitializer (Property: System.Collections.Generic.Dictionary<System.Int32, System.Int32> Class.Z { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'Z = { { x, y } }')
IOperation: (OperationKind.None) (Syntax: '{ { x, y } }')
Children(1): IOperation: (OperationKind.None) (Syntax: '{ x, y }')
Children(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
IPropertyInitializer (Property: Class Class.C { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'C = { X = z }')
IOperation: (OperationKind.None) (Syntax: '{ X = z }')
Children(1): IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Int32) (Syntax: 'X = z')
Left: IOperation: (OperationKind.None) (Syntax: 'X')
Right: IParameterReferenceExpression: z (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'z')
Initializers(4): IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Int32) (Syntax: 'X = x')
Left: IOperation: (OperationKind.None) (Syntax: 'X')
Right: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Collections.Generic.List<System.Int32>) (Syntax: 'Y = { x, y, 3 }')
Left: IOperation: (OperationKind.None) (Syntax: 'Y')
Right: IOperation: (OperationKind.None) (Syntax: '{ x, y, 3 }')
Children(3): IOperation: (OperationKind.None) (Syntax: 'x')
Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
IOperation: (OperationKind.None) (Syntax: 'y')
Children(1): IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
IOperation: (OperationKind.None) (Syntax: '3')
Children(1): ILiteralExpression (Text: 3) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3')
IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Collections.Generic.Dictionary<System.Int32, System.Int32>) (Syntax: 'Z = { { x, y } }')
Left: IOperation: (OperationKind.None) (Syntax: 'Z')
Right: IOperation: (OperationKind.None) (Syntax: '{ { x, y } }')
Children(1): IOperation: (OperationKind.None) (Syntax: '{ x, y }')
Children(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
IAssignmentExpression (OperationKind.AssignmentExpression, Type: Class) (Syntax: 'C = { X = z }')
Left: IOperation: (OperationKind.None) (Syntax: 'C')
Right: IOperation: (OperationKind.None) (Syntax: '{ X = z }')
Children(1): IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Int32) (Syntax: 'X = z')
Left: IOperation: (OperationKind.None) (Syntax: 'X')
Right: IParameterReferenceExpression: z (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'z')
";
var expectedDiagnostics = DiagnosticDescription.None;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,113 +332,5 @@ class C

VerifyOperationTreeAndDiagnosticsForTest<EqualsValueClauseSyntax>(source, expectedOperationTree, expectedDiagnostics);
}

[Fact, WorkItem(17595, "https://github.com/dotnet/roslyn/issues/17595")]
public void MemberInitializerCSharp()
{
string source = @"
struct B
{
public bool Field;
}

class F
{
public int Field;
public string Property1 { set; get; }
public B Property2 { set; get; }
}

class C
{
public void M1()
/*<bind>*/{
var x1 = new F();
var x2 = new F() { Field = 2 };
var x3 = new F() { Property1 = """""""" };
var x4 = new F() { Property1 = """""""", Field = 2 };
var x5 = new F() { Property2 = new B { Field = true } };

var e1 = new F() { Property2 = 1 };
var e2 = new F() { """""""" };
}/*</bind>*/
}
";
string expectedOperationTree = @"
IBlockStatement (7 statements, 7 locals) (OperationKind.BlockStatement, IsInvalid) (Syntax: '{ ... }')
Locals: Local_1: F x1
Local_2: F x2
Local_3: F x3
Local_4: F x4
Local_5: F x5
Local_6: F e1
Local_7: F e2
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'var x1 = new F();')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'var x1 = new F();')
Variables: Local_1: F x1
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F) (Syntax: 'new F()')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'var x2 = ne ... ield = 2 };')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'var x2 = ne ... ield = 2 };')
Variables: Local_1: F x2
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F) (Syntax: 'new F() { Field = 2 }')
Member Initializers(1): IFieldInitializer (Field: System.Int32 F.Field) (OperationKind.FieldInitializerInCreation) (Syntax: 'Field = 2')
ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: '2')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'var x3 = ne ... 1 = """""""" };')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'var x3 = ne ... 1 = """""""" };')
Variables: Local_1: F x3
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F, IsInvalid) (Syntax: 'new F() { P ... y1 = """""""" }')
Member Initializers(1): IPropertyInitializer (Property: System.String F.Property1 { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'Property1 = """"')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: """") (Syntax: '""""')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'var x4 = ne ... ield = 2 };')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'var x4 = ne ... ield = 2 };')
Variables: Local_1: F x4
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F, IsInvalid) (Syntax: 'new F() { P ... Field = 2 }')
Member Initializers(2): IPropertyInitializer (Property: System.String F.Property1 { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'Property1 = """"')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: """") (Syntax: '""""')
IFieldInitializer (Field: System.Int32 F.Field) (OperationKind.FieldInitializerInCreation) (Syntax: 'Field = 2')
ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: '2')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'var x5 = ne ... = true } };')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'var x5 = ne ... = true } };')
Variables: Local_1: F x5
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F) (Syntax: 'new F() { P ... = true } }')
Member Initializers(1): IPropertyInitializer (Property: B F.Property2 { get; set; }) (OperationKind.PropertyInitializerInCreation) (Syntax: 'Property2 = ... ld = true }')
IObjectCreationExpression (Constructor: B..ctor()) (OperationKind.ObjectCreationExpression, Type: B) (Syntax: 'new B { Field = true }')
Member Initializers(1): IFieldInitializer (Field: System.Boolean B.Field) (OperationKind.FieldInitializerInCreation) (Syntax: 'Field = true')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True) (Syntax: 'true')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'var e1 = ne ... rty2 = 1 };')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'var e1 = ne ... rty2 = 1 };')
Variables: Local_1: F e1
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F, IsInvalid) (Syntax: 'new F() { P ... erty2 = 1 }')
Member Initializers(1): IPropertyInitializer (Property: B F.Property2 { get; set; }) (OperationKind.PropertyInitializerInCreation, IsInvalid) (Syntax: 'Property2 = 1')
IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: B, IsInvalid) (Syntax: '1')
ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'var e2 = ne ... ) { """""""" };')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'var e2 = ne ... ) { """""""" };')
Variables: Local_1: F e2
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F, IsInvalid) (Syntax: 'new F() { """""""" }')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS1003: Syntax error, ',' expected
// var x3 = new F() { Property1 = """" };
Diagnostic(ErrorCode.ERR_SyntaxError, @"""""").WithArguments(",", "").WithLocation(20, 42),
// CS1003: Syntax error, ',' expected
// var x4 = new F() { Property1 = """", Field = 2 };
Diagnostic(ErrorCode.ERR_SyntaxError, @"""""").WithArguments(",", "").WithLocation(21, 42),
// CS1003: Syntax error, ',' expected
// var e2 = new F() { """" };
Diagnostic(ErrorCode.ERR_SyntaxError, @"""""").WithArguments(",", "").WithLocation(25, 30),
// CS0747: Invalid initializer member declarator
// var x3 = new F() { Property1 = """" };
Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, @"""""").WithLocation(20, 42),
// CS0747: Invalid initializer member declarator
// var x4 = new F() { Property1 = """", Field = 2 };
Diagnostic(ErrorCode.ERR_InvalidInitializerElementInitializer, @"""""").WithLocation(21, 42),
// CS0029: Cannot implicitly convert type 'int' to 'B'
// var e1 = new F() { Property2 = 1 };
Diagnostic(ErrorCode.ERR_NoImplicitConv, "1").WithArguments("int", "B").WithLocation(24, 40)
};

VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1522,11 +1522,11 @@ public override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, T
/// </remarks>
internal sealed partial class ObjectCreationExpression : Operation, IHasArgumentsExpression, IObjectCreationExpression
{
public ObjectCreationExpression(IMethodSymbol constructor, ImmutableArray<ISymbolInitializer> memberInitializers, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
public ObjectCreationExpression(IMethodSymbol constructor, ImmutableArray<IOperation> initializers, bool isInvalid, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(OperationKind.ObjectCreationExpression, isInvalid, syntax, type, constantValue)
{
Constructor = constructor;
MemberInitializers = memberInitializers;
Initializers = initializers;
}
/// <summary>
/// Constructor to be invoked on the created instance.
Expand All @@ -1535,7 +1535,7 @@ public ObjectCreationExpression(IMethodSymbol constructor, ImmutableArray<ISymbo
/// <summary>
/// Explicitly-specified member initializers.
/// </summary>
public ImmutableArray<ISymbolInitializer> MemberInitializers { get; }
public ImmutableArray<IOperation> Initializers { get; }
public override void Accept(OperationVisitor visitor)
{
visitor.VisitObjectCreationExpression(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public interface IObjectCreationExpression : IHasArgumentsExpression
/// </summary>
IMethodSymbol Constructor { get; }
/// <summary>
/// Explicitly-specified member initializers.
/// List of member or collection initializer expressions in the object initializer, if any.
/// </summary>
ImmutableArray<ISymbolInitializer> MemberInitializers { get; }
ImmutableArray<IOperation> Initializers { get; }
}
}

2 changes: 1 addition & 1 deletion src/Compilers/Core/Portable/Operations/OperationWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ public override void VisitAddressOfExpression(IAddressOfExpression operation)
public override void VisitObjectCreationExpression(IObjectCreationExpression operation)
{
VisitArray(operation.ArgumentsInEvaluationOrder);
VisitArray(operation.MemberInitializers);
VisitArray(operation.Initializers);
}

public override void VisitFieldInitializer(IFieldInitializer operation)
Expand Down
Loading