Skip to content

Commit cdb6fc2

Browse files
committed
Make DeclaredOnly and FlattenHierarchy redundant when calling GetConstructor. Fix #93.
1 parent 8c84172 commit cdb6fc2

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

ReflectionAnalyzers.Tests/REFL006RedundantBindingFlagsTests/CodeFix.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ internal class CodeFix
1010
{
1111
private static readonly DiagnosticAnalyzer Analyzer = new GetXAnalyzer();
1212
private static readonly CodeFixProvider Fix = new BindingFlagsFix();
13-
private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create("REFL006");
13+
private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(REFL006RedundantBindingFlags.Descriptor);
1414

1515
[TestCase("Static", "BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Instance", "BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly")]
1616
[TestCase("Static", "BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.NonPublic", "BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly")]
@@ -173,5 +173,41 @@ private class Private
173173
var message = $"The binding flags can be more precise. Expected: {expected}.";
174174
AnalyzerAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic.WithMessage(message), code, fixedCode);
175175
}
176+
177+
[TestCase("GetConstructor(↓BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null)")]
178+
[TestCase("GetConstructor(↓BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy, null, Type.EmptyTypes, null)")]
179+
public void GetConstructor(string call)
180+
{
181+
var code = @"
182+
namespace RoslynSandbox
183+
{
184+
using System;
185+
using System.Reflection;
186+
187+
class Foo
188+
{
189+
public Foo()
190+
{
191+
var member = typeof(Foo).GetConstructor(↓BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null);
192+
}
193+
}
194+
}".AssertReplace("GetConstructor(↓BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null)", call);
195+
var fixedCode = @"
196+
namespace RoslynSandbox
197+
{
198+
using System;
199+
using System.Reflection;
200+
201+
class Foo
202+
{
203+
public Foo()
204+
{
205+
var member = typeof(Foo).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
206+
}
207+
}
208+
}";
209+
var message = "The binding flags can be more precise. Expected: BindingFlags.Public | BindingFlags.Instance.";
210+
AnalyzerAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic.WithMessage(message), code, fixedCode);
211+
}
176212
}
177213
}

ReflectionAnalyzers/NodeAnalzers/GetXAnalyzer.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,17 @@ private static bool TryGetExpectedFlags(ISymbol target, ITypeSymbol targetType,
291291
flags |= BindingFlags.Instance;
292292
}
293293

294-
if (Equals(target.ContainingType, targetType))
294+
if (!(target is IMethodSymbol method &&
295+
method.MethodKind == MethodKind.Constructor))
295296
{
296-
flags |= BindingFlags.DeclaredOnly;
297-
}
298-
else if (target.IsStatic)
299-
{
300-
flags |= BindingFlags.FlattenHierarchy;
297+
if (Equals(target.ContainingType, targetType))
298+
{
299+
flags |= BindingFlags.DeclaredOnly;
300+
}
301+
else if (target.IsStatic)
302+
{
303+
flags |= BindingFlags.FlattenHierarchy;
304+
}
301305
}
302306
}
303307

@@ -306,6 +310,14 @@ private static bool TryGetExpectedFlags(ISymbol target, ITypeSymbol targetType,
306310

307311
private static bool HasRedundantFlag(ISymbol target, ITypeSymbol targetType, BindingFlags flags)
308312
{
313+
if (target is IMethodSymbol method &&
314+
method.MethodKind == MethodKind.Constructor &&
315+
(flags.HasFlagFast(BindingFlags.DeclaredOnly) ||
316+
flags.HasFlagFast(BindingFlags.FlattenHierarchy)))
317+
{
318+
return true;
319+
}
320+
309321
if (target is ITypeSymbol &&
310322
(flags.HasFlagFast(BindingFlags.Instance) ||
311323
flags.HasFlagFast(BindingFlags.Static) ||

ValidCode/GetConstructor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ public class GetConstructor
77
{
88
public GetConstructor()
99
{
10-
_ = typeof(Default).GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null);
11-
_ = typeof(Single).GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, Type.EmptyTypes, null);
12-
_ = typeof(Two).GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new[] { typeof(int) }, null);
13-
_ = typeof(Two).GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new[] { typeof(double) }, null);
10+
_ = typeof(Default).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
11+
_ = typeof(Single).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
12+
_ = typeof(Two).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(int) }, null);
13+
_ = typeof(Two).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(double) }, null);
1414
}
1515
public class Default
1616
{

0 commit comments

Comments
 (0)