@@ -35,12 +35,6 @@ public static readonly DiagnosticDescriptor InconsistentTabIndexRuleIdDescriptor
35
35
isEnabledByDefault : true ,
36
36
"Remove TabIndex assignments and re-order controls in the parent's control collection." ) ;
37
37
38
- // Contains the list of fields and local controls that explicitly set TabIndex properties.
39
- private readonly Dictionary < string , int > _controlsTabIndex = new ( ) ;
40
- // Contains the list of fields and local controls in order those are added to parent controls.
41
- private readonly Dictionary < string , List < string > > _controlsAddIndex = new ( ) ;
42
- private readonly Dictionary < string , Location > _controlsAddIndexLocations = new ( ) ;
43
-
44
38
45
39
public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics
46
40
=> ImmutableArray . Create ( InconsistentTabIndexRuleIdDescriptor , NonNumericTabIndexValueRuleIdDescriptor ) ;
@@ -68,6 +62,7 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
68
62
continue ;
69
63
}
70
64
65
+ CalculatedAnalysisContext calculatedContext = new ( ) ;
71
66
foreach ( IOperation operation in blockOperation . Operations )
72
67
{
73
68
switch ( operation . Kind )
@@ -80,14 +75,14 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
80
75
if ( expressionStatementOperation . Operation is IOperation invocationOperation &&
81
76
invocationOperation . Syntax is InvocationExpressionSyntax expressionSyntax )
82
77
{
83
- ParseControlAddStatements ( expressionSyntax ) ;
78
+ ParseControlAddStatements ( expressionSyntax , calculatedContext ) ;
84
79
continue ;
85
80
}
86
81
87
82
// Look for ".TabIndex = <x>"
88
83
if ( expressionStatementOperation . Operation is IAssignmentOperation assignmentOperation )
89
84
{
90
- ParseTabIndexAssignments ( ( AssignmentExpressionSyntax ) assignmentOperation . Syntax , context ) ;
85
+ ParseTabIndexAssignments ( ( AssignmentExpressionSyntax ) assignmentOperation . Syntax , context , calculatedContext ) ;
91
86
continue ;
92
87
}
93
88
@@ -99,7 +94,7 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
99
94
}
100
95
}
101
96
102
- if ( _controlsTabIndex . Count < 1 )
97
+ if ( calculatedContext . ControlsTabIndex . Count < 1 )
103
98
{
104
99
// No controls explicitly set TabIndex - all good
105
100
return ;
@@ -116,25 +111,25 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
116
111
// [this.button1:1]
117
112
// [label2:0]
118
113
Dictionary < string , int > flatControlsAddIndex = new ( ) ;
119
- foreach ( string key in _controlsAddIndex . Keys )
114
+ foreach ( string key in calculatedContext . ControlsAddIndex . Keys )
120
115
{
121
- for ( int i = 0 ; i < _controlsAddIndex [ key ] . Count ; i ++ )
116
+ for ( int i = 0 ; i < calculatedContext . ControlsAddIndex [ key ] . Count ; i ++ )
122
117
{
123
- string controlName = _controlsAddIndex [ key ] [ i ] ;
118
+ string controlName = calculatedContext . ControlsAddIndex [ key ] [ i ] ;
124
119
flatControlsAddIndex [ controlName ] = i ;
125
120
}
126
121
}
127
122
128
123
// Verify explicit TabIndex is the same as the "add order"
129
- foreach ( string key in _controlsTabIndex . Keys )
124
+ foreach ( string key in calculatedContext . ControlsTabIndex . Keys )
130
125
{
131
126
if ( ! flatControlsAddIndex . ContainsKey ( key ) )
132
127
{
133
128
// TODO: assert, diagnostics, etc.
134
129
continue ;
135
130
}
136
131
137
- int tabIndex = _controlsTabIndex [ key ] ;
132
+ int tabIndex = calculatedContext . ControlsTabIndex [ key ] ;
138
133
int addIndex = flatControlsAddIndex [ key ] ;
139
134
140
135
if ( tabIndex == addIndex )
@@ -144,16 +139,15 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
144
139
145
140
var diagnostic = Diagnostic . Create (
146
141
descriptor : InconsistentTabIndexRuleIdDescriptor ,
147
- location : _controlsAddIndexLocations [ key ] ,
142
+ location : calculatedContext . ControlsAddIndexLocations [ key ] ,
148
143
properties : new Dictionary < string , string ? > { { "ZOrder" , addIndex . ToString ( ) } , { "TabIndex" , tabIndex . ToString ( ) } } . ToImmutableDictionary ( ) ,
149
144
key , addIndex , tabIndex ) ;
150
145
context . ReportDiagnostic ( diagnostic ) ;
151
146
}
152
-
153
147
}
154
148
}
155
149
156
- private void ParseControlAddStatements ( InvocationExpressionSyntax expressionSyntax )
150
+ private void ParseControlAddStatements ( InvocationExpressionSyntax expressionSyntax , CalculatedAnalysisContext calculatedContext )
157
151
{
158
152
if ( ! expressionSyntax . Expression . ToString ( ) . EndsWith ( ".Controls.Add" ) )
159
153
{
@@ -188,16 +182,16 @@ private void ParseControlAddStatements(InvocationExpressionSyntax expressionSynt
188
182
// [this.Controls.Add] : new List { button3, this.button1 }
189
183
// [panel1.Controls.Add] : new List { label2 }
190
184
191
- if ( ! _controlsAddIndex . ContainsKey ( container ) )
185
+ if ( ! calculatedContext . ControlsAddIndex . ContainsKey ( container ) )
192
186
{
193
- _controlsAddIndex [ container ] = new List < string > ( ) ;
187
+ calculatedContext . ControlsAddIndex [ container ] = new List < string > ( ) ;
194
188
}
195
189
196
- _controlsAddIndex [ container ] . Add ( controlName ) ;
197
- _controlsAddIndexLocations [ controlName ] = syntax . Parent ! . Parent ! . GetLocation ( ) ;
190
+ calculatedContext . ControlsAddIndex [ container ] . Add ( controlName ) ;
191
+ calculatedContext . ControlsAddIndexLocations [ controlName ] = syntax . Parent ! . Parent ! . GetLocation ( ) ;
198
192
}
199
193
200
- private void ParseTabIndexAssignments ( AssignmentExpressionSyntax expressionSyntax , OperationBlockAnalysisContext context )
194
+ private void ParseTabIndexAssignments ( AssignmentExpressionSyntax expressionSyntax , OperationBlockAnalysisContext context , CalculatedAnalysisContext calculatedContext )
201
195
{
202
196
var propertyNameExpressionSyntax = ( MemberAccessExpressionSyntax ) expressionSyntax . Left ;
203
197
SimpleNameSyntax propertyNameSyntax = propertyNameExpressionSyntax . Name ;
@@ -230,7 +224,7 @@ private void ParseTabIndexAssignments(AssignmentExpressionSyntax expressionSynta
230
224
#pragma warning restore CS8605 // Unboxing a possibly null value.
231
225
232
226
// "button3:0"
233
- _controlsTabIndex [ controlName ] = tabIndexValue ;
227
+ calculatedContext . ControlsTabIndex [ controlName ] = tabIndexValue ;
234
228
}
235
229
236
230
private static string ? GetControlName ( ExpressionSyntax expressionSyntax )
@@ -244,5 +238,14 @@ private void ParseTabIndexAssignments(AssignmentExpressionSyntax expressionSynta
244
238
245
239
_ => null ,
246
240
} ;
241
+
242
+ private sealed class CalculatedAnalysisContext
243
+ {
244
+ // Contains the list of fields and local controls that explicitly set TabIndex properties.
245
+ public Dictionary < string , int > ControlsTabIndex { get ; } = new ( ) ;
246
+ // Contains the list of fields and local controls in order those are added to parent controls.
247
+ public Dictionary < string , List < string > > ControlsAddIndex { get ; } = new ( ) ;
248
+ public Dictionary < string , Location > ControlsAddIndexLocations { get ; } = new ( ) ;
249
+ }
247
250
}
248
251
}
0 commit comments