Skip to content

Commit b0fda82

Browse files
committed
Merge branch 'work'
# Conflicts: # ICSharpCode.CodeConverter/VB/NodesVisitor.cs # Tests/VB/TypeCastTests.cs
2 parents 0301eb0 + b16181e commit b0fda82

7 files changed

Lines changed: 93 additions & 55 deletions

File tree

ICSharpCode.CodeConverter/VB/CommonConversions.cs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -409,24 +409,21 @@ public void ConvertBaseList(CSS.BaseTypeDeclarationSyntax type, List<InheritsSta
409409
}
410410

411411

412-
private static IEnumerable<SyntaxToken> ConvertModifiersCore(IReadOnlyCollection<SyntaxToken> modifiers,
413-
TokenContext context, bool isConstructor)
414-
{
415-
if (context != TokenContext.Local && context != TokenContext.MemberInInterface && context != TokenContext.MemberInProperty) {
416-
bool visibility = false;
417-
foreach (var token in modifiers) {
418-
if (token.IsCsVisibility(true, isConstructor)) { //TODO Don't always treat as variable or const, pass in more context to detect this
419-
visibility = true;
420-
break;
421-
}
422-
}
423-
if (!visibility)
424-
yield return CSharpDefaultVisibility(context);
425-
}
426-
foreach (var token in modifiers.Where(m => !IgnoreInContext(m, context))) {
427-
var m = ConvertModifier(token, context);
428-
if (m.HasValue) yield return m.Value;
429-
}
412+
private static IEnumerable<SyntaxToken> ConvertModifiersCore(IReadOnlyCollection<SyntaxToken> modifiers, TokenContext context, bool isConstructor) {
413+
var needsExplicitVisibility = !(modifiers.Any(x => x.IsKind(CS.SyntaxKind.PartialKeyword)) && context == TokenContext.Global)
414+
&& context != TokenContext.Local
415+
&& context != TokenContext.MemberInInterface
416+
&& context != TokenContext.MemberInProperty
417+
&& !modifiers.Any(x => x.IsCsVisibility(true, isConstructor)); //TODO Don't always treat as variable or const, pass in more context to detect this
418+
var vbModifiers = modifiers
419+
.Where(m => !IgnoreInContext(m, context))
420+
.Select(x => ConvertModifier(x, context))
421+
.Where(x => x.HasValue)
422+
.Select(x => x.Value)
423+
.ToList();
424+
if(needsExplicitVisibility)
425+
vbModifiers.Insert(vbModifiers.FirstOrDefault().IsKind(SyntaxKind.PartialKeyword) ? 1 : 0, CSharpDefaultVisibility(context));
426+
return vbModifiers;
430427
}
431428

432429
private static bool IgnoreInContext(SyntaxToken m, TokenContext context)
@@ -576,22 +573,21 @@ private static bool KeywordRequiresEscaping(SyntaxToken id)
576573
}
577574

578575

579-
public static ExpressionSyntax Literal(object o, string valueText = null) => GetLiteralExpression(o, valueText);
576+
public ExpressionSyntax Literal(object o, string valueText = null) => GetLiteralExpression(o, valueText, VbSyntaxGenerator);
580577

581-
internal static ExpressionSyntax GetLiteralExpression(object value, string valueText = null)
578+
internal static ExpressionSyntax GetLiteralExpression(object value, string valueText, SyntaxGenerator generator)
582579
{
583580
if (value is char)
584-
return SyntaxFactory.LiteralExpression(SyntaxKind.CharacterLiteralExpression, SyntaxFactory.Literal((char)value));
581+
return (ExpressionSyntax)generator.LiteralExpression((char)value);
585582

586583
if (value is string)
587-
return SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal((string)value));
584+
return (ExpressionSyntax)generator.LiteralExpression((string)value);
588585

589586
if (value == null)
590-
return SyntaxFactory.NothingLiteralExpression(SyntaxFactory.Token(SyntaxKind.NothingKeyword));
587+
return (ExpressionSyntax)generator.NullLiteralExpression();
591588

592589
if (value is bool)
593-
return (bool)value ? SyntaxFactory.TrueLiteralExpression(SyntaxFactory.Token(SyntaxKind.TrueKeyword)) : SyntaxFactory.FalseLiteralExpression(SyntaxFactory.Token(SyntaxKind.FalseKeyword));
594-
590+
return (ExpressionSyntax)((bool)value ? generator.TrueLiteralExpression() : generator.FalseLiteralExpression());
595591

596592
valueText = valueText != null ? ConvertNumericLiteralValueText(valueText) : value.ToString();
597593

ICSharpCode.CodeConverter/VB/MethodBodyExecutableStatementVisitor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public override SyntaxList<StatementSyntax> VisitForStatement(CSS.ForStatementSy
280280
} else {
281281
var stmts = SyntaxFactory.List(convertedStatements)
282282
.AddRange(node.Incrementors.Select(ConvertSingleExpression));
283-
var condition = node.Condition == null ? CommonConversions.Literal(true) : (ExpressionSyntax)node.Condition.Accept(_nodesVisitor);
283+
var condition = node.Condition == null ? _commonConversions.Literal(true) : (ExpressionSyntax)node.Condition.Accept(_nodesVisitor);
284284
block = SyntaxFactory.WhileBlock(
285285
SyntaxFactory.WhileStatement(condition),
286286
stmts
@@ -343,13 +343,13 @@ private bool ConvertForToSimpleForNextWithoutStatements(CSS.ForStatementSyntax n
343343
if (condition.IsKind(CS.SyntaxKind.GreaterThanOrEqualExpression))
344344
end = (ExpressionSyntax)condition.Right.Accept(_nodesVisitor);
345345
else if (condition.IsKind(CS.SyntaxKind.GreaterThanExpression))
346-
end = SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, (ExpressionSyntax)condition.Right.Accept(_nodesVisitor), SyntaxFactory.Token(SyntaxKind.PlusToken), CommonConversions.Literal(1));
346+
end = SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, (ExpressionSyntax)condition.Right.Accept(_nodesVisitor), SyntaxFactory.Token(SyntaxKind.PlusToken), _commonConversions.Literal(1));
347347
else return false;
348348
} else {
349349
if (condition.IsKind(CS.SyntaxKind.LessThanOrEqualExpression))
350350
end = (ExpressionSyntax)condition.Right.Accept(_nodesVisitor);
351351
else if (condition.IsKind(CS.SyntaxKind.LessThanExpression))
352-
end = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, (ExpressionSyntax)condition.Right.Accept(_nodesVisitor), SyntaxFactory.Token(SyntaxKind.MinusToken), CommonConversions.Literal(1));
352+
end = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, (ExpressionSyntax)condition.Right.Accept(_nodesVisitor), SyntaxFactory.Token(SyntaxKind.MinusToken), _commonConversions.Literal(1));
353353
else return false;
354354
}
355355

@@ -378,7 +378,7 @@ private bool ConvertForToSimpleForNextWithoutStatements(CSS.ForStatementSyntax n
378378
}
379379

380380
blockWithoutStatements = SyntaxFactory.ForBlock(
381-
SyntaxFactory.ForStatement(variable, start, end, step == 1 ? null : SyntaxFactory.ForStepClause(CommonConversions.Literal(step))),
381+
SyntaxFactory.ForStatement(variable, start, end, step == 1 ? null : SyntaxFactory.ForStepClause(_commonConversions.Literal(step))),
382382
SyntaxFactory.List<StatementSyntax>(),
383383
SyntaxFactory.NextStatement()
384384
);

ICSharpCode.CodeConverter/VB/NodesVisitor.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ public override VisualBasicSyntaxNode VisitDestructorDeclaration(CSS.DestructorD
414414
public override VisualBasicSyntaxNode VisitMethodDeclaration(CSS.MethodDeclarationSyntax node)
415415
{
416416
var isIteratorState = new MethodBodyExecutableStatementVisitor(_semanticModel, TriviaConvertingVisitor, _commonConversions);
417-
bool requiresBody = node.Body != null || node.ExpressionBody != null || node.Modifiers.Any(m => SyntaxTokenExtensions.IsKind(m, CS.SyntaxKind.ExternKeyword));
417+
bool requiresBody = node.Body != null || node.ExpressionBody != null || node.Modifiers.Any(m => SyntaxTokenExtensions.IsKind(m, CS.SyntaxKind.ExternKeyword, CS.SyntaxKind.PartialKeyword));
418418
var block = _commonConversions.ConvertBody(node.Body, node.ExpressionBody, isIteratorState);
419419
var id = _commonConversions.ConvertIdentifier(node.Identifier);
420420
var attributes = SyntaxFactory.List(node.AttributeLists.Select(a => (AttributeListSyntax)a.Accept(TriviaConvertingVisitor)));
@@ -829,7 +829,7 @@ public override VisualBasicSyntaxNode VisitLiteralExpression(CSS.LiteralExpressi
829829
)
830830
);
831831
} else {
832-
return CommonConversions.Literal(node.Token.Value, node.Token.Text);
832+
return _commonConversions.Literal(node.Token.Value, node.Token.Text);
833833
}
834834
}
835835

@@ -898,7 +898,7 @@ public override VisualBasicSyntaxNode VisitPrefixUnaryExpression(CSS.PrefixUnary
898898
return SyntaxFactory.AssignmentStatement(
899899
kind,
900900
(ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor),
901-
SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(kind)), CommonConversions.Literal(1)
901+
SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(kind)), _commonConversions.Literal(1)
902902
);
903903
}
904904
if (kind == SyntaxKind.AddAssignmentStatement || kind == SyntaxKind.SubtractAssignmentStatement) {
@@ -908,12 +908,15 @@ public override VisualBasicSyntaxNode VisitPrefixUnaryExpression(CSS.PrefixUnary
908908
else
909909
operatorName = "Decrement";
910910
return SyntaxFactory.InvocationExpression(
911-
SyntaxFactory.ParseName(nameof(System) + "." + nameof(System.Threading) + "." + nameof(System.Threading.Interlocked) + "." + operatorName),
911+
SyntaxFactory.ParseName(GetQualifiedName(nameof(System), nameof(System.Threading), nameof(System.Threading.Interlocked), operatorName)),
912912
ExpressionSyntaxExtensions.CreateArgList((ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor))
913913
);
914914
}
915915
return SyntaxFactory.UnaryExpression(kind, SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(kind)), (ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor));
916916
}
917+
private static string GetQualifiedName(params string[] names) {
918+
return names.Aggregate((seed, current) => seed + '.' + current);
919+
}
917920

918921
public override VisualBasicSyntaxNode VisitAssignmentExpression(CSS.AssignmentExpressionSyntax node)
919922
{
@@ -986,7 +989,7 @@ public override VisualBasicSyntaxNode VisitPostfixUnaryExpression(CSS.PostfixUna
986989
if (IsReturnValueDiscarded(node)) {
987990
return SyntaxFactory.AssignmentStatement(CS.CSharpExtensions.Kind(node).ConvertToken(TokenContext.Local),
988991
(ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor),
989-
SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(kind)), CommonConversions.Literal(1)
992+
SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(kind)), _commonConversions.Literal(1)
990993
);
991994
} else {
992995
string operatorName, minMax;
@@ -1001,13 +1004,13 @@ public override VisualBasicSyntaxNode VisitPostfixUnaryExpression(CSS.PostfixUna
10011004
op = SyntaxKind.AddExpression;
10021005
}
10031006
return SyntaxFactory.InvocationExpression(
1004-
SyntaxFactory.ParseName(nameof(Math) + "." + minMax),
1007+
SyntaxFactory.ParseName(GetQualifiedName(nameof(System), nameof(Math), minMax)),
10051008
new ExpressionSyntax[] {
10061009
SyntaxFactory.InvocationExpression(
1007-
SyntaxFactory.ParseName("System.Threading.Interlocked." + operatorName),
1010+
SyntaxFactory.ParseName(GetQualifiedName(nameof(System), nameof(System.Threading), nameof(System.Threading.Interlocked), operatorName)),
10081011
ExpressionSyntaxExtensions.CreateArgList((ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor))
10091012
),
1010-
SyntaxFactory.BinaryExpression(op, (ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor), SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(op)), CommonConversions.Literal(1))
1013+
SyntaxFactory.BinaryExpression(op, (ExpressionSyntax)node.Operand.Accept(TriviaConvertingVisitor), SyntaxFactory.Token(VBUtil.GetExpressionOperatorTokenKind(op)), _commonConversions.Literal(1))
10111014
}.CreateArgList()
10121015
);
10131016
}
@@ -1245,7 +1248,7 @@ public override VisualBasicSyntaxNode VisitCastExpression(CSS.CastExpressionSynt
12451248
var expr = (ExpressionSyntax)node.Expression.Accept(TriviaConvertingVisitor);
12461249
Func<SyntaxKind, VisualBasicSyntaxNode> toNumber = kind => {
12471250
if (sourceType?.SpecialType == SpecialType.System_Char)
1248-
return SyntaxFactory.InvocationExpression(SyntaxFactory.ParseName(nameof(Strings.AscW)), ExpressionSyntaxExtensions.CreateArgList(expr));
1251+
return SyntaxFactory.InvocationExpression(SyntaxFactory.ParseName(GetQualifiedName(nameof(Microsoft), nameof(Microsoft.VisualBasic), nameof(Microsoft.VisualBasic.Strings.AscW))), ExpressionSyntaxExtensions.CreateArgList(expr));
12491252
return SyntaxFactory.PredefinedCastExpression(SyntaxFactory.Token(kind), expr);
12501253
};
12511254
switch (destType.SpecialType) {
@@ -1255,7 +1258,7 @@ public override VisualBasicSyntaxNode VisitCastExpression(CSS.CastExpressionSynt
12551258
return SyntaxFactory.PredefinedCastExpression(SyntaxFactory.Token(SyntaxKind.CBoolKeyword), expr);
12561259
case SpecialType.System_Char:
12571260
return sourceType?.IsNumericType() == true
1258-
? (VisualBasicSyntaxNode)SyntaxFactory.InvocationExpression(SyntaxFactory.ParseName(nameof(Strings.ChrW)), ExpressionSyntaxExtensions.CreateArgList(expr))
1261+
? (VisualBasicSyntaxNode)SyntaxFactory.InvocationExpression(SyntaxFactory.ParseName(GetQualifiedName(nameof(Microsoft), nameof(Microsoft.VisualBasic), nameof(Microsoft.VisualBasic.Strings.ChrW))), ExpressionSyntaxExtensions.CreateArgList(expr))
12591262
: SyntaxFactory.PredefinedCastExpression(SyntaxFactory.Token(SyntaxKind.CCharKeyword), expr);
12601263
case SpecialType.System_SByte:
12611264
return toNumber(SyntaxKind.CSByteKeyword);

Tests/VB/MemberTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,5 +1291,17 @@ await TestConversionCSharpToVisualBasic(
12911291
WriteOnly Property Parameters As IEnumerable(Of Object)
12921292
End Interface");
12931293
}
1294+
[Fact]
1295+
public async Task PartialMethod() {
1296+
await TestConversionCSharpToVisualBasic(
1297+
@"public partial class Entities {
1298+
partial void OnContextCreated();
1299+
}",
1300+
@"Public Partial Class Entities
1301+
Partial Private Sub OnContextCreated()
1302+
End Sub
1303+
End Class");
1304+
}
1305+
12941306
}
12951307
}

Tests/VB/NamespaceLevelTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,5 +537,18 @@ Implements System.ComponentModel.INotifyPropertyChanged
537537
Public Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
538538
End Class", conversion: EmptyNamespaceOptionStrictOff);
539539
}
540+
[Fact]
541+
public async Task PartialClass_OmitedModifier() {
542+
await TestConversionCSharpToVisualBasic(
543+
@"public partial class Entities {
544+
}
545+
partial class Entities {
546+
}",
547+
@"Public Partial Class Entities
548+
End Class
549+
550+
Partial Class Entities
551+
End Class");
552+
}
540553
}
541554
}

Tests/VB/SpecialConversionTests.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ End Class
3838
public async Task TestSimplePostIncrementAssign()
3939
{
4040
await TestConversionCSharpToVisualBasic(
41-
@"class TestClass
42-
{
41+
@"class TestClass{
4342
void TestMethod()
4443
{
4544
int a = 5, b;
4645
b = a++;
4746
}
48-
}", @"Friend Class TestClass
47+
}",
48+
@"Friend Class TestClass
4949
Private Sub TestMethod()
5050
Dim b As Integer, a As Integer = 5
51-
b = Math.Min(Threading.Interlocked.Increment(a), a - 1)
51+
b = System.Math.Min(System.Threading.Interlocked.Increment(a), a - 1)
5252
End Sub
53-
End Class");
53+
End Class", conversion: EmptyNamespaceOptionStrictOff);
5454
}
5555

5656
[Fact]
@@ -539,5 +539,21 @@ End Property
539539
End Class
540540
End Namespace");
541541
}
542+
[Fact]
543+
public async Task ConstantsShouldBeQualified() {
544+
await TestConversionCSharpToVisualBasic(
545+
@"public class TestClass {
546+
public void Method() {
547+
string vbLf = ""\n""
548+
string vbCrLf = ""\r\n"";
549+
}
550+
}",
551+
@"Public Class TestClass
552+
Public Sub Method()
553+
Dim vbLf As String = Microsoft.VisualBasic.vbLf
554+
Dim vbCrLf As String = Microsoft.VisualBasic.vbCrLf
555+
End Sub
556+
End Class", conversion: EmptyNamespaceOptionStrictOff);
557+
}
542558
}
543559
}

Tests/VB/TypeCastTests.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,26 +133,24 @@ await TestConversionCSharpToVisualBasic(
133133
public async Task CastConstantNumberToCharacter()
134134
{
135135
await TestConversionCSharpToVisualBasic(
136-
@"void Test()
137-
{
136+
@"void Test() {
138137
char CR = (char)0xD;
139-
}", @"Private Sub Test()
140-
Dim CR As Char = ChrW(&HD)
141-
End Sub");
138+
}",
139+
@"Private Sub Test()
140+
Dim CR As Char = Microsoft.VisualBasic.ChrW(&HD)
141+
End Sub", conversion: EmptyNamespaceOptionStrictOff);
142142
}
143143
[Fact]
144144
public async Task CastCharacterToNumber() {
145145
await TestConversionCSharpToVisualBasic(
146146
@"void Test() {
147147
byte a = (byte)'A';
148148
decimal b = (byte)'B';
149-
}
150-
",
149+
}",
151150
@"Private Sub Test()
152-
Dim a As Byte = AscW(""A""c)
153-
Dim b As Decimal = AscW(""B""c)
154-
End Sub
155-
");
151+
Dim a As Byte = Microsoft.VisualBasic.AscW(""A""c)
152+
Dim b As Decimal = Microsoft.VisualBasic.AscW(""B""c)
153+
End Sub", conversion: EmptyNamespaceOptionStrictOff);
156154
}
157155
[Fact(Skip = "Many code generation")]
158156
public async Task CastCharacterIncrement() {

0 commit comments

Comments
 (0)