@@ -36,49 +36,20 @@ public override void Initialize(AnalysisContext context)
36
36
return ;
37
37
}
38
38
39
- context . RegisterCodeBlockAction ( AnalyzeBlock ) ;
39
+ context . RegisterOperationAction ( AnalyzeSwitch , OperationKind . Switch ) ;
40
40
41
- void AnalyzeBlock ( CodeBlockAnalysisContext con ) => SwitchAnalyzer . AnalyzeBlock (
42
- context : con ,
43
- shouldProcessEnum : shouldProcessEnum ,
44
- shouldProcessInterface : shouldProcessInterface ,
41
+ void AnalyzeSwitch ( OperationAnalysisContext con ) => CheckSwitch (
42
+ switchStatement : con . Operation . Syntax as SwitchStatementSyntax ,
43
+ context : con ,
44
+ shouldProcessEnum : shouldProcessEnum ,
45
+ shouldProcessInterface : shouldProcessInterface ,
45
46
shouldProcessClass : shouldProcessClass ) ;
46
47
}
47
48
48
- private static void AnalyzeBlock ( CodeBlockAnalysisContext context , bool shouldProcessEnum , bool shouldProcessInterface , bool shouldProcessClass )
49
- {
50
- var blockSyntaxes = context . CodeBlock . ChildNodes ( ) . OfType < BlockSyntax > ( ) ;
51
-
52
- var switchStatements = blockSyntaxes . SelectMany ( x => x . Statements . OfType < SwitchStatementSyntax > ( ) ) ;
53
-
54
- foreach ( var switchStatement in switchStatements )
55
- {
56
- try
57
- {
58
-
59
- CheckSwitch (
60
- switchStatement : switchStatement ,
61
- context : context ,
62
- shouldProcessEnum : shouldProcessEnum ,
63
- shouldProcessInterface : shouldProcessInterface ,
64
- shouldProcessClass : shouldProcessClass ) ;
65
- }
66
- catch ( Exception e )
67
- {
68
- var diagnostic = Diagnostic . Create (
69
- descriptor : AnalyzerErrorDescriptor ,
70
- location : switchStatement . GetLocation ( ) ,
71
- messageArgs : e . ToString ( ) ) ;
72
-
73
- context . ReportDiagnostic ( diagnostic ) ;
74
- }
75
- }
76
- }
77
-
78
- private static void CheckSwitch ( SwitchStatementSyntax switchStatement , CodeBlockAnalysisContext context , bool shouldProcessEnum , bool shouldProcessInterface , bool shouldProcessClass )
49
+ private static void CheckSwitch ( SwitchStatementSyntax switchStatement , OperationAnalysisContext context , bool shouldProcessEnum , bool shouldProcessInterface , bool shouldProcessClass )
79
50
{
80
51
var expression = switchStatement . Expression ;
81
- var typeInfo = context . SemanticModel . GetTypeInfo ( expression ) ;
52
+ var typeInfo = context . Operation . SemanticModel . GetTypeInfo ( expression ) ;
82
53
var expressionType = typeInfo . ConvertedType ;
83
54
var switchCases = switchStatement . Sections ;
84
55
var switchLocationStart = switchStatement . GetLocation ( ) . SourceSpan . Start ;
@@ -145,7 +116,7 @@ private static void CheckSwitch(SwitchStatementSyntax switchStatement, CodeBlock
145
116
if ( expressionType . TypeKind == TypeKind . Interface && shouldProcessInterface )
146
117
{
147
118
bool ShouldProceed ( ) => InterfaceAnalyzer . ShouldProceedWithChecks ( switchCases ) ;
148
- IEnumerable < SwitchArgumentTypeItem < string > > AllImplementations ( ) => InterfaceAnalyzer . GetAllImplementationNames ( switchLocationStart , expressionType , context . SemanticModel ) ;
119
+ IEnumerable < SwitchArgumentTypeItem < string > > AllImplementations ( ) => InterfaceAnalyzer . GetAllImplementationNames ( switchLocationStart , expressionType , context . Operation . SemanticModel ) ;
149
120
IEnumerable < string > CaseImplementations ( ) => PatternMatchingHelper . GetCaseValues ( switchCases ) ;
150
121
151
122
ProcessSwitch ( ShouldProceed , AllImplementations , CaseImplementations , InterfaceAnalyzer . Rule ) ;
@@ -154,7 +125,7 @@ private static void CheckSwitch(SwitchStatementSyntax switchStatement, CodeBlock
154
125
if ( expressionType . TypeKind == TypeKind . Class && shouldProcessClass )
155
126
{
156
127
bool ShouldProceed ( ) => ClassAnalyzer . ShouldProceedWithChecks ( switchCases , expressionType . Name ) ;
157
- IEnumerable < SwitchArgumentTypeItem < string > > AllImplementations ( ) => ClassAnalyzer . GetAllImplementationNames ( switchLocationStart , expressionType , context . SemanticModel ) ;
128
+ IEnumerable < SwitchArgumentTypeItem < string > > AllImplementations ( ) => ClassAnalyzer . GetAllImplementationNames ( switchLocationStart , expressionType , context . Operation . SemanticModel ) ;
158
129
IEnumerable < string > CaseImplementations ( ) => PatternMatchingHelper . GetCaseValues ( switchCases ) ;
159
130
160
131
ProcessSwitch ( ShouldProceed , AllImplementations , CaseImplementations , ClassAnalyzer . Rule ) ;
@@ -179,7 +150,7 @@ private static void ProcessSwitchCases<T>(
179
150
Func < IEnumerable < string > > caseImplementationFunc ,
180
151
DiagnosticDescriptor rule ,
181
152
Location location ,
182
- CodeBlockAnalysisContext context ,
153
+ OperationAnalysisContext context ,
183
154
int switchStatementLocation ) where T : IComparable
184
155
{
185
156
if ( shouldProceedFunc == null
@@ -193,23 +164,23 @@ private static void ProcessSwitchCases<T>(
193
164
194
165
var allImplementations = allImplementationsFunc ( ) . ToList ( ) ;
195
166
196
- var obj = new object ( ) ;
197
- var caseImplementations = caseImplementationFunc ( ) . ToDictionary ( x => x , _ => obj ) ;
167
+ var caseImplementations = caseImplementationFunc ( ) . ToImmutableHashSet ( ) ;
198
168
199
169
var checkedValues = allImplementations
200
- . Where ( expectedValue => caseImplementations . ContainsKey ( expectedValue . FullName ) )
201
- . ToDictionary ( x => x . Value , x => obj ) ;
170
+ . Where ( expectedValue => caseImplementations . Contains ( expectedValue . FullName ) )
171
+ . Select ( x => x . Value )
172
+ . ToImmutableHashSet ( ) ;
202
173
203
174
var notCheckedValues = allImplementations . Where ( x =>
204
- ! checkedValues . ContainsKey ( x . Value ) )
175
+ ! checkedValues . Contains ( x . Value ) )
205
176
. OrderBy ( x => x . FullName )
206
177
. ToList ( ) ;
207
178
208
179
if ( notCheckedValues . Any ( ) )
209
180
{
210
181
var firstUncheckedValue = notCheckedValues . First ( ) ;
211
182
var typeName = firstUncheckedValue . Member ;
212
- var symbols = context . SemanticModel . LookupSymbols ( switchStatementLocation ) ;
183
+ var symbols = context . Operation . SemanticModel . LookupSymbols ( switchStatementLocation ) ;
213
184
var shouldAddNamespace = ! symbols . Any ( x => x . Name == typeName && x . ContainingNamespace . Name == firstUncheckedValue . Prefix ) ;
214
185
215
186
var notCoveredValues = notCheckedValues . Select ( caseName =>
0 commit comments