diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1516UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1516UnitTests.cs index 7ec69ac6c..018f167e6 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1516UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1516UnitTests.cs @@ -32,7 +32,6 @@ public class Bar public string Test3; public string TestProperty1 { get; set; } - public string TestProperty2 { get; set; } /// /// A summary. @@ -149,7 +148,6 @@ class Foo { } Diagnostic().WithLocation(2, 1), Diagnostic().WithLocation(5, 1), Diagnostic().WithLocation(12, 1), - Diagnostic().WithLocation(13, 1), Diagnostic().WithLocation(18, 1), Diagnostic().WithLocation(24, 1), Diagnostic().WithLocation(29, 1), diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs index 2ac731989..dc2f996e6 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1516ElementsMustBeSeparatedByBlankLine.cs @@ -345,34 +345,48 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi if (!members[i - 1].ContainsDiagnostics && !members[i].ContainsDiagnostics) { - // Report if - // the current declaration is not a field declaration - // or the previous declaration is of different type - // or the previous declaration spans across multiple lines - // - // Note that the order of checking is important, as the call to IsMultiLine requires a FieldDeclarationSyntax, - // something that can only be guaranteed if the first two checks fail. - if (!members[i].IsKind(SyntaxKind.FieldDeclaration) - || !members[i - 1].IsKind(members[i].Kind()) - || IsMultiline((FieldDeclarationSyntax)members[i - 1])) + // Don't report if + // the previous declaration is of the same type + // AND it is either + // - a single line field declaration where the previous field is single line + // or + // - a single line property declaration where the previous property is single line + if (members[i - 1].IsKind(members[i].Kind()) + && ((members[i].IsKind(SyntaxKind.FieldDeclaration) + && !IsMultiline((FieldDeclarationSyntax)members[i]) + && !IsMultiline((FieldDeclarationSyntax)members[i - 1])) + || (members[i].IsKind(SyntaxKind.PropertyDeclaration) + && !IsMultiline((PropertyDeclarationSyntax)members[i]) + && !IsMultiline((PropertyDeclarationSyntax)members[i - 1])))) { - ReportIfThereIsNoBlankLine(context, members[i - 1], members[i]); + continue; } + + ReportIfThereIsNoBlankLine(context, members[i - 1], members[i]); } } } private static bool IsMultiline(FieldDeclarationSyntax fieldDeclaration) { - var lineSpan = fieldDeclaration.GetLineSpan(); - var attributeLists = fieldDeclaration.AttributeLists; + return IsMultiline(fieldDeclaration, fieldDeclaration.AttributeLists); + } + + private static bool IsMultiline(PropertyDeclarationSyntax propertyDeclaration) + { + return IsMultiline(propertyDeclaration, propertyDeclaration.AttributeLists); + } + + private static bool IsMultiline(MemberDeclarationSyntax memberDeclaration, SyntaxList attributeLists) + { + var lineSpan = memberDeclaration.GetLineSpan(); int startLine; // Exclude attributes when determining if a field declaration spans multiple lines if (attributeLists.Count > 0) { - var lastAttributeSpan = fieldDeclaration.SyntaxTree.GetLineSpan(attributeLists.Last().FullSpan); + var lastAttributeSpan = memberDeclaration.SyntaxTree.GetLineSpan(attributeLists.Last().FullSpan); startLine = lastAttributeSpan.EndLinePosition.Line; } else