1
1
namespace ReflectionAnalyzers
2
2
{
3
3
using System . Linq ;
4
- using System . Threading ;
5
4
using Gu . Roslyn . AnalyzerExtensions ;
6
5
using Microsoft . CodeAnalysis ;
7
6
using Microsoft . CodeAnalysis . CSharp . Syntax ;
@@ -130,26 +129,27 @@ internal static bool TryGetTargetType(InvocationExpressionSyntax getX, SyntaxNod
130
129
TryGetTargetType ( memberAccess . Expression , context , null , out result , out instance ) ;
131
130
}
132
131
133
- internal static GetXResult TryGetTarget ( IMethodSymbol getX , ITypeSymbol targetType , string targetName , BindingFlags effectiveFlags , SyntaxNodeAnalysisContext context , out ISymbol target )
132
+ internal static GetXResult TryGetTarget ( IMethodSymbol getX , ITypeSymbol targetType , string targetMetadataName , BindingFlags effectiveFlags , SyntaxNodeAnalysisContext context , out ISymbol target )
134
133
{
134
+ var name = TrimName ( ) ;
135
135
target = null ;
136
136
if ( targetType is ITypeParameterSymbol typeParameter )
137
137
{
138
138
if ( typeParameter . ConstraintTypes . Length == 0 )
139
139
{
140
- return TryGetTarget ( getX , context . Compilation . GetSpecialType ( SpecialType . System_Object ) , targetName , effectiveFlags , context , out target ) ;
140
+ return TryGetTarget ( getX , context . Compilation . GetSpecialType ( SpecialType . System_Object ) , name , effectiveFlags , context , out target ) ;
141
141
}
142
142
143
143
foreach ( var constraintType in typeParameter . ConstraintTypes )
144
144
{
145
- var result = TryGetTarget ( getX , constraintType , targetName , effectiveFlags , context , out target ) ;
145
+ var result = TryGetTarget ( getX , constraintType , name , effectiveFlags , context , out target ) ;
146
146
if ( result != GetXResult . NoMatch )
147
147
{
148
148
return result ;
149
149
}
150
150
}
151
151
152
- return TryGetTarget ( getX , context . Compilation . GetSpecialType ( SpecialType . System_Object ) , targetName , effectiveFlags , context , out target ) ;
152
+ return TryGetTarget ( getX , context . Compilation . GetSpecialType ( SpecialType . System_Object ) , name , effectiveFlags , context , out target ) ;
153
153
}
154
154
155
155
if ( getX == KnownSymbol . Type . GetNestedType ||
@@ -158,9 +158,9 @@ internal static GetXResult TryGetTarget(IMethodSymbol getX, ITypeSymbol targetTy
158
158
! effectiveFlags . HasFlagFast ( BindingFlags . Instance ) &&
159
159
! effectiveFlags . HasFlagFast ( BindingFlags . FlattenHierarchy ) ) )
160
160
{
161
- foreach ( var member in targetType . GetMembers ( targetName ) )
161
+ foreach ( var member in targetType . GetMembers ( name ) )
162
162
{
163
- if ( ! MatchesFlags ( member , effectiveFlags ) )
163
+ if ( ! MatchesFilter ( member , targetMetadataName , effectiveFlags ) )
164
164
{
165
165
continue ;
166
166
}
@@ -180,7 +180,7 @@ internal static GetXResult TryGetTarget(IMethodSymbol getX, ITypeSymbol targetTy
180
180
return GetXResult . Single ;
181
181
}
182
182
183
- if ( targetType . TryFindFirstMemberRecursive ( targetName , out target ) )
183
+ if ( targetType . TryFindFirstMemberRecursive ( name , out target ) )
184
184
{
185
185
if ( getX == KnownSymbol . Type . GetNestedType &&
186
186
! targetType . Equals ( target . ContainingType ) )
@@ -214,9 +214,9 @@ internal static GetXResult TryGetTarget(IMethodSymbol getX, ITypeSymbol targetTy
214
214
var current = targetType ;
215
215
while ( current != null )
216
216
{
217
- foreach ( var member in current . GetMembers ( targetName ) )
217
+ foreach ( var member in current . GetMembers ( name ) )
218
218
{
219
- if ( ! MatchesFlags ( member , effectiveFlags ) )
219
+ if ( ! MatchesFilter ( member , targetMetadataName , effectiveFlags ) )
220
220
{
221
221
continue ;
222
222
}
@@ -258,7 +258,7 @@ internal static GetXResult TryGetTarget(IMethodSymbol getX, ITypeSymbol targetTy
258
258
259
259
if ( target == null )
260
260
{
261
- if ( targetType . TryFindFirstMemberRecursive ( targetName , out target ) )
261
+ if ( targetType . TryFindFirstMemberRecursive ( name , out target ) )
262
262
{
263
263
return GetXResult . WrongFlags ;
264
264
}
@@ -332,7 +332,7 @@ bool IsExplicitImplementation( out ISymbol result)
332
332
{
333
333
foreach ( var @interface in targetType . AllInterfaces )
334
334
{
335
- if ( @interface . TryFindFirstMemberRecursive ( targetName , out result ) )
335
+ if ( @interface . TryFindFirstMemberRecursive ( name , out result ) )
336
336
{
337
337
return true ;
338
338
}
@@ -341,6 +341,17 @@ bool IsExplicitImplementation( out ISymbol result)
341
341
result = null ;
342
342
return false ;
343
343
}
344
+
345
+ string TrimName ( )
346
+ {
347
+ var index = targetMetadataName . IndexOf ( '`' ) ;
348
+ if ( index > 0 )
349
+ {
350
+ return targetMetadataName . Substring ( 0 , index ) ;
351
+ }
352
+
353
+ return targetMetadataName ;
354
+ }
344
355
}
345
356
346
357
internal static bool TryGetDefaultFlags ( QualifiedMethod getX , out BindingFlags defaultFlags )
@@ -409,8 +420,13 @@ private static bool TryGetFlags(InvocationExpressionSyntax invocation, IMethodSy
409
420
context . SemanticModel . TryGetConstantValue ( argument . Expression , context . CancellationToken , out bindingFlags ) ;
410
421
}
411
422
412
- private static bool MatchesFlags ( ISymbol candidate , BindingFlags filter )
423
+ private static bool MatchesFilter ( ISymbol candidate , string metadataName , BindingFlags filter )
413
424
{
425
+ if ( candidate . MetadataName != metadataName )
426
+ {
427
+ return false ;
428
+ }
429
+
414
430
if ( candidate . DeclaredAccessibility == Accessibility . Public &&
415
431
! filter . HasFlagFast ( BindingFlags . Public ) )
416
432
{
@@ -498,7 +514,7 @@ private static bool TryGetTargetType(ExpressionSyntax expression, SyntaxNodeAnal
498
514
}
499
515
500
516
return context . SemanticModel . TryGetType ( typeAccess . Expression , context . CancellationToken , out result ) ;
501
- case IdentifierNameSyntax identifierName when expression . TryFirstAncestor ( out TypeDeclarationSyntax containingType ) :
517
+ case IdentifierNameSyntax _ when expression . TryFirstAncestor ( out TypeDeclarationSyntax containingType ) :
502
518
return context . SemanticModel . TryGetSymbol ( containingType , context . CancellationToken , out result ) ;
503
519
}
504
520
}
0 commit comments