Skip to content

Commit

Permalink
Fix WTG1002 false-positive in enumerable subclasses (#214)
Browse files Browse the repository at this point in the history
Fix false-positive for non-generic GetEnumerator overriding generic GetEnumerator in base class
  • Loading branch information
yaakov-h authored Aug 8, 2023
1 parent 6339e02 commit eb4423c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 5 deletions.
24 changes: 24 additions & 0 deletions src/WTG.Analyzers.Test/TestData/VarAnalyzer/Foreach/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ public void MissingTypeInfo(UnknownType values)
{
}
}

public void ImplicitNonGeneric(ImplicitNonGenericCollection values)
{
foreach (int value in values) // can't translate this so don't suggest it
{
}
}

public void ChildImplicitNonGeneric(ChildImplicitNonGenericCollection values)
{
foreach (int value in values) // can't translate this so don't suggest it
{
}
}
}

public class MagicCollection<T> : IEnumerable
Expand Down Expand Up @@ -95,3 +109,13 @@ public class AmbigiousCollection : IEnumerable<int>, IEnumerable<double>
IEnumerator<int> IEnumerable<int>.GetEnumerator() { yield break; }
IEnumerator<double> IEnumerable<double>.GetEnumerator() { yield break; }
}

public class ImplicitNonGenericCollection : IEnumerable<int>
{
public IEnumerator GetEnumerator() { yield break; }
IEnumerator<int> IEnumerable<int>.GetEnumerator() { yield break; }
}

public class ChildImplicitNonGenericCollection : ImplicitNonGenericCollection
{
}
24 changes: 24 additions & 0 deletions src/WTG.Analyzers.Test/TestData/VarAnalyzer/Foreach/Source.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ public void MissingTypeInfo(UnknownType values)
{
}
}

public void ImplicitNonGeneric(ImplicitNonGenericCollection values)
{
foreach (int value in values) // can't translate this so don't suggest it
{
}
}

public void ChildImplicitNonGeneric(ChildImplicitNonGenericCollection values)
{
foreach (int value in values) // can't translate this so don't suggest it
{
}
}
}

public class MagicCollection<T> : IEnumerable
Expand Down Expand Up @@ -95,3 +109,13 @@ public class AmbigiousCollection : IEnumerable<int>, IEnumerable<double>
IEnumerator<int> IEnumerable<int>.GetEnumerator() { yield break; }
IEnumerator<double> IEnumerable<double>.GetEnumerator() { yield break; }
}

public class ImplicitNonGenericCollection : IEnumerable<int>
{
public IEnumerator GetEnumerator() { yield break; }
IEnumerator<int> IEnumerable<int>.GetEnumerator() { yield break; }
}

public class ChildImplicitNonGenericCollection : ImplicitNonGenericCollection
{
}
14 changes: 13 additions & 1 deletion src/WTG.Analyzers.Utils.Test/EnumerableTypeUtilsTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -15,6 +15,8 @@ public class EnumerableTypeUtilsTest
[TestCase("IEnumerable", ExpectedResult = "object")]
[TestCase("PreGenericTypedCollection", ExpectedResult = "float")]
[TestCase("ExplicitOnlyCollection", ExpectedResult = "double")]
[TestCase("ImplicitNonGenericCollection", ExpectedResult = "object")]
[TestCase("ChildImplicitNonGenericCollection", ExpectedResult = "object")]
public string GetItemType(string enumerableType)
{
return EnumerableTypeUtils.GetElementType(GetType(enumerableType))?.ToString();
Expand Down Expand Up @@ -53,6 +55,16 @@ class ExplicitOnlyCollection : IEnumerable<double>
IEnumerator<double> IEnumerable<double>.GetEnumerator() { yield break; }
IEnumerator IEnumerable.GetEnumerator() { yield break; }
}
class ImplicitNonGenericCollection : IEnumerable<double>
{
IEnumerator<double> IEnumerable<double>.GetEnumerator() { yield break; }
IEnumerator GetEnumerator() { yield break; }
}
class ChildImplicitNonGenericCollection : ImplicitNonGenericCollection
{
}
";

var document = ModelUtils.CreateDocument(source);
Expand Down
14 changes: 10 additions & 4 deletions src/WTG.Analyzers.Utils/EnumerableTypeUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,21 @@ public static class EnumerableTypeUtils

static ITypeSymbol? GetExplicitElementType(ITypeSymbol enumerableType)
{
foreach (var method in enumerableType.GetMembers(nameof(IEnumerable.GetEnumerator)).OfType<IMethodSymbol>())
do
{
if (!method.IsGenericMethod && method.Parameters.Length == 0 && method.TypeArguments.Length == 0)
foreach (var method in enumerableType.GetMembers(nameof(IEnumerable.GetEnumerator)).OfType<IMethodSymbol>())
{
var retType = method.ReturnType;
if (!method.IsGenericMethod && method.Parameters.Length == 0 && method.TypeArguments.Length == 0)
{
var retType = method.ReturnType;

return GetElementTypeFromEnumeratorType(retType);
return GetElementTypeFromEnumeratorType(retType);
}
}

enumerableType = enumerableType.BaseType!;
}
while (enumerableType != null);

return null;
}
Expand Down

0 comments on commit eb4423c

Please sign in to comment.