CodeConverter icon indicating copy to clipboard operation
CodeConverter copied to clipboard

C# -> VB: Declaration patterns don't convert

Open RussellSmith2 opened this issue 6 years ago • 2 comments

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.

RussellSmith2 avatar Dec 30 '18 02:12 RussellSmith2

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

RussellSmith2 avatar Jan 13 '20 03:01 RussellSmith2

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.

GrahamTheCoder avatar Jun 28 '20 10:06 GrahamTheCoder