CodeConverter
CodeConverter copied to clipboard
C# -> VB: Declaration patterns don't convert
Input code
using System;
namespace ICSharpCode.CodeConverter.Util
{
static partial class ObjectExtensions
{
public static TResult TypeSwitch<TBaseType, TDerivedType1, TResult>(this TBaseType obj, Func<TDerivedType1, TResult> matchFunc1, Func<TBaseType, TResult> defaultFunc = null) where TDerivedType1 : TBaseType
{
switch (obj) {
case TDerivedType1 tObj:
return matchFunc1(tObj);
case TBaseType tObj when (defaultFunc != null):
return defaultFunc(tObj);
default:
return default(TResult);
}
}
}
}
Erroneous output
Imports System
Imports System.Runtime.CompilerServices
Namespace ICSharpCode.CodeConverter.Util
Friend Partial Module ObjectExtensions
<Extension()>
Function TypeSwitch(Of TBaseType, TDerivedType1 As TBaseType, TResult)(ByVal obj As TBaseType, ByVal matchFunc1 As Func(Of TDerivedType1, TResult), ByVal Optional defaultFunc As Func(Of TBaseType, TResult) = Nothing) As TResult
Select Case obj
Case
Return matchFunc1(tObj)
Case
Return defaultFunc(tObj)
Case Else
Return Nothing
End Select
End Function
End Module
End Namespace
Details
Product in use: web converter Version in use: 6.2.0.0
Right now it looks like this should convert to if else statements, though it looks like this feature may get added to VB.net in the future.
The VB variable declaration gets generated twice when a Declaration Pattern is inside a Local Declaration Statement.
Input code
public async Task<IEnumerable<ExpressionSyntax>> ConvertArrayBounds(ArgumentListSyntax argumentListSyntax)
{
return await argumentListSyntax.Arguments.SelectAsync(a => {
VBSyntax.ExpressionSyntax upperBoundExpression = a is SimpleArgumentSyntax sas ? sas.Expression
: a is RangeArgumentSyntax ras ? ras.UpperBound
: throw new ArgumentOutOfRangeException(nameof(a), a, null);
return IncreaseArrayUpperBoundExpression(upperBoundExpression);
});
}
Erroneous output
Public Async Function ConvertArrayBounds(ByVal argumentListSyntax As ArgumentListSyntax) As Task(Of IEnumerable(Of ExpressionSyntax))
Dim sas As SimpleArgumentSyntax = Nothing, ras As RangeArgumentSyntax = Nothing
Return Await argumentListSyntax.Arguments.SelectAsync(Function(a)
Dim sas As SimpleArgumentSyntax = Nothing, ras As RangeArgumentSyntax = Nothing
Dim upperBoundExpression As VBSyntax.ExpressionSyntax = If(CSharpImpl.__Assign(sas, TryCast(a, SimpleArgumentSyntax)) IsNot Nothing, sas.Expression, If(CSharpImpl.__Assign(ras, TryCast(a, RangeArgumentSyntax)) IsNot Nothing, ras.UpperBound, CSharpImpl.__Throw(Of)(New ArgumentOutOfRangeException(NameOf(a), a, Nothing))))
Return IncreaseArrayUpperBoundExpression(upperBoundExpression)
End Function)
End Function
Expected output
Public Async Function ConvertArrayBounds(ByVal argumentListSyntax As ArgumentListSyntax) As Task(Of IEnumerable(Of ExpressionSyntax))
Return Await argumentListSyntax.Arguments.SelectAsync(Function(a)
Dim sas As SimpleArgumentSyntax = Nothing, ras As RangeArgumentSyntax = Nothing
Dim upperBoundExpression As VBSyntax.ExpressionSyntax = If(CSharpImpl.__Assign(sas, TryCast(a, SimpleArgumentSyntax)) IsNot Nothing, sas.Expression, If(CSharpImpl.__Assign(ras, TryCast(a, RangeArgumentSyntax)) IsNot Nothing, ras.UpperBound, CSharpImpl.__Throw(Of)(New ArgumentOutOfRangeException(NameOf(a), a, Nothing))))
Return IncreaseArrayUpperBoundExpression(upperBoundExpression)
End Function)
End Function
Details
- Version in use: Current compiled repo
It looks like all future VB development will "focus on stability", so VB probably isn't getting the improved select case feature. Therefore I think we'll have to transform to an if-else chain as you mentioned.
So probably best to fix the double-declaration bug, then write the code to generally transform select to a switch, and activate it when a declaration pattern appears in the case expression.