Skip to content

Commit dff005c

Browse files
authored
Workaround issue with explicitly implemented indexers (#34318)
1 parent c0c26f3 commit dff005c

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

src/GenAPI/Microsoft.DotNet.GenAPI/Filtering/ImplicitSymbolFilter.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,17 @@ public bool Include(ISymbol symbol)
2828
method.MethodKind == MethodKind.EventRemove ||
2929
method.MethodKind == MethodKind.EventRaise ||
3030
method.MethodKind == MethodKind.DelegateInvoke)
31+
{
32+
return false;
33+
}
34+
35+
// If the method is an explicitly implemented getter or setter, exclude it.
36+
// https://github.com/dotnet/roslyn/issues/53911
37+
if (method.MethodKind == MethodKind.ExplicitInterfaceImplementation &&
38+
method.ExplicitInterfaceImplementations.Any(m => m is { MethodKind: MethodKind.PropertyGet or MethodKind.PropertySet }))
39+
{
3140
return false;
41+
}
3242
}
3343

3444
if (symbol is ITypeSymbol type)

src/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ public static SyntaxNode DeclarationExt(this SyntaxGenerator syntaxGenerator, IS
8989
}
9090
}
9191

92+
if (symbol is IPropertySymbol propertySymbol)
93+
{
94+
// Explicitly implemented indexers do not set IsIndexer
95+
// https://github.com/dotnet/roslyn/issues/53911
96+
if (!propertySymbol.IsIndexer && propertySymbol.ExplicitInterfaceImplementations.Any(i => i.IsIndexer))
97+
{
98+
return syntaxGenerator.IndexerDeclaration(propertySymbol);
99+
}
100+
}
101+
92102
try
93103
{
94104
return syntaxGenerator.Declaration(symbol);

src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2499,5 +2499,122 @@ public static void M<T>(this object c, scoped System.ReadOnlySpan<T> values) { }
24992499
}
25002500
""");
25012501
}
2502+
2503+
[Fact]
2504+
public void TestExplicitInterfaceIndexer()
2505+
{
2506+
RunTest(original: """
2507+
namespace a
2508+
{
2509+
public interface IFooList
2510+
{
2511+
object this[int index] { get; set; }
2512+
}
2513+
2514+
public struct Bar : IFooList
2515+
{
2516+
#pragma warning disable CS8597
2517+
public string this[int index] { get { throw null; } set { } }
2518+
object IFooList.this[int index] { get { throw null; } set { } }
2519+
#pragma warning restore CS8597
2520+
}
2521+
}
2522+
""",
2523+
expected: """
2524+
namespace a
2525+
{
2526+
public partial struct Bar : IFooList
2527+
{
2528+
object IFooList.this[int index] { get { throw null; } set { } }
2529+
public string this[int index] { get { throw null; } set { } }
2530+
}
2531+
2532+
public partial interface IFooList
2533+
{
2534+
object this[int index] { get; set; }
2535+
}
2536+
}
2537+
""",
2538+
includeInternalSymbols: false);
2539+
}
2540+
2541+
[Fact]
2542+
public void TestExplicitInterfaceNonGenericCollections()
2543+
{
2544+
RunTest(original: """
2545+
#nullable disable
2546+
using System;
2547+
using System.Collections;
2548+
namespace a
2549+
{
2550+
#pragma warning disable CS8597
2551+
2552+
public partial class MyStringCollection : ICollection, IEnumerable, IList
2553+
{
2554+
public int Count { get { throw null; } }
2555+
public string this[int index] { get { throw null; } set { } }
2556+
bool ICollection.IsSynchronized { get { throw null; } }
2557+
object ICollection.SyncRoot { get { throw null; } }
2558+
bool IList.IsFixedSize { get { throw null; } }
2559+
bool IList.IsReadOnly { get { throw null; } }
2560+
object IList.this[int index] { get { throw null; } set { } }
2561+
public int Add(string value) { throw null; }
2562+
public void AddRange(string[] value) { }
2563+
public void AddRange(MyStringCollection value) { }
2564+
public void Clear() { }
2565+
public bool Contains(string value) { throw null; }
2566+
public void CopyTo(string[] array, int index) { }
2567+
public override int GetHashCode() { throw null; }
2568+
public int IndexOf(string value) { throw null; }
2569+
public void Insert(int index, string value) { }
2570+
public void Remove(string value) { }
2571+
public void RemoveAt(int index) { }
2572+
void ICollection.CopyTo(Array array, int index) { }
2573+
IEnumerator IEnumerable.GetEnumerator() { throw null; }
2574+
int IList.Add(object value) { throw null; }
2575+
bool IList.Contains(object value) { throw null; }
2576+
int IList.IndexOf(object value) { throw null; }
2577+
void IList.Insert(int index, object value) { }
2578+
void IList.Remove(object value) { }
2579+
}
2580+
2581+
#pragma warning restore CS8597
2582+
}
2583+
""",
2584+
expected: """
2585+
namespace a
2586+
{
2587+
public partial class MyStringCollection : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
2588+
{
2589+
public int Count { get { throw null; } }
2590+
public string this[int index] { get { throw null; } set { } }
2591+
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
2592+
object System.Collections.ICollection.SyncRoot { get { throw null; } }
2593+
bool System.Collections.IList.IsFixedSize { get { throw null; } }
2594+
bool System.Collections.IList.IsReadOnly { get { throw null; } }
2595+
object System.Collections.IList.this[int index] { get { throw null; } set { } }
2596+
public int Add(string value) { throw null; }
2597+
public void AddRange(MyStringCollection value) { }
2598+
public void AddRange(string[] value) { }
2599+
public void Clear() { }
2600+
public bool Contains(string value) { throw null; }
2601+
public void CopyTo(string[] array, int index) { }
2602+
public override int GetHashCode() { throw null; }
2603+
public int IndexOf(string value) { throw null; }
2604+
public void Insert(int index, string value) { }
2605+
public void Remove(string value) { }
2606+
public void RemoveAt(int index) { }
2607+
void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
2608+
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
2609+
int System.Collections.IList.Add(object value) { throw null; }
2610+
bool System.Collections.IList.Contains(object value) { throw null; }
2611+
int System.Collections.IList.IndexOf(object value) { throw null; }
2612+
void System.Collections.IList.Insert(int index, object value) { }
2613+
void System.Collections.IList.Remove(object value) { }
2614+
}
2615+
}
2616+
""",
2617+
includeInternalSymbols: false);
2618+
}
25022619
}
25032620
}

0 commit comments

Comments
 (0)