Skip to content

Commit 32b43ae

Browse files
Merge pull request #276 from mrmonday/258-vb-to-cs-fix-casing
Automatically fix the casing of identifiers where possible
2 parents 0e69b67 + e171af5 commit 32b43ae

5 files changed

Lines changed: 45 additions & 12 deletions

File tree

ICSharpCode.CodeConverter/CSharp/CommonConversions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ private string ConvertNumericLiteralValueText(string textForUser, object value)
274274
return value.ToString();
275275
}
276276

277-
public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false)
277+
public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false, bool updateCase = false)
278278
{
279279
string text = id.ValueText;
280280

@@ -285,6 +285,10 @@ public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false)
285285
if (id.SyntaxTree == _semanticModel.SyntaxTree) {
286286
var symbol = _semanticModel.GetSymbolInfo(id.Parent).Symbol;
287287
if (symbol != null && !string.IsNullOrWhiteSpace(symbol.Name)) {
288+
if (updateCase && text.Equals(symbol.Name, StringComparison.OrdinalIgnoreCase)) {
289+
text = symbol.Name;
290+
}
291+
288292
if (symbol.IsConstructor() && isAttribute) {
289293
text = symbol.ContainingType.Name;
290294
if (text.EndsWith("Attribute", StringComparison.OrdinalIgnoreCase))

ICSharpCode.CodeConverter/CSharp/NodesVisitor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,9 +1298,9 @@ public override CSharpSyntaxNode VisitQueryExpression(VBSyntax.QueryExpressionSy
12981298
return _queryConverter.ConvertClauses(node.Clauses);
12991299
}
13001300

1301-
private SyntaxToken ConvertIdentifier(SyntaxToken identifierIdentifier, bool isAttribute = false)
1301+
private SyntaxToken ConvertIdentifier(SyntaxToken identifierIdentifier, bool isAttribute = false, bool updateCase = false)
13021302
{
1303-
return CommonConversions.ConvertIdentifier(identifierIdentifier, isAttribute);
1303+
return CommonConversions.ConvertIdentifier(identifierIdentifier, isAttribute, updateCase);
13041304
}
13051305

13061306
public override CSharpSyntaxNode VisitOrdering(VBSyntax.OrderingSyntax node)
@@ -1630,7 +1630,7 @@ public override CSharpSyntaxNode VisitTypeConstraint(VBSyntax.TypeConstraintSynt
16301630

16311631
public override CSharpSyntaxNode VisitIdentifierName(VBSyntax.IdentifierNameSyntax node)
16321632
{
1633-
var identifier = SyntaxFactory.IdentifierName(ConvertIdentifier(node.Identifier, node.GetAncestor<VBSyntax.AttributeSyntax>() != null));
1633+
var identifier = SyntaxFactory.IdentifierName(ConvertIdentifier(node.Identifier, node.GetAncestor<VBSyntax.AttributeSyntax>() != null, updateCase: true));
16341634

16351635
return !node.Parent.IsKind(VBasic.SyntaxKind.SimpleMemberAccessExpression, VBasic.SyntaxKind.QualifiedName, VBasic.SyntaxKind.NameColonEquals, VBasic.SyntaxKind.ImportsStatement, VBasic.SyntaxKind.NamespaceStatement, VBasic.SyntaxKind.NamedFieldInitializer)
16361636
|| node.Parent is VBSyntax.MemberAccessExpressionSyntax maes && maes.Expression == node

TestData/VBToCSCharacterization/ConvertSolution/WindowsAppVb/My Project/Application.Designer.cs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tests/CSharp/ExpressionTests.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,33 @@ End Sub
11041104
{
11051105
}
11061106
}");
1107-
}
1108-
}
1109-
}
1107+
}
1108+
1109+
[Fact]
1110+
public void MemberAccessCasing()
1111+
{
1112+
TestConversionVisualBasicToCSharpWithoutComments(@"Public Class Class1
1113+
Sub Bar()
1114+
1115+
End Sub
1116+
1117+
Sub Foo()
1118+
bar()
1119+
me.bar()
1120+
End Sub
1121+
End Class", @"public class Class1
1122+
{
1123+
public void Bar()
1124+
{
1125+
}
1126+
1127+
public void Foo()
1128+
{
1129+
Bar();
1130+
this.Bar();
1131+
}
1132+
}");
1133+
}
1134+
1135+
}
1136+
}

Tests/CSharp/StatementTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -624,20 +624,22 @@ public void DeclareStatement(string vbMethodDecl,string vbType, string csType)
624624
{
625625
// Intentionally uses a type name with a different casing as the loop variable, i.e. "process" to test name resolution
626626
TestConversionVisualBasicToCSharp($@"Imports System.Diagnostics
627+
Imports System.Threading
627628
628629
Public Class AcmeClass
629630
Private Declare {vbMethodDecl} SetForegroundWindow Lib ""user32"" (ByVal hwnd As Int32){vbType}
630631
631632
Public Shared Sub Main()
632-
For Each process In Process.GetProcesses().Where(Function(p) Not String.IsNullOrEmpty(p.MainWindowTitle))
633-
SetForegroundWindow(process.MainWindowHandle.ToInt32())
633+
For Each proc In Process.GetProcesses().Where(Function(p) Not String.IsNullOrEmpty(p.MainWindowTitle))
634+
SetForegroundWindow(proc.MainWindowHandle.ToInt32())
634635
Thread.Sleep(1000)
635636
Next
636637
End Sub
637638
End Class"
638639
, $@"using System;
639640
using System.Diagnostics;
640641
using System.Linq;
642+
using System.Threading;
641643
642644
public class AcmeClass
643645
{{
@@ -646,9 +648,9 @@ public class AcmeClass
646648
647649
public static void Main()
648650
{{
649-
foreach (var process in Process.GetProcesses().Where(p => !string.IsNullOrEmpty(p.MainWindowTitle)))
651+
foreach (var proc in Process.GetProcesses().Where(p => !string.IsNullOrEmpty(p.MainWindowTitle)))
650652
{{
651-
SetForegroundWindow(process.MainWindowHandle.ToInt32());
653+
SetForegroundWindow(proc.MainWindowHandle.ToInt32());
652654
Thread.Sleep(1000);
653655
}}
654656
}}

0 commit comments

Comments
 (0)