CheckStyle – Enforcing a coding style: part 3

CheckStyle – Enforcing a coding style: part 3

This entry is part 3 of 4 in the series Implementing a Java code style with CheckStyle

The sensible way to make your own ruleset.

As I mentioned in CheckStyle – Enforcing a coding style: part 2, there is a far simpler way to choose your own rules than by manually editing an xml file.

I use the Community edition of Intellij IDEA. Going back a few years however I learnt my first Java code at ITU using Eclipse. To be fair I did try it out when I started programming professionally, but I never really was happy with it so I was rather reluctant to install it just to write some rules. That was a big mistake: the Eclipse Checkstyle (eclipse-cs) plugin for the Eclipse IDE really does a fantastic job of making your own ruleset simple.

Drag the link from the page linked above onto Eclipse to install the plugin. Once it is set up, then Windows –> preferences gives you

Configure eclipse-cs
Configure eclipse-cs

Probably easiest to click copy on one of the bundled rules, give it a name and off you go:

Choose your rules fle
Choose your rules file

Then it is simply a case of going down the list and selecting the rules you wish to apply.

Ticking the boxes
Choosing rules is as easy as clicking in the box

Or is it?

Well it turns out that it is not quite so simple to get things ‘just right.’

It is undoubtedly the fastest way to choose the rules that you wish to apply rather than deleting sections from the CheckstyleChecks file, but I found that it was not so easy to define the level or choose the right options to apply. It also put the rules in a seemingly random order. Once I started trying to use them it was clear that it needed tweaking, and I found this much faster and easier to edit in Intellij IDEA, using the api documentation for guidance. As soon as you start to fix your code you will probably want to make some changes.

As ever I have this love/hate relationship with Javadoc. For now I have set it to ignore.

So my official rules:

 

AlexOnTest.tech / AlexanderOnTesting.com checks
[xml] <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">

<!–
This configuration file was written by the eclipse-cs plugin configuration editor
–>
<!–
Checkstyle-Configuration: AlexOnTest.tech
Description:
My own rules
–>
<module name="Checker">
<!– default severity –>
<property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/>
<!– define the suppression file –>
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/suppressions.xml"/>
</module>
<!– permit suppression annotations –>
<module name="SuppressWarningsFilter"/>
<module name="NewlineAtEndOfFile"/>
<module name="Translation"/>
<!– All length checks as warnings –>
<module name="FileLength">
<property name="severity" value="warning"/>
</module>
<!– no tabs –>
<module name="FileTabCharacter">
<property name="severity" value="error"/>
<property name="eachLine" value="true"/>
</module>
<!– no trailing spaces – except whitespace only lines –>
<module name="RegexpSingleline">
<property name="severity" value="warning"/>
<property name="format" value="[^ \n\t]\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="UniqueProperties"/>
<!– All Javadoc checks currently ignored –>
<module name="JavadocPackage">
<property name="severity" value="ignore"/>
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
</module>
<module name="TreeWalker">
<!– enables @SuppressWarnings annotation –>
<module name="SuppressWarningsHolder"/>
<!– define SuppressionCommentFilter to turn off all checks –>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CHECKSTYLE_OFF"/>
<property name="onCommentFormat" value="CHECKSTYLE_ON"/>
</module>
<!– define SuppressionCommentFilter to turn off defined check (preferred) –>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CSOFF\: ([\w\|]+)"/>
<property name="onCommentFormat" value="CSON\: ([\w\|]+)"/>
<property name="checkFormat" value="$1"/>
</module>
<!– All Javadoc checks currently ignored –>
<module name="JavadocMethod">
<property name="severity" value="ignore"/>
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
</module>
<!– All Javadoc checks currently ignored –>
<module name="JavadocType">
<property name="severity" value="ignore"/>
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
</module>
<!– All Javadoc checks currently ignored –>
<module name="JavadocVariable">
<property name="severity" value="ignore"/>
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
</module>
<!– All Javadoc checks currently ignored –>
<module name="JavadocStyle">
<property name="severity" value="ignore"/>
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
</module>
<!– Naming problems as errors –>
<module name="ConstantName">
<property name="severity" value="error"/>
</module>
<module name="LocalFinalVariableName">
<property name="severity" value="error"/>
</module>
<module name="LocalVariableName">
<property name="severity" value="error"/>
</module>
<module name="MemberName">
<property name="severity" value="error"/>
</module>
<module name="MethodName">
<property name="severity" value="error"/>
</module>
<module name="PackageName">
<property name="severity" value="error"/>
</module>
<module name="ParameterName">
<property name="severity" value="error"/>
<property name="accessModifiers" value="public"/>
</module>
<module name="StaticVariableName">
<property name="severity" value="error"/>
</module>
<module name="TypeName">
<property name="severity" value="error"/>
</module>
<module name="AbstractClassName">
<property name="severity" value="error"/>
</module>
<module name="ClassTypeParameterName">
<property name="severity" value="error"/>
</module>
<!– import checks as errors –>
<module name="AvoidStarImport">
<property name="severity" value="error"/>
</module>
<module name="IllegalImport">
<property name="severity" value="error"/>
</module>
<module name="RedundantImport">
<property name="severity" value="error"/>
</module>
<module name="UnusedImports">
<property name="severity" value="error"/>
<!– do not permit import solely for Javadoc –>
<property name="processJavadoc" value="false"/>
</module>
<module name="ImportOrder">
<!– Match intellij IDEA defaults –>
<property name="severity" value="error"/>
<property name="groups" value="*,javax,java"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<!– All length checks as warnings –>
<module name="LineLength">
<property name="severity" value="warning"/>
<property name="max" value="120"/>
<property name="tabWidth" value="4"/>
</module>
<module name="MethodLength">
<property name="severity" value="warning"/>
</module>
<module name="ParameterNumber">
<property name="severity" value="warning"/>
</module>
<module name="EmptyForIteratorPad"/>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<module name="AvoidInlineConditionals"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="HiddenField">
<!– allow constructor or setter parameter with same name as field –>
<property name="ignoreConstructorParameter" value="true"/>
<property name="ignoreSetter" value="true"/>
</module>
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber"/>
<module name="MissingSwitchDefault"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<module name="DesignForExtension"/>
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier"/>
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
<module name="MethodCount">
<property name="severity" value="warning"/>
<property name="tokens" value="CLASS_DEF,ENUM_CONSTANT_DEF,ENUM_DEF,INTERFACE_DEF,ANNOTATION_DEF"/>
</module>
<module name="EmptyForInitializerPad">
<property name="option" value="space"/>
</module>
<module name="EmptyLineSeparator">
<property name="allowMultipleEmptyLines" value="false"/>
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
</module>
<module name="SingleSpaceSeparator"/>
<module name="EmptyCatchBlock"/>
<module name="CovariantEquals"/>
<module name="DefaultComesLast"/>
<module name="DeclarationOrder"/>
<module name="EqualsAvoidNull"/>
<module name="ExplicitInitialization"/>
<module name="FallThrough"/>
<module name="FinalLocalVariable">
<property name="tokens" value="PARAMETER_DEF,VARIABLE_DEF"/>
</module>
<module name="IllegalCatch"/>
<module name="IllegalThrows"/>
<module name="IllegalType">
<property name="tokens" value="METHOD_DEF,PARAMETER_DEF,VARIABLE_DEF"/>
</module>
<module name="ModifiedControlVariable"/>
<module name="MultipleStringLiterals">
<property name="allowedDuplicates" value="2"/>
</module>
<module name="MultipleVariableDeclarations"/>
<module name="NestedForDepth">
<property name="max" value="2"/>
</module>
<module name="NestedIfDepth">
<property name="max" value="2"/>
</module>
<module name="NestedTryDepth"/>
<module name="NoClone"/>
<module name="PackageDeclaration"/>
<module name="ParameterAssignment"/>
<module name="ReturnCount">
<property name="max" value="5"/>
</module>
<module name="StringLiteralEquality"/>
<module name="ArrayTrailingComma"/>
<module name="UnnecessaryParentheses"/>
<module name="OneStatementPerLine"/>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="MutableException"/>
<module name="ThrowsCount"/>
<module name="OneTopLevelClass"/>
<module name="BooleanExpressionComplexity"/>
<module name="ClassDataAbstractionCoupling"/>
<module name="ClassFanOutComplexity"/>
<module name="CyclomaticComplexity"/>
<module name="NPathComplexity"/>
<module name="Indentation"/>
<module name="CommentsIndentation"/>
<module name="TrailingComment"/>
<module name="OuterTypeFilename"/>
<module name="AnnotationLocation">
<property name="severity" value="error"/>
</module>
</module>
</module>
[/xml]

 

Progress made:

  • Installed Eclipse and the eclipse-cs plugin.

Lessons learnt:

  • Sometimes even a tool you don’t like will save you a lot of time.
  • Eclipse and the eclipse-cs plugin really are by far the quickest way to do this and have ample explanation.
  • Don’t ignore the wisdom of StackOverflow.
Series Navigation<< CheckStyle – Enforcing a coding style: part 2CheckStyle – Enforcing a coding style: part 4 >>
Comments are closed.