Skip to content

Commit

Permalink
BUGFIX REFL016 use nameof when nested types.
Browse files Browse the repository at this point in the history
Fix #229
  • Loading branch information
JohanLarsson committed May 16, 2020
1 parent 5978a87 commit 5ef938e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
33 changes: 33 additions & 0 deletions ReflectionAnalyzers.Tests/REFL016UseNameofTests/Valid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -586,5 +586,38 @@ class C : Control

RoslynAssert.Valid(Analyzer, Descriptor, code);
}

[TestCase("GetMethod(\"M1\")")]
[TestCase("GetMethod(\"M1\", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null)")]
public static void InNestedTypeInheritance(string expression)
{
var @base = @"
namespace N
{
class Base
{
protected void M1() { }
}
}";

var code = @"
namespace N
{
using System;
using System.Reflection;
class C : Base
{
class Nested
{
void M2()
{
typeof(Base).GetMethod(""M1"");
}
}
}
}".AssertReplace("GetMethod(\"M1\")", expression);
RoslynAssert.Valid(Analyzer, Descriptor, @base, code);
}
}
}
23 changes: 22 additions & 1 deletion ReflectionAnalyzers/Helpers/NameOf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal static bool TryGetExpressionText(ReflectedMember member, SyntaxNodeAnal
targetName = null;
if (member.Symbol is null ||
!member.Symbol.CanBeReferencedByName ||
!context.SemanticModel.IsAccessible(context.Node.SpanStart, member.Symbol) ||
!IsAccessible() ||
member.Symbol is INamedTypeSymbol { IsGenericType: true } ||
(member.Symbol is IMethodSymbol method && method.MethodKind != MethodKind.Ordinary))
{
Expand Down Expand Up @@ -60,6 +60,27 @@ member.Symbol is ITypeSymbol ||
targetName = $"{TypeOfString(member.Symbol.ContainingType)}.{member.Symbol.Name}";
return true;

bool IsAccessible()
{
// Working around https://github.com/dotnet/roslyn/issues/43696
if (context.SemanticModel.IsAccessible(context.Node.SpanStart, member.Symbol))
{
if (member.Symbol.DeclaredAccessibility.IsEither(Accessibility.Public, Accessibility.Internal))
{
return true;
}

if (context.Node.FirstAncestor<TypeDeclarationSyntax>() is { } containingType)
{
return containingType.Identifier.ValueText == member.Symbol.ContainingType.MetadataName;
}

return true;
}

return false;
}

string TypeOfString(ITypeSymbol t)
{
if (t is INamedTypeSymbol { TupleUnderlyingType: { } utt } namedType &&
Expand Down

0 comments on commit 5ef938e

Please sign in to comment.