Skip to content

Commit

Permalink
C# -> VB: Support "is pattern expressions" - fixes #63
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamTheCoder committed Apr 2, 2018
1 parent ced6d1f commit a288747
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 57 deletions.
28 changes: 23 additions & 5 deletions ICSharpCode.CodeConverter/VB/CommonConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,21 @@ private SyntaxList<StatementSyntax> ConvertStatement(Microsoft.CodeAnalysis.CSha
private SyntaxList<StatementSyntax> InsertRequiredDeclarations(
SyntaxList<StatementSyntax> convertedStatements, CSharpSyntaxNode originaNode)
{
var declarationExpressions = originaNode.DescendantNodes().OfType<DeclarationExpressionSyntax>().ToList();
if (declarationExpressions.Any()) {
convertedStatements = convertedStatements.Insert(0, ConvertToDeclarationStatement(declarationExpressions));
var descendantNodes = originaNode.DescendantNodes().ToList();
var declarationExpressions = descendantNodes.OfType<DeclarationExpressionSyntax>().ToList();
var isPatternExpressions = descendantNodes.OfType<IsPatternExpressionSyntax>().ToList();
if (declarationExpressions.Any() || isPatternExpressions.Any()) {
convertedStatements = convertedStatements.Insert(0, ConvertToDeclarationStatement(declarationExpressions, isPatternExpressions));
}

return convertedStatements;
}

private StatementSyntax ConvertToDeclarationStatement(List<DeclarationExpressionSyntax> des)
private StatementSyntax ConvertToDeclarationStatement(List<DeclarationExpressionSyntax> des,
List<IsPatternExpressionSyntax> isPatternExpressions)
{
var declarators = SyntaxFactory.SeparatedList(des.Select(ConvertToVariableDeclarator));
var declarators = SyntaxFactory.SeparatedList(des.Select(ConvertToVariableDeclarator)
.Concat(isPatternExpressions.Select(ConvertToVariableDeclarator)));
return SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.DimKeyword)), declarators);
}

Expand All @@ -107,6 +111,20 @@ private VariableDeclaratorSyntax ConvertToVariableDeclarator(DeclarationExpressi
var equalsValueSyntax = SyntaxFactory.EqualsValue(SyntaxFactory.LiteralExpression(SyntaxKind.NothingLiteralExpression, SyntaxFactory.Token(SyntaxKind.NothingKeyword)));
return SyntaxFactory.VariableDeclarator(ids, simpleAsClauseSyntax, equalsValueSyntax);
}
private VariableDeclaratorSyntax ConvertToVariableDeclarator(IsPatternExpressionSyntax node)
{
return node.Pattern.TypeSwitch(
(DeclarationPatternSyntax d) => {
var id = ((IdentifierNameSyntax)d.Designation.Accept(_nodesVisitor)).Identifier;
var ids = SyntaxFactory.SingletonSeparatedList(SyntaxFactory.ModifiedIdentifier(id));
TypeSyntax right = (TypeSyntax)d.Type.Accept(_nodesVisitor);
var simpleAsClauseSyntax = SyntaxFactory.SimpleAsClause(right);
var equalsValueSyntax = SyntaxFactory.EqualsValue(SyntaxFactory.LiteralExpression(SyntaxKind.NothingLiteralExpression, SyntaxFactory.Token(SyntaxKind.NothingKeyword)));
return SyntaxFactory.VariableDeclarator(ids, simpleAsClauseSyntax, equalsValueSyntax);
},
p => throw new ArgumentOutOfRangeException(nameof(p), p, null));
}

private CSharpSyntaxVisitor<SyntaxList<StatementSyntax>> CreateMethodBodyVisitor(MethodBodyVisitor methodBodyVisitor = null)
{
Expand Down
116 changes: 70 additions & 46 deletions ICSharpCode.CodeConverter/VB/NodesVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,22 @@ public override VisualBasicSyntaxNode VisitConstructorDeclaration(CSS.Constructo
);
}

public override VisualBasicSyntaxNode VisitIsPatternExpression(CSS.IsPatternExpressionSyntax node)
{
return node.Pattern.TypeSwitch(
(CSS.DeclarationPatternSyntax d) => {
var left = (ExpressionSyntax) d.Designation.Accept(TriviaConvertingVisitor);
ExpressionSyntax right = SyntaxFactory.TryCastExpression(
(ExpressionSyntax)node.Expression.Accept(TriviaConvertingVisitor),
(TypeSyntax)d.Type.Accept(TriviaConvertingVisitor));
var tryCast = CreateInlineAssignmentExpression(left, right);
var nothingExpression = SyntaxFactory.LiteralExpression(SyntaxKind.NothingLiteralExpression, SyntaxFactory.Token(SyntaxKind.NothingKeyword));
return SyntaxFactory.IsNotExpression(tryCast, nothingExpression);
},
p => throw new ArgumentOutOfRangeException(nameof(p), p, null));
}

public override VisualBasicSyntaxNode VisitDeclarationExpression(CSS.DeclarationExpressionSyntax node)
{
return node.Designation.Accept(TriviaConvertingVisitor);
Expand Down Expand Up @@ -677,6 +693,60 @@ public override VisualBasicSyntaxNode VisitPrefixUnaryExpression(CSS.PrefixUnary
return SyntaxFactory.UnaryExpression(kind, SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(kind)), (ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor));
}

public override VisualBasicSyntaxNode VisitAssignmentExpression(CSS.AssignmentExpressionSyntax node)
{
if (IsReturnValueDiscarded(node)) {
if (_semanticModel.GetTypeInfo(node.Right).ConvertedType.IsDelegateType()) {
if (SyntaxTokenExtensions.IsKind(node.OperatorToken, CS.SyntaxKind.PlusEqualsToken)) {
return SyntaxFactory.AddHandlerStatement((ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor), (ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor));
}
if (SyntaxTokenExtensions.IsKind(node.OperatorToken, CS.SyntaxKind.MinusEqualsToken)) {
return SyntaxFactory.RemoveHandlerStatement((ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor), (ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor));
}
}
return MakeAssignmentStatement(node);
}
if (node.Parent is CSS.ForStatementSyntax) {
return MakeAssignmentStatement(node);
}
if (node.Parent is CSS.InitializerExpressionSyntax) {
if (node.Left is CSS.ImplicitElementAccessSyntax) {
return SyntaxFactory.CollectionInitializer(
SyntaxFactory.SeparatedList(new[] {
(ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor),
(ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor)
})
);
} else {
return SyntaxFactory.NamedFieldInitializer(
(IdentifierNameSyntax)node.Left.Accept(TriviaConvertingVisitor),
(ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor)
);
}
}

var left = (ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor);
var right = (ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor);
return CreateInlineAssignmentExpression(left, right);
}

private ExpressionSyntax CreateInlineAssignmentExpression(ExpressionSyntax left, ExpressionSyntax right)
{
_cSharpHelperMethodDefinition.AddInlineAssignMethod = true;
return SyntaxFactory.InvocationExpression(
SyntaxFactory.IdentifierName(CSharpHelperMethodDefinition.QualifiedInlineAssignMethodName),
SyntaxFactory.ArgumentList(
SyntaxFactory.SeparatedList(
new ArgumentSyntax[]
{
SyntaxFactory.SimpleArgument(left),
SyntaxFactory.SimpleArgument(right)
}
)
)
);
}

public override VisualBasicSyntaxNode VisitPostfixUnaryExpression(CSS.PostfixUnaryExpressionSyntax node)
{
var kind = CS.CSharpExtensions.Kind(node).ConvertToken(TokenContext.Local);
Expand Down Expand Up @@ -720,52 +790,6 @@ public override VisualBasicSyntaxNode VisitPostfixUnaryExpression(CSS.PostfixUna
}
}

public override VisualBasicSyntaxNode VisitAssignmentExpression(CSS.AssignmentExpressionSyntax node)
{
if (IsReturnValueDiscarded(node)) {
if (_semanticModel.GetTypeInfo(node.Right).ConvertedType.IsDelegateType()) {
if (SyntaxTokenExtensions.IsKind(node.OperatorToken, CS.SyntaxKind.PlusEqualsToken)) {
return SyntaxFactory.AddHandlerStatement((ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor), (ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor));
}
if (SyntaxTokenExtensions.IsKind(node.OperatorToken, CS.SyntaxKind.MinusEqualsToken)) {
return SyntaxFactory.RemoveHandlerStatement((ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor), (ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor));
}
}
return MakeAssignmentStatement(node);
}
if (node.Parent is CSS.ForStatementSyntax) {
return MakeAssignmentStatement(node);
}
if (node.Parent is CSS.InitializerExpressionSyntax) {
if (node.Left is CSS.ImplicitElementAccessSyntax) {
return SyntaxFactory.CollectionInitializer(
SyntaxFactory.SeparatedList(new[] {
(ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor),
(ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor)
})
);
} else {
return SyntaxFactory.NamedFieldInitializer(
(IdentifierNameSyntax)node.Left.Accept(TriviaConvertingVisitor),
(ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor)
);
}
}

_cSharpHelperMethodDefinition.AddInlineAssignMethod = true;
return SyntaxFactory.InvocationExpression(
SyntaxFactory.IdentifierName(CSharpHelperMethodDefinition.QualifiedInlineAssignMethodName),
SyntaxFactory.ArgumentList(
SyntaxFactory.SeparatedList(
new ArgumentSyntax[] {
SyntaxFactory.SimpleArgument((ExpressionSyntax)node.Left.Accept(TriviaConvertingVisitor)),
SyntaxFactory.SimpleArgument((ExpressionSyntax)node.Right.Accept(TriviaConvertingVisitor))
}
)
)
);
}

private static bool IsReturnValueDiscarded(CSS.ExpressionSyntax node)
{
return node.Parent is CSS.ExpressionStatementSyntax
Expand Down
13 changes: 7 additions & 6 deletions Tests/VB/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ End Sub
End Class");
}

[Fact(Skip = "https://github.com/icsharpcode/CodeConverter/issues/63")]
public void IfIsExpression()
[Fact]
public void IfIsPatternExpression()
{
TestConversionCSharpToVisualBasic(@"class TestClass
{
Expand All @@ -53,10 +53,11 @@ private static int GetLength(object node)
return -1;
}
}", @"Class TestClass
Private Shared Function GetLength(node As Object) As Integer
Dim s As String
If (CSharpImpl.__Assign(s, TryCast(node, String)) IsNot Nothing) Then
Return s.Length
Private Shared Function GetLength(ByVal node As Object) As Integer
Dim s As String = Nothing
If CSharpImpl.__Assign(s, TryCast(node, String)) IsNot Nothing Then
Return s.Length
End If
Return -1
Expand Down

0 comments on commit a288747

Please sign in to comment.