Skip to content

Commit ceb4706

Browse files
"Shared"/"static" as implicit visibility for constructor - fixes #215
1 parent 3b8c0c3 commit ceb4706

8 files changed

Lines changed: 55 additions & 18 deletions

File tree

ICSharpCode.CodeConverter/CSharp/CommonConversions.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,9 @@ public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false)
294294
return SyntaxFactory.Identifier(text);
295295
}
296296

297-
public SyntaxTokenList ConvertModifiers(IEnumerable<SyntaxToken> modifiers, TokenContext context = TokenContext.Global, bool isVariableOrConst = false)
297+
public SyntaxTokenList ConvertModifiers(IEnumerable<SyntaxToken> modifiers, TokenContext context = TokenContext.Global, bool isVariableOrConst = false, bool isConstructor = false)
298298
{
299-
return SyntaxFactory.TokenList(ConvertModifiersCore(modifiers, context, isVariableOrConst).Where(t => CSharpExtensions.Kind(t) != Microsoft.CodeAnalysis.CSharp.SyntaxKind.None));
299+
return SyntaxFactory.TokenList(ConvertModifiersCore(modifiers, context, isVariableOrConst, isConstructor).Where(t => CSharpExtensions.Kind(t) != Microsoft.CodeAnalysis.CSharp.SyntaxKind.None));
300300
}
301301

302302
private SyntaxToken? ConvertModifier(SyntaxToken m, TokenContext context = TokenContext.Global)
@@ -310,13 +310,14 @@ public SyntaxTokenList ConvertModifiers(IEnumerable<SyntaxToken> modifiers, Toke
310310
return token == Microsoft.CodeAnalysis.CSharp.SyntaxKind.None ? null : new SyntaxToken?(SyntaxFactory.Token(token));
311311
}
312312

313-
private IEnumerable<SyntaxToken> ConvertModifiersCore(IEnumerable<SyntaxToken> modifiers, TokenContext context, bool isVariableOrConst = false)
313+
private IEnumerable<SyntaxToken> ConvertModifiersCore(IEnumerable<SyntaxToken> modifiers, TokenContext context,
314+
bool isVariableOrConst = false, bool isConstructor = false)
314315
{
315316
var contextsWithIdenticalDefaults = new[] {TokenContext.Global, TokenContext.Local, TokenContext.InterfaceOrModule, TokenContext.MemberInInterface };
316317
if (!contextsWithIdenticalDefaults.Contains(context)) {
317318
bool visibility = false;
318319
foreach (var token in modifiers) {
319-
if (SyntaxTokenExtensions.IsVbVisibility(token, isVariableOrConst)) {
320+
if (token.IsVbVisibility(isVariableOrConst, isConstructor)) {
320321
visibility = true;
321322
break;
322323
}

ICSharpCode.CodeConverter/CSharp/MethodWithHandles.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static IEnumerable<MemberDeclarationSyntax> GetDeclarationsForFieldBacked
3030
var fieldDecl = decl.WithVariables(SyntaxFactory.SeparatedList(decl.Variables.Select(v =>
3131
v.WithIdentifier(propertyToBackingFieldMapping[v.Identifier.Text])
3232
)));
33-
var fieldModifiers = SyntaxFactory.TokenList(new[] {SyntaxFactory.Token(SyntaxKind.PrivateKeyword)}.Concat(convertedModifiers.Where(m => !m.IsCsVisibility(false))));
33+
var fieldModifiers = SyntaxFactory.TokenList(new[] {SyntaxFactory.Token(SyntaxKind.PrivateKeyword)}.Concat(convertedModifiers.Where(m => !m.IsCsVisibility(false, false))));
3434
yield return SyntaxFactory.FieldDeclaration(attributes, fieldModifiers, fieldDecl);
3535
foreach (var variable in decl.Variables) {
3636
yield return GetDeclarationsForFieldBackedProperty(methodsWithHandles, attributes, convertedModifiers,

ICSharpCode.CodeConverter/CSharp/NodesVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ public override CSharpSyntaxNode VisitConstructorBlock(VBSyntax.ConstructorBlock
721721
{
722722
var block = node.BlockStatement;
723723
var attributes = block.AttributeLists.SelectMany(ConvertAttribute);
724-
var modifiers = CommonConversions.ConvertModifiers(block.Modifiers, GetMemberContext(node));
724+
var modifiers = CommonConversions.ConvertModifiers(block.Modifiers, GetMemberContext(node), isConstructor: true);
725725

726726
var ctor = (node.Statements.FirstOrDefault() as VBSyntax.ExpressionStatementSyntax)?.Expression as VBSyntax.InvocationExpressionSyntax;
727727
var ctorExpression = ctor?.Expression as VBSyntax.MemberAccessExpressionSyntax;

ICSharpCode.CodeConverter/Util/SyntaxTokenExtensions.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.CodeAnalysis.Text;
1010
using CSharpExtensions = Microsoft.CodeAnalysis.CSharp.CSharpExtensions;
1111
using VisualBasicExtensions = Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions;
12+
using VBasic = Microsoft.CodeAnalysis.VisualBasic;
1213

1314
namespace ICSharpCode.CodeConverter.Util
1415
{
@@ -693,7 +694,7 @@ public static bool HasMatchingText(this SyntaxToken token, SyntaxKind kind)
693694

694695
public static bool HasMatchingText(this SyntaxToken token, Microsoft.CodeAnalysis.VisualBasic.SyntaxKind kind)
695696
{
696-
return token.ToString() == Microsoft.CodeAnalysis.VisualBasic.SyntaxFacts.GetText(kind);
697+
return token.ToString() == VBasic.SyntaxFacts.GetText(kind);
697698
}
698699

699700
public static bool IsKind(this SyntaxToken token, SyntaxKind kind1, SyntaxKind kind2)
@@ -1045,16 +1046,18 @@ public static bool IsIdentifierOrAccessorOrAccessibilityModifier(this SyntaxToke
10451046
}
10461047
}
10471048

1048-
public static bool IsVbVisibility(this SyntaxToken token, bool isVariableOrConst)
1049+
public static bool IsVbVisibility(this SyntaxToken token, bool isVariableOrConst, bool isConstructor)
10491050
{
1050-
return token.IsKind(Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.PublicKeyword, Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.FriendKeyword, Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.ProtectedKeyword, Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.PrivateKeyword)
1051-
|| (isVariableOrConst && token.IsKind(Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.ConstKeyword));
1051+
return token.IsKind(VBasic.SyntaxKind.PublicKeyword, VBasic.SyntaxKind.FriendKeyword, VBasic.SyntaxKind.ProtectedKeyword, VBasic.SyntaxKind.PrivateKeyword)
1052+
|| isVariableOrConst && token.IsKind(VBasic.SyntaxKind.ConstKeyword)
1053+
|| isConstructor && token.IsKind(VBasic.SyntaxKind.SharedKeyword);
10521054
}
10531055

1054-
public static bool IsCsVisibility(this SyntaxToken token, bool isVariableOrConst)
1056+
public static bool IsCsVisibility(this SyntaxToken token, bool isVariableOrConst, bool isConstructor)
10551057
{
1056-
return token.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.PublicKeyword, Microsoft.CodeAnalysis.CSharp.SyntaxKind.InternalKeyword, Microsoft.CodeAnalysis.CSharp.SyntaxKind.ProtectedKeyword, Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrivateKeyword)
1057-
|| (isVariableOrConst && token.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.ConstKeyword));
1058+
return token.IsKind(SyntaxKind.PublicKeyword, SyntaxKind.InternalKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.PrivateKeyword)
1059+
|| isVariableOrConst && token.IsKind(SyntaxKind.ConstKeyword)
1060+
|| isConstructor && token.IsKind(SyntaxKind.StaticKeyword);
10581061
}
10591062
}
10601063
}

ICSharpCode.CodeConverter/VB/CommonConversions.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,13 @@ public void ConvertBaseList(BaseTypeDeclarationSyntax type, List<InheritsStateme
295295
}
296296

297297

298-
private static IEnumerable<SyntaxToken> ConvertModifiersCore(IReadOnlyCollection<SyntaxToken> modifiers, TokenContext context)
298+
private static IEnumerable<SyntaxToken> ConvertModifiersCore(IReadOnlyCollection<SyntaxToken> modifiers,
299+
TokenContext context, bool isConstructor)
299300
{
300301
if (context != TokenContext.Local && context != TokenContext.MemberInInterface) {
301302
bool visibility = false;
302303
foreach (var token in modifiers) {
303-
if (token.IsCsVisibility(true)) { //TODO Don't treat const as visibility, pass in more context to detect this
304+
if (token.IsCsVisibility(true, isConstructor)) { //TODO Don't always treat as variable or const, pass in more context to detect this
304305
visibility = true;
305306
break;
306307
}
@@ -341,9 +342,10 @@ private static SyntaxToken CSharpDefaultVisibility(TokenContext context)
341342
throw new ArgumentOutOfRangeException(nameof(context));
342343
}
343344

344-
internal static SyntaxTokenList ConvertModifiers(IReadOnlyCollection<SyntaxToken> modifiers, TokenContext context = TokenContext.Global)
345+
internal static SyntaxTokenList ConvertModifiers(IReadOnlyCollection<SyntaxToken> modifiers,
346+
TokenContext context = TokenContext.Global, bool isConstructor = false)
345347
{
346-
return SyntaxFactory.TokenList(ConvertModifiersCore(modifiers, context));
348+
return SyntaxFactory.TokenList(ConvertModifiersCore(modifiers, context, isConstructor));
347349
}
348350

349351
private static SyntaxToken? ConvertModifier(SyntaxToken m, TokenContext context = TokenContext.Global)

ICSharpCode.CodeConverter/VB/NodesVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ public override VisualBasicSyntaxNode VisitConstructorDeclaration(CSS.Constructo
324324
var initializer = new[] { (StatementSyntax)node.Initializer?.Accept(TriviaConvertingVisitor) }.Where(x => x != null);
325325
return SyntaxFactory.ConstructorBlock(
326326
SyntaxFactory.SubNewStatement(
327-
SyntaxFactory.List(node.AttributeLists.Select(a => (AttributeListSyntax)a.Accept(TriviaConvertingVisitor))), CommonConversions.ConvertModifiers(node.Modifiers, GetMemberContext(node)),
327+
SyntaxFactory.List(node.AttributeLists.Select(a => (AttributeListSyntax)a.Accept(TriviaConvertingVisitor))), CommonConversions.ConvertModifiers(node.Modifiers, GetMemberContext(node), true),
328328
(ParameterListSyntax)node.ParameterList?.Accept(TriviaConvertingVisitor)
329329
),
330330
SyntaxFactory.List(initializer.Concat(_commonConversions.ConvertBody(node.Body, node.ExpressionBody)))

Tests/CSharp/MemberTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,26 @@ public TestClass(out T argument, ref T2 argument2, T3 argument3)
335335
}");
336336
}
337337

338+
[Fact]
339+
public void TestConstructorWithImplicitPublicAccessibility()
340+
{
341+
TestConversionVisualBasicToCSharp(
342+
@"Sub New()
343+
End Sub", @"public SurroundingClass()
344+
{
345+
}");
346+
}
347+
348+
[Fact]
349+
public void TestStaticConstructor()
350+
{
351+
TestConversionVisualBasicToCSharp(
352+
@"Shared Sub New()
353+
End Sub", @"static SurroundingClass()
354+
{
355+
}");
356+
}
357+
338358
[Fact]
339359
public void TestDestructor()
340360
{

Tests/VB/MemberTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,17 @@ End Sub
358358
End Class");
359359
}
360360

361+
362+
[Fact]
363+
public void TestStaticConstructor()
364+
{
365+
TestConversionCSharpToVisualBasic(
366+
@"static SurroundingClass()
367+
{
368+
}", @"Shared Sub New()
369+
End Sub");
370+
}
371+
361372
[Fact]
362373
public void TestConstructorCallingBase()
363374
{

0 commit comments

Comments
 (0)