Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/Rules/MA0051.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Source: [MethodShouldNotBeTooLongAnalyzer.cs](https://github.com/meziantou/Mezia

Long methods are harder to understand. You should refactor them when possible.

The rule reports methods, local functions, constructors, destructors, operators, conversion operators, and the accessors and expression bodies of properties, indexers, and events.

You can configure the rule using an `.editorconfig` file:

````editorconfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public override void Initialize(AnalysisContext context)
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.LocalFunctionStatement);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.PropertyDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.IndexerDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.EventDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.OperatorDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.ConversionOperatorDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.ConstructorDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.DestructorDeclaration);
}
Expand All @@ -50,15 +54,27 @@ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context)
break;

case PropertyDeclarationSyntax node:
if (node.AccessorList is not null)
{
foreach (var accessor in node.AccessorList.Accessors)
{
AnalyzeNode(context, accessor.Body, accessor.Keyword);
AnalyzeNode(context, accessor.ExpressionBody, accessor.Keyword);
}
}
AnalyzeNode(context, node.ExpressionBody, node.Identifier);
AnalyzeAccessors(context, node.AccessorList);
break;

case IndexerDeclarationSyntax node:
AnalyzeNode(context, node.ExpressionBody, node.ThisKeyword);
AnalyzeAccessors(context, node.AccessorList);
break;

case EventDeclarationSyntax node:
AnalyzeAccessors(context, node.AccessorList);
break;

case OperatorDeclarationSyntax node:
AnalyzeNode(context, node.Body, node.OperatorToken);
AnalyzeNode(context, node.ExpressionBody, node.OperatorToken);
break;

case ConversionOperatorDeclarationSyntax node:
AnalyzeNode(context, node.Body, node.ImplicitOrExplicitKeyword);
AnalyzeNode(context, node.ExpressionBody, node.ImplicitOrExplicitKeyword);
break;

case ConstructorDeclarationSyntax node:
Expand All @@ -73,6 +89,18 @@ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context)
}
}

private static void AnalyzeAccessors(SyntaxNodeAnalysisContext context, AccessorListSyntax? accessorList)
{
if (accessorList is null)
return;

foreach (var accessor in accessorList.Accessors)
{
AnalyzeNode(context, accessor.Body, accessor.Keyword);
AnalyzeNode(context, accessor.ExpressionBody, accessor.Keyword);
}
}

private static void AnalyzeNode(SyntaxNodeAnalysisContext context, SyntaxNode? node, SyntaxToken reportNode)
{
if (node is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,166 @@ int Property
return test.RunAsync();
}

[Fact]
public Task TooLongProperty_ExpressionBody_Lines()
{
var test = CreateTest(("MA0051.maximum_lines_per_method", "1"));
test.TestCode = """
public class Test
{
int {|MA0051:Property|} => 0 +
1 +
2;
}
""";

return test.RunAsync();
}

[Fact]
public Task ValidProperty_ExpressionBody_Lines()
{
var test = CreateTest(("MA0051.maximum_lines_per_method", "2"));
test.TestCode = """
public class Test
{
int Property => 0 +
1 +
2;
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongIndexer_ExpressionBody_Lines()
{
var test = CreateTest(("MA0051.maximum_lines_per_method", "1"));
test.TestCode = """
public class Test
{
int {|MA0051:this|}[int index] => 0 +
1 +
2;
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongIndexerAccessors_Statements()
{
var test = CreateTest(("MA0051.maximum_statements_per_method", "2"));
test.TestCode = """
public class Test
{
int this[int index]
{
{|MA0051:get|}
{
var a = 0;var b = 0;
return a + b;
}
}
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongEventAccessors_Statements()
{
var test = CreateTest(("MA0051.maximum_statements_per_method", "2"));
test.TestCode = """
using System;
public class Test
{
event EventHandler Sample
{
{|MA0051:add|}
{
var a = 0;var b = 0;
_ = a + b;
}
remove { }
}
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongOperator_Statements()
{
var test = CreateTest(("MA0051.maximum_statements_per_method", "2"));
test.TestCode = """
public class Test
{
public static Test operator {|MA0051:+|}(Test a, Test b)
{
var c = 0;var d = 0;var e = 0;
return null;
}
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongOperator_ExpressionBody_Lines()
{
var test = CreateTest(("MA0051.maximum_lines_per_method", "1"));
test.TestCode = """
public class Test
{
public static int operator {|MA0051:+|}(Test a, Test b) => 0 +
1 +
2;
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongConversionOperator_ExpressionBody_Lines()
{
var test = CreateTest(("MA0051.maximum_lines_per_method", "1"));
test.TestCode = """
public class Test
{
public static {|MA0051:implicit|} operator int(Test a) => 0 +
1 +
2;
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongConversionOperator_Statements()
{
var test = CreateTest(("MA0051.maximum_statements_per_method", "2"));
test.TestCode = """
public class Test
{
public static {|MA0051:explicit|} operator int(Test a)
{
var b = 0;var c = 0;
return b + c;
}
}
""";

return test.RunAsync();
}

[Fact]
public Task TooLongConstructor_Statements()
{
Expand Down