Fixes #52 - NRE for arbitrary expressions in With Block
Flip the conditional to target the elvis expression instead which is the more specific case. Basically any statement can appear inside a with block Also catch an obvious case of a missing argument list - would be good to look for more subtle ones of these
This commit is contained in:
Родитель
e422c8c7d6
Коммит
12d050f431
|
@ -853,10 +853,9 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
|
||||
var left = (ExpressionSyntax)node.Expression?.Accept(TriviaConvertingVisitor);
|
||||
if (left == null) {
|
||||
if (!node.Parent.Parent.IsKind(VBasic.SyntaxKind.WithBlock)) {
|
||||
if (IsSubPartOfConditionalAccess(node)) {
|
||||
return SyntaxFactory.MemberBindingExpression(simpleNameSyntax);
|
||||
}
|
||||
|
||||
left = SyntaxFactory.IdentifierName(withBlockTempVariableNames.Peek());
|
||||
}
|
||||
|
||||
|
@ -873,9 +872,23 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
return memberAccessExpressionSyntax;
|
||||
}
|
||||
|
||||
private static bool IsSubPartOfConditionalAccess(VBSyntax.MemberAccessExpressionSyntax node)
|
||||
{
|
||||
var firstPossiblyConditionalAncestor = node.Parent;
|
||||
while (firstPossiblyConditionalAncestor != null &&
|
||||
firstPossiblyConditionalAncestor.IsKind(VBasic.SyntaxKind.InvocationExpression,
|
||||
VBasic.SyntaxKind.SimpleMemberAccessExpression))
|
||||
{
|
||||
firstPossiblyConditionalAncestor = firstPossiblyConditionalAncestor.Parent;
|
||||
}
|
||||
|
||||
return firstPossiblyConditionalAncestor?.IsKind(VBasic.SyntaxKind.ConditionalAccessExpression) == true;
|
||||
}
|
||||
|
||||
public override CSharpSyntaxNode VisitConditionalAccessExpression(VBSyntax.ConditionalAccessExpressionSyntax node)
|
||||
{
|
||||
return SyntaxFactory.ConditionalAccessExpression((ExpressionSyntax)node.Expression.Accept(TriviaConvertingVisitor), (ExpressionSyntax)node.WhenNotNull.Accept(TriviaConvertingVisitor));
|
||||
var leftExpression = (ExpressionSyntax)node.Expression?.Accept(TriviaConvertingVisitor) ?? SyntaxFactory.IdentifierName(withBlockTempVariableNames.Peek());
|
||||
return SyntaxFactory.ConditionalAccessExpression(leftExpression, (ExpressionSyntax)node.WhenNotNull.Accept(TriviaConvertingVisitor));
|
||||
}
|
||||
|
||||
public override CSharpSyntaxNode VisitArgumentList(VBSyntax.ArgumentListSyntax node)
|
||||
|
@ -1290,7 +1303,7 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
|
||||
return SyntaxFactory.InvocationExpression(
|
||||
(ExpressionSyntax)node.Expression.Accept(TriviaConvertingVisitor),
|
||||
(ArgumentListSyntax)node.ArgumentList.Accept(TriviaConvertingVisitor)
|
||||
(ArgumentListSyntax)node.ArgumentList?.Accept(TriviaConvertingVisitor) ?? SyntaxFactory.ArgumentList()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ class TestClass
|
|||
Private Sub TestMethod()
|
||||
With New System.Text.StringBuilder
|
||||
.Capacity = 20
|
||||
.Length = 0
|
||||
?.Length = 0
|
||||
End With
|
||||
End Sub
|
||||
End Class", @"using System;
|
||||
|
@ -258,7 +258,39 @@ class TestClass
|
|||
{
|
||||
var withBlock = new System.Text.StringBuilder();
|
||||
withBlock.Capacity = 20;
|
||||
withBlock.Length = 0;
|
||||
withBlock?.Length = 0;
|
||||
}
|
||||
}
|
||||
}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WithBlock2()
|
||||
{
|
||||
TestConversionVisualBasicToCSharpWithoutComments(@"Class TestClass
|
||||
Private Sub Save()
|
||||
Using cmd As SqlCommand = new SqlCommand()
|
||||
With cmd
|
||||
.ExecuteNonQuery()
|
||||
?.ExecuteNonQuery()
|
||||
.ExecuteNonQuery
|
||||
?.ExecuteNonQuery
|
||||
End With
|
||||
End Using
|
||||
End Sub
|
||||
End Class", @"class TestClass
|
||||
{
|
||||
private void Save()
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
{
|
||||
var withBlock = cmd;
|
||||
withBlock.ExecuteNonQuery();
|
||||
withBlock?.ExecuteNonQuery();
|
||||
withBlock.ExecuteNonQuery();
|
||||
withBlock?.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}");
|
||||
|
|
Загрузка…
Ссылка в новой задаче