@@ -42,47 +42,63 @@ public override void Initialize(AnalysisContext analysisContext)
42
42
analysisContext . EnableConcurrentExecution ( ) ;
43
43
analysisContext . ConfigureGeneratedCodeAnalysis ( GeneratedCodeAnalysisFlags . None ) ;
44
44
45
- analysisContext . RegisterOperationBlockStartAction ( context =>
45
+ analysisContext . RegisterCompilationStartAction ( context =>
46
46
{
47
+ var taskTypesBuilder = ImmutableHashSet . CreateBuilder < ITypeSymbol > ( ) ;
47
48
48
- if ( ! ( context . OwningSymbol is IMethodSymbol methodSymbol ) ||
49
- methodSymbol . ReturnsVoid ||
50
- methodSymbol . ReturnType . Kind == SymbolKind . ArrayType ||
51
- ! methodSymbol . Parameters . IsEmpty ||
52
- ! methodSymbol . MatchesConfiguredVisibility ( context . Options , Rule , context . Compilation , context . CancellationToken ) ||
53
- methodSymbol . IsAccessorMethod ( ) ||
54
- ! IsPropertyLikeName ( methodSymbol . Name ) )
55
- {
56
- return ;
57
- }
49
+ taskTypesBuilder . AddIfNotNull (
50
+ context . Compilation . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemThreadingTasksTask ) ) ;
51
+ taskTypesBuilder . AddIfNotNull (
52
+ context . Compilation . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemThreadingTasksTask1 ) ) ;
53
+ taskTypesBuilder . AddIfNotNull (
54
+ context . Compilation . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemThreadingTasksValueTask ) ) ;
55
+ taskTypesBuilder . AddIfNotNull (
56
+ context . Compilation . GetOrCreateTypeByMetadataName ( WellKnownTypeNames . SystemThreadingTasksValueTask1 ) ) ;
58
57
59
- // A few additional checks to reduce the noise for this diagnostic:
60
- // Ensure that the method is non-generic, non-virtual/override, has no overloads and doesn't have special names: 'GetHashCode' or 'GetEnumerator'.
61
- // Also avoid generating this diagnostic if the method body has any invocation expressions.
62
- // Also avoid implicit interface implementation (explicit are handled through the member accessibility)
63
- if ( methodSymbol . IsGenericMethod ||
64
- methodSymbol . IsVirtual ||
65
- methodSymbol . IsOverride ||
66
- methodSymbol . ContainingType . GetMembers ( methodSymbol . Name ) . Length > 1 ||
67
- methodSymbol . Name == GetHashCodeName ||
68
- methodSymbol . Name == GetEnumeratorName ||
69
- methodSymbol . IsImplementationOfAnyImplicitInterfaceMember ( ) )
70
- {
71
- return ;
72
- }
58
+ var taskTypes = taskTypesBuilder . ToImmutable ( ) ;
73
59
74
- bool hasInvocations = false ;
75
- context . RegisterOperationAction ( operationContext =>
60
+ context . RegisterOperationBlockStartAction ( context =>
76
61
{
77
- hasInvocations = true ;
78
- } , OperationKind . Invocation ) ;
62
+ if ( ! ( context . OwningSymbol is IMethodSymbol methodSymbol ) ||
63
+ methodSymbol . ReturnsVoid ||
64
+ methodSymbol . ReturnType . Kind == SymbolKind . ArrayType ||
65
+ ! methodSymbol . Parameters . IsEmpty ||
66
+ ! methodSymbol . MatchesConfiguredVisibility ( context . Options , Rule , context . Compilation , context . CancellationToken ) ||
67
+ methodSymbol . IsAccessorMethod ( ) ||
68
+ ! IsPropertyLikeName ( methodSymbol . Name ) )
69
+ {
70
+ return ;
71
+ }
79
72
80
- context . RegisterOperationBlockEndAction ( endContext =>
81
- {
82
- if ( ! hasInvocations )
73
+ // A few additional checks to reduce the noise for this diagnostic:
74
+ // Ensure that the method is non-generic, non-virtual/override, has no overloads and doesn't have special names: 'GetHashCode' or 'GetEnumerator'.
75
+ // Also avoid generating this diagnostic if the method body has any invocation expressions.
76
+ // Also avoid implicit interface implementation (explicit are handled through the member accessibility)
77
+ if ( methodSymbol . IsGenericMethod ||
78
+ methodSymbol . IsVirtual ||
79
+ methodSymbol . IsOverride ||
80
+ methodSymbol . Name == GetHashCodeName ||
81
+ methodSymbol . Name == GetEnumeratorName ||
82
+ methodSymbol . ContainingType . GetMembers ( methodSymbol . Name ) . Length > 1 ||
83
+ taskTypes . Contains ( methodSymbol . ReturnType . OriginalDefinition ) ||
84
+ methodSymbol . IsImplementationOfAnyImplicitInterfaceMember ( ) )
83
85
{
84
- endContext . ReportDiagnostic ( endContext . OwningSymbol . CreateDiagnostic ( Rule ) ) ;
86
+ return ;
85
87
}
88
+
89
+ bool hasInvocations = false ;
90
+ context . RegisterOperationAction ( operationContext =>
91
+ {
92
+ hasInvocations = true ;
93
+ } , OperationKind . Invocation ) ;
94
+
95
+ context . RegisterOperationBlockEndAction ( endContext =>
96
+ {
97
+ if ( ! hasInvocations )
98
+ {
99
+ endContext . ReportDiagnostic ( endContext . OwningSymbol . CreateDiagnostic ( Rule ) ) ;
100
+ }
101
+ } ) ;
86
102
} ) ;
87
103
} ) ;
88
104
}
0 commit comments