Skip to content

Commit acaadcb

Browse files
Prevent overrides and overloads appearing on the same property - fixes #681
1 parent 1817d3a commit acaadcb

4 files changed

Lines changed: 70 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1010

1111
### VB -> C#
1212

13+
* Prevent overrides and overloads appearing on the same property (https://github.com/icsharpcode/CodeConverter/issues/681)
1314

1415
### C# -> VB
1516

1617

1718
## [8.2.4] - 2021-05-04
1819

1920
### Command line
21+
2022
* The --Core-Only flag no longer requires a value [#704](https://github.com/icsharpcode/CodeConverter/issues/704)
2123

2224

2325
### VB -> C#
26+
2427
* Deal with NullReferenceException caused by Nothing literal [#707](https://github.com/icsharpcode/CodeConverter/issues/707)
2528
* Include text of region which can't be converted
2629
* Convert region names

CodeConverter/CSharp/CommonConversions.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,13 @@ public SyntaxTokenList ConvertModifiers(SyntaxNode node, IReadOnlyCollection<Syn
349349

350350
private static bool? RequiresNewKeyword(ISymbol declaredSymbol)
351351
{
352-
if (!(declaredSymbol is IMethodSymbol methodSymbol)) return null;
353-
if (declaredSymbol.IsOverride ) return false;
354-
var methodSignature = methodSymbol.GetUnqualifiedMethodSignature(true);
355-
return declaredSymbol.ContainingType.FollowProperty(s => s.BaseType).Skip(1).Any(t => t.GetMembers()
356-
.Any(s => s.Name == declaredSymbol.Name && s is IMethodSymbol m && m.GetUnqualifiedMethodSignature(true) == methodSignature));
352+
if (declaredSymbol.IsOverride) return false;
353+
if (declaredSymbol is IPropertySymbol propertySymbol || declaredSymbol is IMethodSymbol methodSymbol) {
354+
var methodSignature = declaredSymbol.GetUnqualifiedMethodOrPropertySignature(true);
355+
return declaredSymbol.ContainingType.FollowProperty(s => s.BaseType).Skip(1).Any(t => t.GetMembers()
356+
.Any(s => s.Name == declaredSymbol.Name && (s is IPropertySymbol || s is IMethodSymbol) && s.GetUnqualifiedMethodOrPropertySignature(true) == methodSignature));
357+
}
358+
return null;
357359
}
358360

359361
private static bool ContextHasIdenticalDefaults(TokenContext context, TokenContext[] contextsWithIdenticalDefaults, ISymbol declaredSymbol)
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Linq;
23
using ICSharpCode.CodeConverter.Util.FromRoslyn;
34
using Microsoft.CodeAnalysis;
@@ -6,19 +7,22 @@ namespace ICSharpCode.CodeConverter.Util
67
{
78
internal static class IMethodSymbolExtensions
89
{
9-
public static string GetParameterSignature(this IMethodSymbol methodSymbol)
10-
{
11-
return string.Join(" ", methodSymbol.Parameters.Select(p => p.Type));
12-
}
10+
public static string GetParameterSignature(this IMethodSymbol methodSymbol) => string.Join(" ", methodSymbol.Parameters.Select(p => p.Type));
11+
public static string GetParameterSignature(this IPropertySymbol propertySymbol) => string.Join(" ", propertySymbol.Parameters.Select(p => p.Type));
1312

14-
public static (string Name, int TypeParameterCount, string ParameterTypes) GetUnqualifiedMethodSignature(this IMethodSymbol methodSymbol, bool caseSensitiveName)
15-
{
16-
return (caseSensitiveName ? methodSymbol.Name : methodSymbol.Name.ToLowerInvariant() , methodSymbol.TypeParameters.Length, GetParameterSignature(methodSymbol));
17-
}
13+
public static (string Name, int TypeParameterCount, string ParameterTypes) GetUnqualifiedMethodOrPropertySignature(this ISymbol s, bool caseSensitiveName) => s switch {
14+
IMethodSymbol m => m.GetUnqualifiedMethodSignature(caseSensitiveName),
15+
IPropertySymbol p => p.GetUnqualifiedPropertySignature(caseSensitiveName),
16+
_ => throw new ArgumentOutOfRangeException(nameof(s), s, $"Symbol must be property or method, but was {s.Kind}")
17+
};
1818

19-
public static bool ReturnsVoidOrAsyncTask(this IMethodSymbol enclosingMethodInfo)
20-
{
21-
return enclosingMethodInfo.ReturnsVoid || enclosingMethodInfo.IsAsync && enclosingMethodInfo.ReturnType.GetArity() == 0;
22-
}
19+
public static (string Name, int TypeParameterCount, string ParameterTypes) GetUnqualifiedMethodSignature(this IMethodSymbol methodSymbol, bool caseSensitiveName) =>
20+
(caseSensitiveName ? methodSymbol.Name : methodSymbol.Name.ToLowerInvariant(), methodSymbol.TypeParameters.Length, GetParameterSignature(methodSymbol));
21+
22+
public static (string Name, int TypeParameterCount, string ParameterTypes) GetUnqualifiedPropertySignature(this IPropertySymbol propertySymbol, bool caseSensitiveName) =>
23+
(caseSensitiveName ? propertySymbol.Name : propertySymbol.Name.ToLowerInvariant(), 0, GetParameterSignature(propertySymbol));
24+
25+
public static bool ReturnsVoidOrAsyncTask(this IMethodSymbol enclosingMethodInfo) =>
26+
enclosingMethodInfo.ReturnsVoid || enclosingMethodInfo.IsAsync && enclosingMethodInfo.ReturnType.GetArity() == 0;
2327
}
2428
}

Tests/CSharp/MemberTests/MemberTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,50 @@ internal partial class TestClass
630630
}");
631631
}
632632

633+
[Fact]
634+
public async Task Issue681_OverloadsOverridesPropertyAsync()
635+
{
636+
await TestConversionVisualBasicToCSharpAsync(
637+
@"Public Class C
638+
Inherits B
639+
640+
Public ReadOnly Overloads Overrides Property X()
641+
Get
642+
Return Nothing
643+
End Get
644+
End Property
645+
End Class
646+
647+
Public Class B
648+
Public ReadOnly Overridable Property X()
649+
Get
650+
Return Nothing
651+
End Get
652+
End Property
653+
End Class", @"
654+
public partial class C : B
655+
{
656+
public override object X
657+
{
658+
get
659+
{
660+
return null;
661+
}
662+
}
663+
}
664+
665+
public partial class B
666+
{
667+
public virtual object X
668+
{
669+
get
670+
{
671+
return null;
672+
}
673+
}
674+
}");
675+
}
676+
633677
[Fact]
634678
public async Task PartialFriendClassWithOverloadsAsync()
635679
{

0 commit comments

Comments
 (0)