-
Notifications
You must be signed in to change notification settings - Fork 0
PmdRulesConstraints
Special (likely controversial) rules for constraints in code katas, Coding Dojos and Code Retreats. See http://coderetreat.org/facilitating/activity-catalog Some less extreme rules like PrimitiveObsession or FirstClassCollections are located in the regular codecop.xml rule set.
As an exercise only void methods are allowed. This enforces Tell, Don't Ask design. Only inherited Object methods can be non-void.
This rule is defined by the following XPath expression:
//MethodDeclaration[ @Void='false' and
not(@MethodName='hashCode' or @MethodName='equals' or
@MethodName='toString' or @MethodName='clone' or
@MethodName='compare' or @MethodName='compareTo' )
]
public class Foo {
public int nonVoidMethod(byte b){
return 1;
}
}
As an exercise no void methods are allowed. This is the functional style. Only JUnit tests and custom asserts can have void methods. Allows implementing Runnable.
This rule is defined by the following XPath expression:
//MethodDeclaration[ @Void='true' and
not(../Annotation/MarkerAnnotation/Name[@Image='Test' or @Image='Before' or @Image='After']) and
not(MethodDeclarator[@Image='run' or substring(@Image,1,6)='assert'])
]
public class BadClass {
public void voidMethod(){
}
}
public class OkClass {
public int getIt(){
}
}
As an exercise no loop constructs are allowed. You cannot use for, do or while.
This rule is defined by the following XPath expression:
//ForStatement | //WhileStatement | //DoStatement
public void main() {
for (int i = 0; i < 3; i++) { }
int i = 0;
while (i < 3) { i++; }
do { } while (false);
}
As an exercise no else statement is allowed. This is rule 2 of Object Calisthenics.
This rule is defined by the following XPath expression:
//IfStatement[@Else='true']
public class Foo {
public void main() {
// ok, no else
if (true) { }
// bad, hase else
if (false) { } else { }
}
}
As an exercise no conditional statements are allowed. You cannot use if, while, switch or ?:.
This rule is defined by the following XPath expression:
//IfStatement | //WhileStatement | //ConditionalExpression | //SwitchStatement
public class Foo {
public void main() {
if (true) { }
int i = true ? 1 : 2;
switch(i) { case 0: break; }
while(true) { }
}
}
Do not use getter or setter to enforces encapsulation. This is rule 9 of Object Calisthenics.
This rule is defined by the following XPath expression:
//MethodDeclaration [
@Synchronized='false' and
count(Block/BlockStatement)=1 and
(
(
MethodDeclarator/FormalParameters[count(FormalParameter)=1] and
ResultType[count(Type)=0] and
Block/BlockStatement/Statement/StatementExpression/Expression/PrimaryExpression[
(count(PrimarySuffix/Arguments)=0) and
(count(descendant::Expression)=0)
] and
//AssignmentOperator[@Image='=']
) or (
MethodDeclarator/FormalParameters[count(FormalParameter)=0] and
ResultType/Type[count(ReferenceType)=1] and
Block/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression[
(count(PrimarySuffix/descendant::*)=0) and
(count(descendant::Expression)=0) and
(count(descendant::AllocationExpression)=0)
] and
count(Block/BlockStatement/Statement/ReturnStatement)=1
)
)
]
class AvoidGetterAndSetterExample {
String myVariable;
void setMyVariable(String pMyVariable) { // don't use
myVarialbe = pMyVariable;
}
...
myVariable = "asdfasdf";
}
As an exercise only static methods are allowed. This exaggerates the common mistake to have too many static methods. Only inherited Object methods can be non-static, Comparable and Comparator.
This rule is defined by the following XPath expression:
//MethodDeclaration[ @Static='false' and
not(@MethodName='hashCode' or @MethodName='equals' or
@MethodName='toString' or @MethodName='clone' or
@MethodName='compare' or @MethodName='compareTo' or
@MethodName='run')
]
public class Foo {
public int nonStaticMethod(byte b){
return 1;
}
}
Deprecated
This rule has been renamed or moved. Use instead: ImmutablesOnly
As an exercise only static fields are allowed. This exaggerates the common mistake to have too many static fields.
This rule is defined by the following XPath expression:
//FieldDeclaration[@Static='false']
public class SomeClass {
private String channel; // not ok
private static boolean showIfSearchedInRegion; // ok
}
To enforce giving names meaningful names, every identifier shall be at least x characters. With x in the range of possibly 40. This forces people to let go of things like "num" or "i1" and "i2". This is part 1 of 20/80, see http://manynames.sevensuns.at/technojoy/2014/12/2080-a-coding-dojo-constraint-just-for-fun.html
This rule is defined by the following Java class: org.codecop.pmd.constraints.LooongIdentifiers
package possiblenextmovesreversi;
public class ReversiBoardPosition {
private final int xCoordOfReversiBoard;
private final int yCoordOfReversiBoard;
public ReversiBoardPosition(int xCoordOfReversiBoard, int yCoordOfReversiBoard) {
this.xCoordOfReversiBoard = xCoordOfReversiBoard;
this.yCoordOfReversiBoard = yCoordOfReversiBoard;
}
}
This rule has the following properties:
| Name | Default value | Description |
|---|---|---|
| identifierMinLen | '20' | Minimal length of identifier names |
Keep statements (lines) short, so not many long identifiers can fit in. This is part 2 of 20/80, see http://manynames.sevensuns.at/technojoy/2014/12/2080-a-coding-dojo-constraint-just-for-fun.html
This rule is defined by the following XPath expression:
//BlockStatement[ (@SingleLine='false') or (number(@EndColumn)-number(@BeginColumn) > $lineMaxLen) ] | //FieldDeclaration[ (@SingleLine='false') or (number(@EndColumn)-number(@BeginColumn) > $lineMaxLen) ] | //MethodDeclarator[ (@SingleLine='false') or (number(@EndColumn)-number(@BeginColumn) > $lineMaxLen) ]
This rule has the following properties:
| Name | Default value | Description |
|---|---|---|
| lineMaxLen | '80' | Maximal length of lines |
As an exercise no static fields are allowed. This fights the common mistake to have too many static fields.
This rule is defined by the following XPath expression:
//FieldDeclaration[@Static='true']
public class SomeClass {
private static String channel; // not ok
private boolean showIfSearchedInRegion; // ok
}
As an exercise no static methods are allowed. This fights the common mistake to have too many static methods.
This rule is defined by the following XPath expression:
//MethodDeclaration[@Static='true']
public class Foo {
public static int staticMethod(byte b){
return 1;
}
}
According to POODR, use Maps as single argument in public API to make your code the most extensible without breaking callers because the API never changes. Also use default values in the Maps as much as possible.
This rule is defined by the following XPath expression:
//ConstructorDeclaration[
@Public='true' and
(
FormalParameters[@ParameterCount > 1] |
FormalParameters/FormalParameter/Type/PrimitiveType |
FormalParameters/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[ not (@Image=$paramType) ]
)
]
|
//MethodDeclaration[
@Public='true' and
not(@MethodName='equals' or @MethodName='compare' or @MethodName='compareTo' ) and
(
MethodDeclarator/FormalParameters[@ParameterCount > 1] |
MethodDeclarator/FormalParameters/FormalParameter/Type/PrimitiveType |
MethodDeclarator/FormalParameters/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[ not (@Image=$paramType) ]
)
]
import java.util.Map;
public class Sandbox {
public Sandbox(Map<?, ?> a) { } // public can only have Map
public void run(Map<?, ?> a) { } // public can only have Map
private void later(int i) { } // private can do anything
public boolean equals(Object obj) { return false; } // equals is allowed
}
This rule has the following properties:
| Name | Default value | Description |
|---|---|---|
| paramType | 'Map' | Simple name of the Map type allowed for public arguments |