diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs index 80cfbbdd33..263d979b9b 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs @@ -2400,7 +2400,54 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.PrintToken(Tokens.CloseParenthesis); return null; } - + + 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) + { + case XmlAxisType.Element: + outputFormatter.PrintToken(Tokens.Dot); + outputFormatter.PrintText("Elements(\""); + outputFormatter.PrintText(xmlMemberAccessExpression.Identifier); + 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); + outputFormatter.PrintText("Descendants(\""); + outputFormatter.PrintText(xmlMemberAccessExpression.Identifier); + outputFormatter.PrintText("\")"); + break; + default: + throw new Exception("Invalid value for XmlAxisType"); + } + return null; + } + public override object TrackedVisitIdentifierExpression(IdentifierExpression identifierExpression, object data) { outputFormatter.PrintIdentifier(identifierExpression.Identifier); @@ -2472,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(); } @@ -3187,9 +3239,22 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.Space(); return selectClause.Projection.AcceptVisitor(this, data); } - - public override object TrackedVisitQueryExpressionWhereClause(QueryExpressionWhereClause whereClause, object data) + + public override object TrackedVisitQueryExpressionSelectVBClause(QueryExpressionSelectVBClause queryExpressionSelectVBClause, object data) + { + outputFormatter.Space(); + outputFormatter.PrintToken(Tokens.Select); + outputFormatter.Space(); + foreach (var v in queryExpressionSelectVBClause.Variables) + { + v.AcceptVisitor(this, data); + } + return null; + } + + public override object TrackedVisitQueryExpressionWhereClause(QueryExpressionWhereClause whereClause, object data) { + outputFormatter.Space(); outputFormatter.PrintToken(Tokens.Where); outputFormatter.Space(); return whereClause.Condition.AcceptVisitor(this, data); diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs index e73d4fcde0..e33bfc08f7 100644 --- a/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs +++ b/src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs @@ -913,7 +913,48 @@ static bool InitStaticVariableHelper(Microsoft.VisualBasic.CompilerServices.Stat TestStatement(@"Dim xml = "", @"var xml = new XElement(""A"", ""\"""");"); } - + + [Test] + public void XmlLINQDescendants() + { + TestStatement(@"Dim element = someXml...", + @"var element = someXml.Descendants(""somename"");"); + } + [Test] + public void XmlLINQElements() + { + TestStatement(@"Dim element = someXml.", + @"var element = someXml.Elements(""somename"");"); + } + + [Test] + public void XmlLINQAttribute() + { + TestStatement(@"Dim value = someXml.@attr", + @"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() {