@@ -58,7 +58,7 @@ private static void AnalyzeUnsafeStatement(SyntaxNodeAnalysisContext context)
5858 if ( ! unsafeStatement . Block . Statements . Any ( ) )
5959 return ;
6060
61- if ( ! ParentDeclarationsContainsUnsafeModifier ( unsafeStatement ) )
61+ if ( ! AncestorContainsUnsafeModifier ( unsafeStatement . Parent ) )
6262 return ;
6363
6464 DiagnosticHelpers . ReportDiagnostic ( context , DiagnosticRules . UnnecessaryUnsafeContext , unsafeStatement . UnsafeKeyword ) ;
@@ -68,26 +68,7 @@ private static void AnalyzeLocalFunctionStatement(SyntaxNodeAnalysisContext cont
6868 {
6969 var localFunctionStatement = ( LocalFunctionStatementSyntax ) context . Node ;
7070
71- SyntaxTokenList modifiers = localFunctionStatement . Modifiers ;
72-
73- int index = modifiers . IndexOf ( SyntaxKind . UnsafeKeyword ) ;
74-
75- if ( index == - 1 )
76- return ;
77-
78- SyntaxNode parent = localFunctionStatement . Parent ;
79-
80- SyntaxDebug . Assert ( parent . IsKind ( SyntaxKind . Block ) , parent ) ;
81-
82- if ( parent is not BlockSyntax )
83- return ;
84-
85- parent = parent . Parent ;
86-
87- if ( ! ParentDeclarationsContainsUnsafeModifier ( parent ) )
88- return ;
89-
90- DiagnosticHelpers . ReportDiagnostic ( context , DiagnosticRules . UnnecessaryUnsafeContext , modifiers [ index ] ) ;
71+ AnalyzeMemberDeclaration ( context , localFunctionStatement , localFunctionStatement . Modifiers ) ;
9172 }
9273
9374 private static void AnalyzeTypeDeclaration ( SyntaxNodeAnalysisContext context )
@@ -176,102 +157,45 @@ private static void AnalyzeIndexerDeclaration(SyntaxNodeAnalysisContext context)
176157
177158 private static void AnalyzeMemberDeclaration (
178159 SyntaxNodeAnalysisContext context ,
179- MemberDeclarationSyntax memberDeclaration ,
160+ SyntaxNode node ,
180161 SyntaxTokenList modifiers )
181162 {
182163 int index = modifiers . IndexOf ( SyntaxKind . UnsafeKeyword ) ;
183164
184165 if ( index == - 1 )
185166 return ;
186167
187- if ( ! ParentTypeDeclarationsContainsUnsafeModifier ( memberDeclaration ) )
168+ if ( ! AncestorContainsUnsafeModifier ( node . Parent ) )
188169 return ;
189170
190171 DiagnosticHelpers . ReportDiagnostic ( context , DiagnosticRules . UnnecessaryUnsafeContext , modifiers [ index ] ) ;
191172 }
192173
193- private static bool ParentDeclarationsContainsUnsafeModifier ( UnsafeStatementSyntax unsafeStatement )
174+ private static bool AncestorContainsUnsafeModifier ( SyntaxNode node )
194175 {
195- SyntaxNode parent = unsafeStatement . Parent ;
196-
197- while ( parent is not null )
176+ while ( node is not null )
198177 {
199- SyntaxKind kind = parent . Kind ( ) ;
200-
201- if ( kind == SyntaxKind . UnsafeStatement )
202- {
203- return true ;
204- }
205- else if ( kind == SyntaxKind . LocalFunctionStatement )
178+ switch ( node )
206179 {
207- break ;
180+ case UnsafeStatementSyntax :
181+ return true ;
182+ case MemberDeclarationSyntax memberDeclarationSyntax :
183+ {
184+ if ( memberDeclarationSyntax . Modifiers . Contains ( SyntaxKind . UnsafeKeyword ) )
185+ return true ;
186+
187+ break ;
188+ }
189+ case LocalFunctionStatementSyntax localFunctionStatement :
190+ {
191+ if ( localFunctionStatement . Modifiers . Contains ( SyntaxKind . UnsafeKeyword ) )
192+ return true ;
193+
194+ break ;
195+ }
208196 }
209197
210- if ( parent is AccessorDeclarationSyntax )
211- {
212- parent = parent . Parent ;
213-
214- if ( parent is AccessorListSyntax )
215- parent = parent . Parent ;
216-
217- break ;
218- }
219-
220- if ( parent is MemberDeclarationSyntax )
221- break ;
222-
223- parent = parent . Parent ;
224- }
225-
226- return ParentDeclarationsContainsUnsafeModifier ( parent ) ;
227- }
228-
229- private static bool ParentDeclarationsContainsUnsafeModifier ( SyntaxNode node )
230- {
231- while ( node . IsKind ( SyntaxKind . LocalFunctionStatement ) )
232- {
233- var localFunction = ( LocalFunctionStatementSyntax ) node ;
234-
235- if ( localFunction . Modifiers . Contains ( SyntaxKind . UnsafeKeyword ) )
236- return true ;
237-
238198 node = node . Parent ;
239-
240- SyntaxDebug . Assert ( node . IsKind ( SyntaxKind . Block ) , node ) ;
241-
242- if ( ! node . IsKind ( SyntaxKind . Block ) )
243- break ;
244-
245- node = node . Parent ;
246- }
247-
248- SyntaxDebug . Assert ( node is MemberDeclarationSyntax , node ) ;
249-
250- if ( node is MemberDeclarationSyntax memberDeclaration )
251- {
252- if ( SyntaxInfo . ModifierListInfo ( memberDeclaration ) . IsUnsafe )
253- return true ;
254-
255- return ParentTypeDeclarationsContainsUnsafeModifier ( memberDeclaration ) ;
256- }
257-
258- return false ;
259- }
260-
261- private static bool ParentTypeDeclarationsContainsUnsafeModifier ( MemberDeclarationSyntax memberDeclaration )
262- {
263- SyntaxNode parent = memberDeclaration . Parent ;
264-
265- while ( parent . IsKind (
266- SyntaxKind . ClassDeclaration ,
267- SyntaxKind . StructDeclaration ,
268- SyntaxKind . RecordStructDeclaration ,
269- SyntaxKind . InterfaceDeclaration ) )
270- {
271- if ( ( ( TypeDeclarationSyntax ) parent ) . Modifiers . Contains ( SyntaxKind . UnsafeKeyword ) )
272- return true ;
273-
274- parent = parent . Parent ;
275199 }
276200
277201 return false ;
0 commit comments