@@ -12,7 +12,8 @@ internal class InvokeAnalyzer : DiagnosticAnalyzer
1212 {
1313 /// <inheritdoc/>
1414 public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics { get ; } = ImmutableArray . Create (
15- REFL002InvokeDiscardReturnValue . Descriptor ) ;
15+ REFL002InvokeDiscardReturnValue . Descriptor ,
16+ REFL024PreferNullOverEmptyArray . Descriptor ) ;
1617
1718 /// <inheritdoc/>
1819 public override void Initialize ( AnalysisContext context )
@@ -28,8 +29,48 @@ private static void Handle(SyntaxNodeAnalysisContext context)
2829 context . Node is InvocationExpressionSyntax invocation &&
2930 invocation . TryGetMethodName ( out var name ) &&
3031 name == "Invoke" &&
31- context . SemanticModel . TryGetSymbol ( invocation , context . CancellationToken , out var target ) )
32+ context . SemanticModel . TryGetSymbol ( invocation , context . CancellationToken , out var invoke ) &&
33+ invoke . ContainingType . IsAssignableTo ( KnownSymbol . MemberInfo , context . Compilation ) )
3234 {
35+ if ( invoke . TryFindParameter ( "parameters" , out var parameter ) &&
36+ invocation . TryFindArgument ( parameter , out var paramsArg ) &&
37+ IsEmptyArray ( paramsArg , context ) )
38+ {
39+ context . ReportDiagnostic ( Diagnostic . Create ( REFL024PreferNullOverEmptyArray . Descriptor , paramsArg . GetLocation ( ) ) ) ;
40+ }
41+ }
42+ }
43+
44+ private static bool IsEmptyArray ( ArgumentSyntax argument , SyntaxNodeAnalysisContext context )
45+ {
46+ switch ( argument . Expression )
47+ {
48+ case InvocationExpressionSyntax invocation when context . SemanticModel . TryGetSymbol ( invocation , context . CancellationToken , out var symbol ) &&
49+ symbol == KnownSymbol . Array . Empty :
50+ return true ;
51+ case ArrayCreationExpressionSyntax arrayCreation :
52+ if ( arrayCreation . Type is ArrayTypeSyntax arrayType )
53+ {
54+ foreach ( var rankSpecifier in arrayType . RankSpecifiers )
55+ {
56+ foreach ( var size in rankSpecifier . Sizes )
57+ {
58+ if ( size is LiteralExpressionSyntax literal &&
59+ literal . Token . ValueText != "0" )
60+ {
61+ return false ;
62+ }
63+ }
64+ }
65+
66+ var initializer = arrayCreation . Initializer ;
67+ return initializer == null ||
68+ initializer . Expressions . Count == 0 ;
69+ }
70+
71+ return false ;
72+ default :
73+ return false ;
3374 }
3475 }
3576 }
0 commit comments