diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs index cce25f8eb4..263d979b9b 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs @@ -2403,6 +2403,11 @@ namespace ICSharpCode.NRefactory.PrettyPrinter public override object TrackedVisitXmlMemberAccessExpression(XmlMemberAccessExpression xmlMemberAccessExpression, object data) { + var parentAsAssignment = xmlMemberAccessExpression.Parent as AssignmentExpression; + var xmlMemberAccessExpressionOnLeftOfAssignment = parentAsAssignment != null && parentAsAssignment.Left == xmlMemberAccessExpression; + + // only output identifier expression if we are not overriding assignment with method call + if(!(xmlMemberAccessExpression.AxisType == XmlAxisType.Attribute && xmlMemberAccessExpressionOnLeftOfAssignment)) xmlMemberAccessExpression.TargetObject.AcceptVisitor(this, data); switch (xmlMemberAccessExpression.AxisType) @@ -2414,10 +2419,22 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.PrintText("\")"); break; case XmlAxisType.Attribute: + if (!xmlMemberAccessExpressionOnLeftOfAssignment) + { outputFormatter.PrintToken(Tokens.Dot); outputFormatter.PrintText("Attribute(\""); outputFormatter.PrintText(xmlMemberAccessExpression.Identifier); outputFormatter.PrintText("\").Value"); + } + else + { + // we need to convert assignment to method call + return AstBuilder.ExpressionBuilder.Call( + xmlMemberAccessExpression.TargetObject, + "SetAttributeValue", + new PrimitiveExpression(xmlMemberAccessExpression.Identifier), + parentAsAssignment.Right); + } break; case XmlAxisType.Descendents: outputFormatter.PrintToken(Tokens.Dot); @@ -2502,7 +2519,12 @@ namespace ICSharpCode.NRefactory.PrettyPrinter public override object TrackedVisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) { - TrackVisit(assignmentExpression.Left, data); + var overrideExpression = TrackVisit(assignmentExpression.Left, data) as InvocationExpression; + if (overrideExpression != null) + { + TrackVisit(overrideExpression, data); + return null; + } if (this.prettyPrintOptions.AroundAssignmentParentheses) { outputFormatter.Space(); } diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs index aebb178470..e33bfc08f7 100644 --- a/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs +++ b/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs @@ -913,7 +913,6 @@ static bool InitStaticVariableHelper(Microsoft.VisualBasic.CompilerServices.Stat TestStatement(@"Dim xml = "", @"var xml = new XElement(""A"", ""\"""");"); } - [Test] public void XmlLINQDescendants() @@ -935,12 +934,27 @@ static bool InitStaticVariableHelper(Microsoft.VisualBasic.CompilerServices.Stat @"var value = someXml.Attribute(""attr"").Value;"); } + [Test] + public void XmlLINQAttributeSetConstant() + { + TestStatement(@"someElement.@someAttr = 8", + @"someElement.SetAttributeValue(""someAttr"", 8);"); + } + + [Test] + public void XmlLINQAttributeSetExpression() + { + TestStatement(@"someElement.@someAttr = string.Format(""{0}"", 19)", + @"someElement.SetAttributeValue(""someAttr"", string.Format(""{0}"", 19));"); + } + [Test] public void LinqQueryWhereSelect() { TestStatement(@"Dim value = From value In values Where value = ""someValue"" Select value", @"var value = from value in values where value == ""someValue"" select value;"); } + [Test] public void SD2_1500a() {