Skip to content

Commit d7ede1d

Browse files
Use interpolation to cover some more basic xml cases
1 parent ad525b3 commit d7ede1d

2 files changed

Lines changed: 76 additions & 8 deletions

File tree

CodeConverter/CSharp/ExpressionNodeVisitor.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,36 @@ public override async Task<CSharpSyntaxNode> DefaultVisit(SyntaxNode node)
9090
.WithNodeInformation(node);
9191
}
9292

93+
public override async Task<CSharpSyntaxNode> VisitXmlEmbeddedExpression(VBSyntax.XmlEmbeddedExpressionSyntax node) =>
94+
await node.Expression.AcceptAsync<ExpressionSyntax>(TriviaConvertingExpressionVisitor);
95+
9396
public override async Task<CSharpSyntaxNode> VisitXmlElement(VBasic.Syntax.XmlElementSyntax node)
9497
{
9598
_extraUsingDirectives.Add("System.Xml.Linq");
96-
var aggregatedContent = node.Content.Select(n => n.ToString()).Aggregate(String.Empty, (a, b) => a + b);
97-
var xmlAsString = $"{node.StartTag}{aggregatedContent}{node.EndTag}".Trim();
99+
var interpolations = await AcceptXmlInterpolated(node);
100+
var interpolationsList = SyntaxFactory.List(interpolations);
101+
var xmlAsString = $"{node.StartTag}{interpolationsList}{node.EndTag}".Trim();
102+
var interpolatedString = SyntaxFactory.InterpolatedStringExpression(SyntaxFactory.Token(SyntaxKind.InterpolatedStringStartToken), interpolationsList, SyntaxFactory.Token(SyntaxKind.InterpolatedStringEndToken));
98103
return SyntaxFactory.InvocationExpression(
99104
SyntaxFactory.MemberAccessExpression(
100105
SyntaxKind.SimpleMemberAccessExpression,
101106
SyntaxFactory.IdentifierName("XElement"),
102107
SyntaxFactory.IdentifierName("Parse")))
103-
.WithArgumentList(
104-
ExpressionSyntaxExtensions.CreateArgList(
105-
SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression,
106-
SyntaxFactory.Literal(xmlAsString))
107-
)
108-
);
108+
.WithArgumentList(ExpressionSyntaxExtensions.CreateArgList(interpolatedString));
109+
}
110+
111+
private static InterpolatedStringTextSyntax InterpolatedStringText(string text) =>
112+
SyntaxFactory.InterpolatedStringText(SyntaxFactory.Token(SyntaxFactory.TriviaList(), SyntaxKind.InterpolatedStringTextToken, text, text, SyntaxFactory.TriviaList()));
113+
114+
private async Task<IEnumerable<InterpolatedStringContentSyntax>> AcceptXmlInterpolated(VBSyntax.XmlNodeSyntax n)
115+
{
116+
if (n is VBSyntax.XmlElementSyntax xmlEs) {
117+
return InterpolatedStringText(xmlEs.StartTag.ToString()).Yield()
118+
.Concat(await xmlEs.Content.SelectManyAsync(AcceptXmlInterpolated))
119+
.Concat(InterpolatedStringText(xmlEs.EndTag.ToString()));
120+
}
121+
var expression = await n.AcceptAsync<ExpressionSyntax>(TriviaConvertingExpressionVisitor);
122+
return new[] { SyntaxFactory.Interpolation(expression) };
109123
}
110124

111125
/// <summary>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using ICSharpCode.CodeConverter.Tests.TestRunners;
4+
using Xunit;
5+
6+
namespace ICSharpCode.CodeConverter.Tests.CSharp.ExpressionTests
7+
{
8+
/// <summary>
9+
/// See https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/xml/how-to-transform-xml-by-using-linq
10+
/// </summary>
11+
public class XmlExpressionTests : ConverterTestBase
12+
{
13+
[Fact]
14+
public async Task NestedXmlEchoSimpleAsync()
15+
{
16+
await TestConversionVisualBasicToCSharpAsync(@"Class TestClass
17+
Private Sub TestMethod()
18+
Dim hello = ""Hello""
19+
dim x = <h1><%= hello %></h1>
20+
End Sub
21+
End Class", @"using System.Xml.Linq;
22+
23+
internal partial class TestClass
24+
{
25+
private void TestMethod()
26+
{
27+
string hello = ""Hello"";
28+
XElement x = XElement.Parse($""<h1>{hello}</h1>"");
29+
}
30+
}");
31+
}
32+
[Fact]
33+
public async Task TwoLayerNestedXmlWithExpressionsAsync()
34+
{
35+
await TestConversionVisualBasicToCSharpAsync(@"Class TestClass
36+
Private Sub TestMethod()
37+
Dim var1 = 1
38+
Dim var2 = 2
39+
dim x = <h1><%= var1 %><%= var2 %><span><%= var2 %><%= var1 %></span></h1>
40+
End Sub
41+
End Class", @"using System.Xml.Linq;
42+
43+
internal partial class TestClass
44+
{
45+
private void TestMethod()
46+
{
47+
int var1 = 1;
48+
int var2 = 2;
49+
XElement x = XElement.Parse($""<h1>{var1}{var2}<span>{var2}{var1}</span> </h1>"");
50+
}
51+
}");
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)