@@ -35,12 +35,6 @@ public static readonly DiagnosticDescriptor InconsistentTabIndexRuleIdDescriptor
3535 isEnabledByDefault : true ,
3636 "Remove TabIndex assignments and re-order controls in the parent's control collection." ) ;
3737
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-
4438
4539 public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics
4640 => ImmutableArray . Create ( InconsistentTabIndexRuleIdDescriptor , NonNumericTabIndexValueRuleIdDescriptor ) ;
@@ -68,6 +62,7 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
6862 continue ;
6963 }
7064
65+ CalculatedAnalysisContext calculatedContext = new ( ) ;
7166 foreach ( IOperation operation in blockOperation . Operations )
7267 {
7368 switch ( operation . Kind )
@@ -80,14 +75,14 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
8075 if ( expressionStatementOperation . Operation is IOperation invocationOperation &&
8176 invocationOperation . Syntax is InvocationExpressionSyntax expressionSyntax )
8277 {
83- ParseControlAddStatements ( expressionSyntax ) ;
78+ ParseControlAddStatements ( expressionSyntax , calculatedContext ) ;
8479 continue ;
8580 }
8681
8782 // Look for ".TabIndex = <x>"
8883 if ( expressionStatementOperation . Operation is IAssignmentOperation assignmentOperation )
8984 {
90- ParseTabIndexAssignments ( ( AssignmentExpressionSyntax ) assignmentOperation . Syntax , context ) ;
85+ ParseTabIndexAssignments ( ( AssignmentExpressionSyntax ) assignmentOperation . Syntax , context , calculatedContext ) ;
9186 continue ;
9287 }
9388
@@ -99,7 +94,7 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
9994 }
10095 }
10196
102- if ( _controlsTabIndex . Count < 1 )
97+ if ( calculatedContext . ControlsTabIndex . Count < 1 )
10398 {
10499 // No controls explicitly set TabIndex - all good
105100 return ;
@@ -116,25 +111,25 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
116111 // [this.button1:1]
117112 // [label2:0]
118113 Dictionary < string , int > flatControlsAddIndex = new ( ) ;
119- foreach ( string key in _controlsAddIndex . Keys )
114+ foreach ( string key in calculatedContext . ControlsAddIndex . Keys )
120115 {
121- for ( int i = 0 ; i < _controlsAddIndex [ key ] . Count ; i ++ )
116+ for ( int i = 0 ; i < calculatedContext . ControlsAddIndex [ key ] . Count ; i ++ )
122117 {
123- string controlName = _controlsAddIndex [ key ] [ i ] ;
118+ string controlName = calculatedContext . ControlsAddIndex [ key ] [ i ] ;
124119 flatControlsAddIndex [ controlName ] = i ;
125120 }
126121 }
127122
128123 // 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 )
130125 {
131126 if ( ! flatControlsAddIndex . ContainsKey ( key ) )
132127 {
133128 // TODO: assert, diagnostics, etc.
134129 continue ;
135130 }
136131
137- int tabIndex = _controlsTabIndex [ key ] ;
132+ int tabIndex = calculatedContext . ControlsTabIndex [ key ] ;
138133 int addIndex = flatControlsAddIndex [ key ] ;
139134
140135 if ( tabIndex == addIndex )
@@ -144,16 +139,15 @@ private void CodeBlockAction(OperationBlockAnalysisContext context)
144139
145140 var diagnostic = Diagnostic . Create (
146141 descriptor : InconsistentTabIndexRuleIdDescriptor ,
147- location : _controlsAddIndexLocations [ key ] ,
142+ location : calculatedContext . ControlsAddIndexLocations [ key ] ,
148143 properties : new Dictionary < string , string ? > { { "ZOrder" , addIndex . ToString ( ) } , { "TabIndex" , tabIndex . ToString ( ) } } . ToImmutableDictionary ( ) ,
149144 key , addIndex , tabIndex ) ;
150145 context . ReportDiagnostic ( diagnostic ) ;
151146 }
152-
153147 }
154148 }
155149
156- private void ParseControlAddStatements ( InvocationExpressionSyntax expressionSyntax )
150+ private void ParseControlAddStatements ( InvocationExpressionSyntax expressionSyntax , CalculatedAnalysisContext calculatedContext )
157151 {
158152 if ( ! expressionSyntax . Expression . ToString ( ) . EndsWith ( ".Controls.Add" ) )
159153 {
@@ -188,16 +182,16 @@ private void ParseControlAddStatements(InvocationExpressionSyntax expressionSynt
188182 // [this.Controls.Add] : new List { button3, this.button1 }
189183 // [panel1.Controls.Add] : new List { label2 }
190184
191- if ( ! _controlsAddIndex . ContainsKey ( container ) )
185+ if ( ! calculatedContext . ControlsAddIndex . ContainsKey ( container ) )
192186 {
193- _controlsAddIndex [ container ] = new List < string > ( ) ;
187+ calculatedContext . ControlsAddIndex [ container ] = new List < string > ( ) ;
194188 }
195189
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 ( ) ;
198192 }
199193
200- private void ParseTabIndexAssignments ( AssignmentExpressionSyntax expressionSyntax , OperationBlockAnalysisContext context )
194+ private void ParseTabIndexAssignments ( AssignmentExpressionSyntax expressionSyntax , OperationBlockAnalysisContext context , CalculatedAnalysisContext calculatedContext )
201195 {
202196 var propertyNameExpressionSyntax = ( MemberAccessExpressionSyntax ) expressionSyntax . Left ;
203197 SimpleNameSyntax propertyNameSyntax = propertyNameExpressionSyntax . Name ;
@@ -230,7 +224,7 @@ private void ParseTabIndexAssignments(AssignmentExpressionSyntax expressionSynta
230224#pragma warning restore CS8605 // Unboxing a possibly null value.
231225
232226 // "button3:0"
233- _controlsTabIndex [ controlName ] = tabIndexValue ;
227+ calculatedContext . ControlsTabIndex [ controlName ] = tabIndexValue ;
234228 }
235229
236230 private static string ? GetControlName ( ExpressionSyntax expressionSyntax )
@@ -244,5 +238,14 @@ private void ParseTabIndexAssignments(AssignmentExpressionSyntax expressionSynta
244238
245239 _ => null ,
246240 } ;
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+ }
247250 }
248251}
0 commit comments