@@ -192,30 +192,33 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi
192192 if ( ! members [ i - 1 ] . ContainsDiagnostics && ! members [ i ] . ContainsDiagnostics )
193193 {
194194 // Report if
195- // the previous declaration spans across multiple lines
195+ // the current declaration is not a field declaration
196196 // or the previous declaration is of different type
197- // or the current declaration has documentation
198- // or the current declaration is not a field declaration,
199- if ( ! members [ i - 1 ] . IsKind ( members [ i ] . Kind ( ) )
200- || ! members [ i ] . IsKind ( SyntaxKind . FieldDeclaration )
201- || IsMultiline ( members [ i - 1 ] ) )
197+ // or the previous declaration spans across multiple lines
198+ //
199+ // Note that the order of checking is important, as the call to IsMultiLine requires a FieldDeclarationSyntax,
200+ // something that can only be guaranteed if the first two checks fail.
201+ if ( ! members [ i ] . IsKind ( SyntaxKind . FieldDeclaration )
202+ || ! members [ i - 1 ] . IsKind ( members [ i ] . Kind ( ) )
203+ || IsMultiline ( ( FieldDeclarationSyntax ) members [ i - 1 ] ) )
202204 {
203205 ReportIfThereIsNoBlankLine ( context , members [ i - 1 ] , members [ i ] ) ;
204206 }
205207 }
206208 }
207209 }
208210
209- private static bool IsMultiline ( SyntaxNode node )
211+ private static bool IsMultiline ( FieldDeclarationSyntax fieldDeclaration )
210212 {
211- var lineSpan = node . GetLineSpan ( ) ;
212- var attributes = GetAttributes ( node ) ;
213+ var lineSpan = fieldDeclaration . GetLineSpan ( ) ;
214+ var attributeLists = fieldDeclaration . AttributeLists ;
215+
213216 int startLine ;
214217
215- // Exclude attributes when determining if a node spans multiple lines
216- if ( attributes . Count > 0 )
218+ // Exclude attributes when determining if a field declaration spans multiple lines
219+ if ( attributeLists . Count > 0 )
217220 {
218- var lastAttributeSpan = node . SyntaxTree . GetLineSpan ( attributes . Last ( ) . FullSpan ) ;
221+ var lastAttributeSpan = fieldDeclaration . SyntaxTree . GetLineSpan ( attributeLists . Last ( ) . FullSpan ) ;
219222 startLine = lastAttributeSpan . EndLinePosition . Line ;
220223 }
221224 else
@@ -226,6 +229,12 @@ private static bool IsMultiline(SyntaxNode node)
226229 return startLine != lineSpan . EndLinePosition . Line ;
227230 }
228231
232+ private static bool IsMultiline ( AccessorDeclarationSyntax accessorDeclaration )
233+ {
234+ var lineSpan = accessorDeclaration . GetLineSpan ( ) ;
235+ return lineSpan . StartLinePosition . Line != lineSpan . EndLinePosition . Line ;
236+ }
237+
229238 private static void ReportIfThereIsNoBlankLine ( SyntaxNodeAnalysisContext context , SyntaxNode firstNode , SyntaxNode secondNode )
230239 {
231240 if ( XmlCommentHelper . HasDocumentation ( secondNode ) )
@@ -283,52 +292,5 @@ private static bool HasEmptyLine(IEnumerable<SyntaxTrivia> allTrivia)
283292
284293 return false ;
285294 }
286-
287- // copied from Roslyn code, as its inaccessible there
288- // (from Microsoft.CodeAnalysis.CSharp.Extensions.MemberDeclarationSyntaxExtensions)
289- private static SyntaxList < AttributeListSyntax > GetAttributes ( SyntaxNode node )
290- {
291- var memberDeclaration = node as MemberDeclarationSyntax ;
292- if ( memberDeclaration != null )
293- {
294- switch ( memberDeclaration . Kind ( ) )
295- {
296- case SyntaxKind . EnumDeclaration :
297- return ( ( EnumDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
298- case SyntaxKind . EnumMemberDeclaration :
299- return ( ( EnumMemberDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
300- case SyntaxKind . ClassDeclaration :
301- case SyntaxKind . InterfaceDeclaration :
302- case SyntaxKind . StructDeclaration :
303- return ( ( TypeDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
304- case SyntaxKind . DelegateDeclaration :
305- return ( ( DelegateDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
306- case SyntaxKind . FieldDeclaration :
307- return ( ( FieldDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
308- case SyntaxKind . EventFieldDeclaration :
309- return ( ( EventFieldDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
310- case SyntaxKind . ConstructorDeclaration :
311- return ( ( ConstructorDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
312- case SyntaxKind . DestructorDeclaration :
313- return ( ( DestructorDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
314- case SyntaxKind . PropertyDeclaration :
315- return ( ( PropertyDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
316- case SyntaxKind . EventDeclaration :
317- return ( ( EventDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
318- case SyntaxKind . IndexerDeclaration :
319- return ( ( IndexerDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
320- case SyntaxKind . OperatorDeclaration :
321- return ( ( OperatorDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
322- case SyntaxKind . ConversionOperatorDeclaration :
323- return ( ( ConversionOperatorDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
324- case SyntaxKind . MethodDeclaration :
325- return ( ( MethodDeclarationSyntax ) memberDeclaration ) . AttributeLists ;
326- case SyntaxKind . IncompleteMember :
327- return ( ( IncompleteMemberSyntax ) memberDeclaration ) . AttributeLists ;
328- }
329- }
330-
331- return SyntaxFactory . List < AttributeListSyntax > ( ) ;
332- }
333295 }
334296}
0 commit comments