From bb9d80bb7e6fba94e90fbec9f3895cc4a0ffc18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rald=20Barr=C3=A9?= Date: Wed, 19 Jul 2023 19:41:24 -0400 Subject: [PATCH] MA0051 supports skip_local_functions when counting lines --- .../Rules/MethodShouldNotBeTooLongAnalyzer.cs | 12 +++++ .../MethodShouldNotBeTooLongAnalyzerTests.cs | 48 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/Meziantou.Analyzer/Rules/MethodShouldNotBeTooLongAnalyzer.cs b/src/Meziantou.Analyzer/Rules/MethodShouldNotBeTooLongAnalyzer.cs index 75d700230..46c3a452d 100644 --- a/src/Meziantou.Analyzer/Rules/MethodShouldNotBeTooLongAnalyzer.cs +++ b/src/Meziantou.Analyzer/Rules/MethodShouldNotBeTooLongAnalyzer.cs @@ -84,6 +84,18 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context, SyntaxNode? n var location = node.GetLocation(); var lineSpan = location.GetLineSpan(); var lines = lineSpan.EndLinePosition.Line - lineSpan.StartLinePosition.Line; + + if (GetSkipLocalFunctions(context)) + { + var localFunctions = node.DescendantNodes(node => !node.IsKind(SyntaxKind.LocalFunctionStatement)).Where(node => node.IsKind(SyntaxKind.LocalFunctionStatement)); + foreach (var localFunction in localFunctions) + { + var functionLocation = localFunction.GetLocation().GetLineSpan(); + lines -= functionLocation.EndLinePosition.Line - functionLocation.StartLinePosition.Line; + } + } + + if (lines > maximumLines) { context.ReportDiagnostic(s_rule, reportNode, $"{lines} lines; maximum allowed: {maximumLines}"); diff --git a/tests/Meziantou.Analyzer.Test/Rules/MethodShouldNotBeTooLongAnalyzerTests.cs b/tests/Meziantou.Analyzer.Test/Rules/MethodShouldNotBeTooLongAnalyzerTests.cs index 55b71c335..02256c9bf 100644 --- a/tests/Meziantou.Analyzer.Test/Rules/MethodShouldNotBeTooLongAnalyzerTests.cs +++ b/tests/Meziantou.Analyzer.Test/Rules/MethodShouldNotBeTooLongAnalyzerTests.cs @@ -88,6 +88,54 @@ await CreateProjectBuilder() .ValidateAsync(); } + [Fact] + public async Task TooLong_SkipLocalFunction() + { + const string SourceCode = @" +public class Test +{ + void [||]Method() + { + var a = 0; + var b = 0; + var c = 0; + void A() + { + void B() { } + } + } +}"; + await CreateProjectBuilder() + .WithSourceCode(SourceCode) + .AddAnalyzerConfiguration("MA0051.maximum_lines_per_method", "5") + .AddAnalyzerConfiguration("MA0051.skip_local_functions", "false") + .ValidateAsync(); + } + + [Fact] + public async Task ValidMethod_SkipLocalFunction() + { + const string SourceCode = @" +public class Test +{ + void Method() + { + var a = 0; + var b = 0; + var c = 0; + void A() + { + void B() { } + } + } +}"; + await CreateProjectBuilder() + .WithSourceCode(SourceCode) + .AddAnalyzerConfiguration("MA0051.maximum_lines_per_method", "5") + .AddAnalyzerConfiguration("MA0051.skip_local_functions", "true") + .ValidateAsync(); + } + [Fact] public void CountStatement_ForLoop() {