Skip to content

Commit

Permalink
Merge pull request #1031 from TymurGubayev/TymurGubayev-patch-1
Browse files Browse the repository at this point in the history
Fix `VisualBasic.Chr` method recognition
  • Loading branch information
GrahamTheCoder authored Sep 20, 2023
2 parents 2668565 + 9ebcb26 commit 45e0128
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 4 deletions.
13 changes: 9 additions & 4 deletions CodeConverter/CSharp/ExpressionNodeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1904,10 +1904,10 @@ private ArgumentListSyntax CreateArgList(ISymbol invocationSymbol)
private async Task<CSharpSyntaxNode> SubstituteVisualBasicMethodOrNullAsync(VBSyntax.InvocationExpressionSyntax node, ISymbol symbol)
{
ExpressionSyntax cSharpSyntaxNode = null;
if (symbol?.ContainingNamespace.MetadataName == nameof(Microsoft.VisualBasic) && symbol.Name == "ChrW" || symbol?.Name == "Chr") {
if (IsVisualBasicChrMethod(symbol)) {
var vbArg = node.ArgumentList.Arguments.Single().GetExpression();
var constValue = _semanticModel.GetConstantValue(vbArg);
if (IsCultureInvariant(symbol, constValue)) {
if (IsCultureInvariant(constValue)) {
var csArg = await vbArg.AcceptAsync<ExpressionSyntax>(TriviaConvertingExpressionVisitor);
cSharpSyntaxNode = CommonConversions.TypeConversionAnalyzer.AddExplicitConversion(node, csArg, true, true, true, forceTargetType: _semanticModel.GetTypeInfo(node).Type);
}
Expand All @@ -1928,11 +1928,16 @@ private static bool RequiresStringCompareMethodToBeAppended(ISymbol symbol) =>
symbol.ContainingType.ContainingNamespace.ContainingNamespace.Name == nameof(Microsoft) &&
symbol.Name is "InStr" or "InStrRev" or "Replace" or "Split" or "StrComp";

private static bool IsVisualBasicChrMethod(ISymbol symbol) =>
symbol is not null
&& symbol.ContainingNamespace.MetadataName == nameof(Microsoft.VisualBasic)
&& (symbol.Name == "ChrW" || symbol.Name == "Chr");

/// <summary>
/// https://github.com/icsharpcode/CodeConverter/issues/745
/// </summary>
private static bool IsCultureInvariant(ISymbol symbol, Optional<object> constValue) =>
(symbol.Name == "ChrW" || symbol.Name == "Chr") && constValue.HasValue && Convert.ToUInt64(constValue.Value, CultureInfo.InvariantCulture) <= 127;
private static bool IsCultureInvariant(Optional<object> constValue) =>
constValue.HasValue && Convert.ToUInt64(constValue.Value, CultureInfo.InvariantCulture) <= 127;

private CSharpSyntaxNode AddEmptyArgumentListIfImplicit(SyntaxNode node, ExpressionSyntax id)
{
Expand Down
67 changes: 67 additions & 0 deletions Tests/CSharp/SpecialConversionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,73 @@ public void Test(byte b)
}");
}

[Fact]
public async Task TestNonVisualBasicChrMethodConversionsAsync()
{
await TestConversionVisualBasicToCSharpAsync(@"
Class TestConversions
Sub Test()
Dim a As String
a = Chr(2)
a = Me.Chr(2)
a = Strings.Chr(2)
a = Microsoft.VisualBasic.Strings.Chr(2)
a = Microsoft.VisualBasic.Chr(2)
End Sub
Sub TestW()
Dim a As String
a = ChrW(2)
a = Me.ChrW(2)
a = Strings.ChrW(2)
a = Microsoft.VisualBasic.Strings.ChrW(2)
a = Microsoft.VisualBasic.ChrW(2)
End Sub
Function Chr(o As Object) As Char
Return Microsoft.VisualBasic.Chr(o)
End Function
Function ChrW(o As Object) As Char
Return Microsoft.VisualBasic.ChrW(o)
End Function
End Class", @"using Microsoft.VisualBasic; // Install-Package Microsoft.VisualBasic
using Microsoft.VisualBasic.CompilerServices; // Install-Package Microsoft.VisualBasic
internal partial class TestConversions
{
public void Test()
{
string a;
a = Conversions.ToString(Chr(2));
a = Conversions.ToString(Chr(2));
a = Conversions.ToString('\u0002');
a = Conversions.ToString('\u0002');
a = Conversions.ToString('\u0002');
}
public void TestW()
{
string a;
a = Conversions.ToString(ChrW(2));
a = Conversions.ToString(ChrW(2));
a = Conversions.ToString('\u0002');
a = Conversions.ToString('\u0002');
a = Conversions.ToString('\u0002');
}
public char Chr(object o)
{
return Strings.Chr(Conversions.ToInteger(o));
}
public char ChrW(object o)
{
return Strings.ChrW(Conversions.ToInteger(o));
}
}");
}

[Fact]
public async Task UsingBoolInToExpressionAsync()
{
Expand Down

0 comments on commit 45e0128

Please sign in to comment.