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
18 changes: 0 additions & 18 deletions analyzers/its/expected/akka.net/S2094-Akka-netstandard2.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,6 @@
"Message": "Remove this empty class, write its code or make it an \u0022interface\u0022.",
"Uri": "https://github.com/SonarSource/sonar-dotnet/blob/master/analyzers/its/Projects/akka.net/src/core/Akka/IO/Inet.cs#L229",
"Location": "Line 229 Position 31-43"
},
{
"Id": "S2094",
"Message": "Remove this empty class, write its code or make it an \u0022interface\u0022.",
"Uri": "https://github.com/SonarSource/sonar-dotnet/blob/master/analyzers/its/Projects/akka.net/src/core/Akka/IO/Tcp.cs#L738",
"Location": "Line 738 Position 22-27"
},
{
"Id": "S2094",
"Message": "Remove this empty class, write its code or make it an \u0022interface\u0022.",
"Uri": "https://github.com/SonarSource/sonar-dotnet/blob/master/analyzers/its/Projects/akka.net/src/core/Akka/Routing/Listeners.cs#L37",
"Location": "Line 37 Position 27-42"
},
{
"Id": "S2094",
"Message": "Remove this empty class, write its code or make it an \u0022interface\u0022.",
"Uri": "https://github.com/SonarSource/sonar-dotnet/blob/master/analyzers/its/Projects/akka.net/src/core/Akka/Routing/RouterMsg.cs#L31",
"Location": "Line 31 Position 27-50"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public abstract class ClassShouldNotBeEmptyBase<TSyntaxKind, TDeclarationSyntax>
KnownType.System_Attribute,
KnownType.System_Exception);

private static readonly IEnumerable<string> IgnoredSuffixes = ["Command", "Event", "Message"];

protected abstract bool IsEmptyAndNotPartial(SyntaxNode node);
protected abstract TDeclarationSyntax GetIfHasDeclaredBaseClassOrInterface(SyntaxNode node);
protected abstract bool HasInterfaceOrGenericBaseClass(TDeclarationSyntax declaration);
Expand All @@ -51,13 +53,17 @@ protected override void Initialize(SonarAnalysisContext context) =>
&& IsEmptyAndNotPartial(c.Node)
&& !HasAnyAttribute(c.Node)
&& !HasConditionalCompilationDirectives(c.Node)
&& !ShouldIgnoreBecauseOfName(identifier)
&& !ShouldIgnoreBecauseOfBaseClassOrInterface(c.Node, c.SemanticModel))
{
c.ReportIssue(Diagnostic.Create(Rule, identifier.GetLocation(), DeclarationTypeKeyword(c.Node)));
}
},
Language.SyntaxKind.ClassAndRecordClassDeclarations);

private static bool ShouldIgnoreBecauseOfName(SyntaxToken identifier) =>
IgnoredSuffixes.Any(identifier.ValueText.EndsWith);

private bool ShouldIgnoreBecauseOfBaseClassOrInterface(SyntaxNode node, SemanticModel model) =>
GetIfHasDeclaredBaseClassOrInterface(node) is { } declaration
&& (HasInterfaceOrGenericBaseClass(declaration) || ShouldIgnoreType(declaration, model));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,16 @@ class ImplementsMarker: IMarker { } // Compliant - implements a marker
struct EmptyStruct { } // Compliant - this rule only deals with classes

enum EmptyEnum { } // Compliant - this rule only deals with classes

class SomeCommand { } // Compliant, ignored because of the suffix
class SomeEvent { } // Compliant, ignored because of the suffix
class SomeMessage { } // Compliant, ignored because of the suffix
class Some_Command { } // Compliant, ignored because of the suffix
class Someevent { } // Noncompliant
class SOMEMESSAGE { } // Noncompliant
class SomeCommandHandler { } // Noncompliant
class MessageHandler { } // Noncompliant
class Command { } // Compliant, ignored because of the suffix
class Event { } // Compliant, ignored because of the suffix
class Message { } // Compliant, ignored because of the suffix
}