Skip to content

Commit 71aa79c

Browse files
Merge pull request #1162 from icsharpcode/issue-1159-inferred-generic-integer-type-cast
Issue 1159 inferred generic integer type cast
2 parents 67185b0 + c5180ef commit 71aa79c

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

CodeConverter/CSharp/TypeConversionAnalyzer.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ private ExpressionSyntax AddTypeConversion(VBSyntax.ExpressionSyntax vbNode, Exp
9898
var enumUnderlyingType = ((INamedTypeSymbol) vbType).EnumUnderlyingType;
9999
csNode = AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, enumUnderlyingType);
100100
return AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, enumUnderlyingType, vbConvertedType);
101+
case TypeConversionKind.LiteralSuffix:
102+
if (csNode is CSSyntax.LiteralExpressionSyntax && vbNode is VBSyntax.LiteralExpressionSyntax { Token: { Value: { } val, Text: { } text } } && LiteralConversions.GetLiteralExpression(val, text, vbConvertedType) is { } csLiteral) {
103+
return csLiteral;
104+
}
105+
return csNode;
101106
case TypeConversionKind.Unknown:
102107
case TypeConversionKind.Identity:
103108
return addParenthesisIfNeeded ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode;
@@ -327,7 +332,7 @@ private bool TryAnalyzeCsConversion(VBasic.VisualBasicCompilation vbCompilation,
327332
// e.g. When VB "&" changes to C# "+", there are lots more overloads available that implicit casts could match.
328333
// e.g. sbyte * ulong uses the decimal * operator in VB. In C# it's ambiguous - see ExpressionTests.vb "TestMul".
329334
typeConversionKind =
330-
isConst && IsImplicitConstantConversion(vbNode) || csUnderlyingConversion.IsIdentity || !sourceForced && IsExactTypeNumericLiteral(vbNode, underlyingVbConvertedType) ? TypeConversionKind.Identity :
335+
isConst && IsImplicitConstantConversion(vbNode) || csUnderlyingConversion.IsIdentity || !sourceForced && IsExactTypeNumericLiteral(vbNode, underlyingVbConvertedType) ? TypeConversionKind.LiteralSuffix :
331336
csUnderlyingConversion.IsImplicit || underlyingVbType.IsNumericType() ? TypeConversionKind.NonDestructiveCast
332337
: TypeConversionKind.Conversion;
333338
return true;
@@ -502,7 +507,8 @@ public enum TypeConversionKind
502507
NullableBool,
503508
StringToCharArray,
504509
DelegateConstructor,
505-
FractionalNumberRoundThenCast
510+
FractionalNumberRoundThenCast,
511+
LiteralSuffix
506512
}
507513

508514
public static bool ConvertStringToCharLiteral(VBSyntax.ExpressionSyntax node,

Tests/CSharp/TypeCastTests.cs

+78
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,84 @@ private static T GenericFunctionWithCastThatExistsInCsharp<T>() where T : TestGe
15591559
}
15601560

15611561
[Fact]
1562+
public async Task TestInferringImplicitGenericTypesAsync()
1563+
{
1564+
await TestConversionVisualBasicToCSharpAsync(@"
1565+
Imports System
1566+
Imports System.Linq
1567+
1568+
Public Class TestClass
1569+
Public Sub GenerateFromConstants
1570+
Dim floatArr = Enumerable.Repeat(1.0F, 5).ToArray()
1571+
Dim doubleArr = Enumerable.Repeat(2.0, 5).ToArray()
1572+
Dim decimalArr = Enumerable.Repeat(3.0D, 5).ToArray()
1573+
Dim boolArr = Enumerable.Repeat(true, 5).ToArray()
1574+
Dim intArr = Enumerable.Repeat(1, 5).ToArray()
1575+
Dim uintArr = Enumerable.Repeat(1ui, 5).ToArray()
1576+
Dim longArr = Enumerable.Repeat(1l, 5).ToArray()
1577+
Dim ulongArr = Enumerable.Repeat(1ul, 5).ToArray()
1578+
Dim charArr = Enumerable.Repeat(""a""c, 5).ToArray()
1579+
Dim strArr = Enumerable.Repeat(""a"", 5).ToArray()
1580+
Dim objArr = Enumerable.Repeat(new object(), 5).ToArray()
1581+
End Sub
1582+
1583+
Public Sub GenerateFromCasts
1584+
Dim floatArr = Enumerable.Repeat(CSng(1), 5).ToArray()
1585+
Dim doubleArr = Enumerable.Repeat(CDbl(2), 5).ToArray()
1586+
Dim decimalArr = Enumerable.Repeat(CDec(3), 5).ToArray()
1587+
Dim boolArr = Enumerable.Repeat(CBool(1), 5).ToArray()
1588+
Dim intArr = Enumerable.Repeat(CInt(1.0), 5).ToArray()
1589+
Dim uintArr = Enumerable.Repeat(CUInt(1.0), 5).ToArray()
1590+
Dim longArr = Enumerable.Repeat(CLng(1.0), 5).ToArray()
1591+
Dim ulongArr = Enumerable.Repeat(CULng(1.0), 5).ToArray()
1592+
Dim charArr = Enumerable.Repeat(CChar(""a""), 5).ToArray()
1593+
Dim strArr = Enumerable.Repeat(CStr(""a""c), 5).ToArray()
1594+
Dim objArr1 = Enumerable.Repeat(CObj(""a""), 5).ToArray()
1595+
Dim objArr2 = Enumerable.Repeat(CType(""a"", object), 5).ToArray()
1596+
End Sub
1597+
End Class
1598+
", @"
1599+
using System;
1600+
using System.Linq;
1601+
using Microsoft.VisualBasic.CompilerServices; // Install-Package Microsoft.VisualBasic
1602+
1603+
public partial class TestClass
1604+
{
1605+
public void GenerateFromConstants()
1606+
{
1607+
float[] floatArr = Enumerable.Repeat(1.0f, 5).ToArray();
1608+
double[] doubleArr = Enumerable.Repeat(2.0d, 5).ToArray();
1609+
decimal[] decimalArr = Enumerable.Repeat(3.0m, 5).ToArray();
1610+
bool[] boolArr = Enumerable.Repeat(true, 5).ToArray();
1611+
int[] intArr = Enumerable.Repeat(1, 5).ToArray();
1612+
uint[] uintArr = Enumerable.Repeat(1U, 5).ToArray();
1613+
long[] longArr = Enumerable.Repeat(1L, 5).ToArray();
1614+
ulong[] ulongArr = Enumerable.Repeat(1UL, 5).ToArray();
1615+
char[] charArr = Enumerable.Repeat('a', 5).ToArray();
1616+
string[] strArr = Enumerable.Repeat(""a"", 5).ToArray();
1617+
object[] objArr = Enumerable.Repeat(new object(), 5).ToArray();
1618+
}
1619+
1620+
public void GenerateFromCasts()
1621+
{
1622+
float[] floatArr = Enumerable.Repeat(1f, 5).ToArray();
1623+
double[] doubleArr = Enumerable.Repeat(2d, 5).ToArray();
1624+
decimal[] decimalArr = Enumerable.Repeat(3m, 5).ToArray();
1625+
bool[] boolArr = Enumerable.Repeat(Conversions.ToBoolean(1), 5).ToArray();
1626+
int[] intArr = Enumerable.Repeat((int)Math.Round(1.0d), 5).ToArray();
1627+
uint[] uintArr = Enumerable.Repeat((uint)Math.Round(1.0d), 5).ToArray();
1628+
long[] longArr = Enumerable.Repeat((long)Math.Round(1.0d), 5).ToArray();
1629+
ulong[] ulongArr = Enumerable.Repeat((ulong)Math.Round(1.0d), 5).ToArray();
1630+
char[] charArr = Enumerable.Repeat('a', 5).ToArray();
1631+
string[] strArr = Enumerable.Repeat(""a"", 5).ToArray();
1632+
object[] objArr1 = Enumerable.Repeat((object)""a"", 5).ToArray();
1633+
object[] objArr2 = Enumerable.Repeat((object)""a"", 5).ToArray();
1634+
}
1635+
}");
1636+
}
1637+
1638+
1639+
[Fact]
15621640
public async Task TestCTypeStringToEnumAsync()
15631641
{
15641642
await TestConversionVisualBasicToCSharpAsync(

0 commit comments

Comments
 (0)