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() {