diff --git a/CHANGELOG.md b/CHANGELOG.md index 886ab35b8..08951fe22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * Don't generate unnecessary properties for WithEvents fields [#572](https://github.com/icsharpcode/CodeConverter/issues/572) * Add type conversion where needed for externally declared loop control variable [#609](https://github.com/icsharpcode/CodeConverter/issues/609) * Convert string operators in common cases [#608](https://github.com/icsharpcode/CodeConverter/issues/608) +* Type convert parameterized property in assignment [#610](https://github.com/icsharpcode/CodeConverter/issues/610) ### C# -> VB diff --git a/CodeConverter/CSharp/CommonConversions.cs b/CodeConverter/CSharp/CommonConversions.cs index 06665c073..d04472b6f 100644 --- a/CodeConverter/CSharp/CommonConversions.cs +++ b/CodeConverter/CSharp/CommonConversions.cs @@ -548,7 +548,7 @@ public static CSSyntax.VariableDeclaratorSyntax CreateVariableDeclarator(string !VBasic.VisualBasicExtensions.IsDefault(pro.Property)) { var isSetter = pro.Parent.Kind == OperationKind.SimpleAssignment && pro.Parent.Children.First() == pro; var extraArg = isSetter - ? await operation.Parent.Syntax.ChildNodes().ElementAt(1).AcceptAsync(TriviaConvertingExpressionVisitor) + ? await GetParameterizedSetterArgAsync(operation) : null; return (isSetter ? pro.Property.SetMethod.Name : pro.Property.GetMethod.Name, extraArg); } @@ -556,6 +556,13 @@ public static CSSyntax.VariableDeclaratorSyntax CreateVariableDeclarator(string return (null, null); } + private async Task GetParameterizedSetterArgAsync(IOperation operation) + { + var vbNode = (VBSyntax.ExpressionSyntax) operation.Parent.Syntax.ChildNodes().ElementAt(1); + var csNode = await vbNode.AcceptAsync(TriviaConvertingExpressionVisitor); + return TypeConversionAnalyzer.AddExplicitConversion(vbNode, csNode, forceTargetType: operation.Type); + } + public CSSyntax.IdentifierNameSyntax GetRetVariableNameOrNull(VBSyntax.MethodBlockBaseSyntax node) { if (!node.MustReturn()) return null; diff --git a/CodeConverter/CSharp/LiteralConversions.cs b/CodeConverter/CSharp/LiteralConversions.cs index 391c65e65..366080602 100644 --- a/CodeConverter/CSharp/LiteralConversions.cs +++ b/CodeConverter/CSharp/LiteralConversions.cs @@ -49,9 +49,14 @@ public static ExpressionSyntax GetLiteralExpression(object value, string textFor case ulong ul: return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, ul)); case double d: - // The value is passed as a double from VB expression: "3.5F" + // The value is passed as a double from VB expression: "3.5F" and "3.5M" // Important to use value text, otherwise "10.0" gets coerced to and integer literal of 10 which can change semantics - var syntaxToken = convertedType?.SpecialType == SpecialType.System_Single ? SyntaxFactory.Literal(textForUser, (float) d) : SyntaxFactory.Literal(textForUser, d); + var syntaxToken = convertedType?.SpecialType switch + { + SpecialType.System_Single => SyntaxFactory.Literal(textForUser, (float)d), + SpecialType.System_Decimal => SyntaxFactory.Literal(textForUser, (decimal)d), + _ => SyntaxFactory.Literal(textForUser, d) + }; return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, syntaxToken); case float f: return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, f)); diff --git a/Tests/CSharp/MemberTests/PropertyMemberTests.cs b/Tests/CSharp/MemberTests/PropertyMemberTests.cs index ffc6f77b0..fce8db9b8 100644 --- a/Tests/CSharp/MemberTests/PropertyMemberTests.cs +++ b/Tests/CSharp/MemberTests/PropertyMemberTests.cs @@ -128,6 +128,44 @@ public override string ToString() }", hasLineCommentConversionIssue: true);//TODO: Improve comment mapping for parameterized property } + [Fact] + public async Task TestParameterizedPropertyRequiringConversionAsync() + { + await TestConversionVisualBasicToCSharpAsync( +@"Public Class Class1 + Public Property SomeProp(ByVal index As Integer) As Single + Get + Return 1.5 + End Get + Set(ByVal Value As Single) + End Set + End Property + + Public Sub Foo() + Dim someDecimal As Decimal = 123.0 + SomeProp(123) = someDecimal + End Sub +End Class", @"using Microsoft.VisualBasic.CompilerServices; // Install-Package Microsoft.VisualBasic + +public partial class Class1 +{ + public float get_SomeProp(int index) + { + return 1.5F; + } + + public void set_SomeProp(int index, float value) + { + } + + public void Foo() + { + decimal someDecimal = 123.0M; + set_SomeProp(123, Conversions.ToSingle(someDecimal)); + } +}", hasLineCommentConversionIssue: true);//TODO: Improve comment mapping for parameterized property + } + [Fact] public async Task TestOptionalParameterizedPropertyAsync() {