From de0f1205671281679866e92edd9337a7416409e6 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sun, 2 Feb 2020 15:53:19 +0100 Subject: [PATCH] Remove empty line between documentation comment and declaration (RCS1036) --- .../RemoveRedundantEmptyLineAnalyzer.cs | 44 ++++++++++++++----- .../RCS1036RemoveRedundantEmptyLineTests.cs | 23 ++++++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/Analyzers/CSharp/Analysis/RemoveRedundantEmptyLineAnalyzer.cs b/src/Analyzers/CSharp/Analysis/RemoveRedundantEmptyLineAnalyzer.cs index 279d34752f..7a031d9dfa 100644 --- a/src/Analyzers/CSharp/Analysis/RemoveRedundantEmptyLineAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/RemoveRedundantEmptyLineAnalyzer.cs @@ -45,15 +45,15 @@ public override void Initialize(AnalysisContext context) context.RegisterSyntaxNodeAction(AnalyzeFixedStatement, SyntaxKind.FixedStatement); context.RegisterSyntaxNodeAction(AnalyzeAccessorList, SyntaxKind.AccessorList); - context.RegisterSyntaxNodeAction(AnalyzeBlock, SyntaxKind.Block); + context.RegisterSyntaxNodeAction(AnalyzeSingleLineDocumentationCommentTrivia, SyntaxKind.SingleLineDocumentationCommentTrivia); context.RegisterSyntaxNodeAction(AnalyzeInitializer, SyntaxKind.ArrayInitializerExpression); context.RegisterSyntaxNodeAction(AnalyzeInitializer, SyntaxKind.CollectionInitializerExpression); context.RegisterSyntaxNodeAction(AnalyzeInitializer, SyntaxKind.ObjectInitializerExpression); } - public static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context) + private static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context) { var classDeclaration = (ClassDeclarationSyntax)context.Node; @@ -64,7 +64,7 @@ public static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context) classDeclaration.CloseBraceToken); } - public static void AnalyzeStructDeclaration(SyntaxNodeAnalysisContext context) + private static void AnalyzeStructDeclaration(SyntaxNodeAnalysisContext context) { var structDeclaration = (StructDeclarationSyntax)context.Node; @@ -75,7 +75,7 @@ public static void AnalyzeStructDeclaration(SyntaxNodeAnalysisContext context) structDeclaration.CloseBraceToken); } - public static void AnalyzeInterfaceDeclaration(SyntaxNodeAnalysisContext context) + private static void AnalyzeInterfaceDeclaration(SyntaxNodeAnalysisContext context) { var interfaceDeclaration = (InterfaceDeclarationSyntax)context.Node; @@ -86,7 +86,7 @@ public static void AnalyzeInterfaceDeclaration(SyntaxNodeAnalysisContext context interfaceDeclaration.CloseBraceToken); } - public static void AnalyzeNamespaceDeclaration(SyntaxNodeAnalysisContext context) + private static void AnalyzeNamespaceDeclaration(SyntaxNodeAnalysisContext context) { var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node; @@ -115,7 +115,7 @@ public static void AnalyzeNamespaceDeclaration(SyntaxNodeAnalysisContext context AnalyzeEnd(context, members.Last(), namespaceDeclaration.CloseBraceToken); } - public static void AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context) + private static void AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context) { var switchStatement = (SwitchStatementSyntax)context.Node; @@ -128,7 +128,7 @@ public static void AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context) } } - public static void AnalyzeTryStatement(SyntaxNodeAnalysisContext context) + private static void AnalyzeTryStatement(SyntaxNodeAnalysisContext context) { var tryStatement = (TryStatementSyntax)context.Node; @@ -157,7 +157,7 @@ public static void AnalyzeTryStatement(SyntaxNodeAnalysisContext context) } } - public static void AnalyzeElseClause(SyntaxNodeAnalysisContext context) + private static void AnalyzeElseClause(SyntaxNodeAnalysisContext context) { var elseClause = (ElseClauseSyntax)context.Node; @@ -344,7 +344,7 @@ private static void AnalyzeDeclaration( } } - public static void AnalyzeBlock(SyntaxNodeAnalysisContext context) + private static void AnalyzeBlock(SyntaxNodeAnalysisContext context) { var block = (BlockSyntax)context.Node; @@ -361,7 +361,29 @@ public static void AnalyzeBlock(SyntaxNodeAnalysisContext context) } } - public static void AnalyzeInitializer(SyntaxNodeAnalysisContext context) + private static void AnalyzeSingleLineDocumentationCommentTrivia(SyntaxNodeAnalysisContext context) + { + var comment = (DocumentationCommentTriviaSyntax)context.Node; + + if (comment is IStructuredTriviaSyntax structuredTrivia) + { + SyntaxTrivia trivia = structuredTrivia.ParentTrivia; + SyntaxTriviaList leadingTrivia = trivia.Token.LeadingTrivia; + + int index = leadingTrivia.IndexOf(trivia); + + if (index >= 0 + && index < leadingTrivia.Count - 1 + && leadingTrivia[index + 1].IsEndOfLineTrivia()) + { + DiagnosticHelpers.ReportDiagnostic(context, + DiagnosticDescriptors.RemoveRedundantEmptyLine, + leadingTrivia[index + 1].GetLocation()); + } + } + } + + private static void AnalyzeInitializer(SyntaxNodeAnalysisContext context) { var initializer = (InitializerExpressionSyntax)context.Node; @@ -417,7 +439,7 @@ bool IsExpectedTrailingTrivia(SyntaxTriviaList triviaList) } } - public static void AnalyzeAccessorList(SyntaxNodeAnalysisContext context) + private static void AnalyzeAccessorList(SyntaxNodeAnalysisContext context) { var accessorList = (AccessorListSyntax)context.Node; diff --git a/src/Tests/Analyzers.Tests/RCS1036RemoveRedundantEmptyLineTests.cs b/src/Tests/Analyzers.Tests/RCS1036RemoveRedundantEmptyLineTests.cs index d2607039af..a61bf7a7d9 100644 --- a/src/Tests/Analyzers.Tests/RCS1036RemoveRedundantEmptyLineTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1036RemoveRedundantEmptyLineTests.cs @@ -197,6 +197,29 @@ void M() "); } + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveRedundantEmptyLine)] + public async Task Test_EmptyLineAfterDocComment() + { + await VerifyDiagnosticAndFixAsync(@" +class C +{ + /// +[| +|] void M() + { + } +} +", @" +class C +{ + /// + void M() + { + } +} +"); + } + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveRedundantEmptyLine)] public async Task TestNoDiagnostic_ObjectInitializer() {