diff --git a/ReflectionAnalyzers.Tests/REFL014PreferGetMemberThenAccessorTests/CodeFix.cs b/ReflectionAnalyzers.Tests/REFL014PreferGetMemberThenAccessorTests/CodeFix.cs index a16c8690..5b96e8e5 100644 --- a/ReflectionAnalyzers.Tests/REFL014PreferGetMemberThenAccessorTests/CodeFix.cs +++ b/ReflectionAnalyzers.Tests/REFL014PreferGetMemberThenAccessorTests/CodeFix.cs @@ -1,4 +1,4 @@ -namespace ReflectionAnalyzers.Tests.REFL014PreferGetMemberThenAccessorTests +namespace ReflectionAnalyzers.Tests.REFL014PreferGetMemberThenAccessorTests { using System.Linq; using System.Threading.Tasks; @@ -642,5 +642,86 @@ event EventHandler IC1.E var message = @"Prefer typeof(BinaryReferencedAssembly.C1).GetEvent(""E"", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).AddMethod."; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic.WithMessage(message), solution, after); } + + [Test] + public static void InNestedType() + { + var before = @" +namespace N +{ + using System.Reflection; + + class C + { + protected bool P { get; } + + class Nested + { + object Get => typeof(C).↓GetMethod(""get_P"", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); + } + } +}"; + + var after = @" +namespace N +{ + using System.Reflection; + + class C + { + protected bool P { get; } + + class Nested + { + object Get => typeof(C).GetProperty(nameof(C.P), BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).GetMethod; + } + } +}"; + + RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); + } + + [Test] + public static void InNestedTypeWhenInheritance() + { + var @base = @" +namespace N +{ + class Base + { + protected bool P { get; } + } +}"; + + var before = @" +namespace N +{ + using System.Reflection; + + class C : Base + { + class Nested + { + object Get => typeof(C).↓GetMethod(""get_P"", BindingFlags.NonPublic | BindingFlags.Instance); + } + } +}"; + + var after = @" +namespace N +{ + using System.Reflection; + + class C : Base + { + class Nested + { + object Get => typeof(C).GetProperty(nameof(C.P), BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).GetMethod; + } + } +}"; + + RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, new[] { @base, before }, after); + } } } diff --git a/ReflectionAnalyzers/NodeAnalzers/GetXAnalyzer.cs b/ReflectionAnalyzers/NodeAnalzers/GetXAnalyzer.cs index 48eb3d1f..94d3c14a 100644 --- a/ReflectionAnalyzers/NodeAnalzers/GetXAnalyzer.cs +++ b/ReflectionAnalyzers/NodeAnalzers/GetXAnalyzer.cs @@ -483,7 +483,7 @@ private static bool UsesNameOfWrongMember(ReflectedMember member, Name name, Syn private static bool IsPreferGetMemberThenAccessor(ReflectedMember member, Name name, Flags flags, Types types, SyntaxNodeAnalysisContext context, [NotNullWhen(true)] out string? callText) { - if (member.Invocation?.Expression is MemberAccessExpressionSyntax memberAccess) + if (member is { ReflectedType: { }, Invocation: { Expression: MemberAccessExpressionSyntax memberAccess } }) { if (member is { Match: FilterMatch.Single, Symbol: IMethodSymbol method }) { @@ -634,7 +634,7 @@ string MemberName(ISymbol associatedSymbol) } return context.SemanticModel.IsAccessible(context.Node.SpanStart, associatedSymbol) - ? $"nameof({associatedSymbol.ContainingType.ToString(context)}.{associatedSymbol.Name})" + ? $"nameof({member.ReflectedType.ToString(context)}.{associatedSymbol.Name})" : $"\"{associatedSymbol.Name}\""; } }