This rule is defined by the following XPath expression:
//ClassOrInterfaceDeclaration[@Abstract = 'true'] /ClassOrInterfaceBody /ClassOrInterfaceBodyDeclaration /MethodDeclaration[@Abstract = 'false' and @Native = 'false'] [ ( boolean(./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral) = 'true' ) or ( boolean(./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal[@Image = '0']) = 'true' ) or ( boolean(./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal[string-length(@Image) = 2]) = 'true' ) or ( ( (boolean(./Block/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal[@Image = '']) = 'true' ) ) and ( count (./Block/*) = 1 ) ) or ( count (./Block/*) = 0 ) ]
Example:
public abstract class ShouldBeAbstract { public Object couldBeAbstract() { // Should be abstract method ? return null; } public void couldBeAbstract() { } }