StarChart-Labs / corona-ide

A exploratory project to build a lighter, simpler Java IDE - or learn trying!
Eclipse Public License 1.0
3 stars 1 forks source link

Add Checkstyle Code Quality Checking #78

Open romeara opened 5 years ago

romeara commented 5 years ago

Add Checkstyle to the build process to increase and enforce continued code quality checks on the library. This can be done by adding Checkstyle to the Gradle setup, and defining a rules file.

Based on experience with Alloy, the Gradle modifications will look like (per project to apply to):

apply plugin: 'checkstyle'

checkstyle {
   configFile = rootProject.file('config/checkstyle/checkstyle.xml')
   configProperties = [ 'checkstyle.config.dir' : rootProject.file('config/checkstyle') ]
   toolVersion = '8.18'
}

task checkstyleAll{}

tasks.withType(Checkstyle).all { checkstyleTask -> checkstyleAll.dependsOn checkstyleTask }

check.dependsOn checkstyleAll

And the starting rules file could be:

<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
          "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">

<!-- Doc for the modules used here may be found at http://checkstyle.sourceforge.net/checks.html -->
<module name = "Checker">
    <property name="charset" value="UTF-8"/>

    <property name="fileExtensions" value="java"/>

    <!-- Checks for whitespace                               -->
    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
    <module name="FileTabCharacter">
        <property name="eachLine" value="true"/>
    </module>

    <module name="TreeWalker">
        <!-- Checks that file name = outer class name -->
        <module name="OuterTypeFilename"/>
        <!-- Checks for unnecessary use of octal/unicode escape characters, which are less readable -->
        <module name="IllegalTokenText">
            <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
            <property name="format"
                      value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
            <property name="message"
                      value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
        </module>
        <!-- Prevents using the unicode escape sequence, which is less reasable -->
        <module name="AvoidEscapedUnicodeCharacters">
            <property name="allowEscapesForControlCharacters" value="true"/>
            <property name="allowByTailComment" value="true"/>
            <property name="allowNonPrintableEscapes" value="true"/>
        </module>
        <!-- Checks for long lines - Long lines are hard to read in printouts or if developers have limited screen space for the source code -->
        <module name="LineLength">
            <property name="max" value="250"/>
            <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
        </module>
        <!-- Ensures only one top-level class is defined per file, which aids in clarity when navigating a project's APIs -->
        <module name="OneTopLevelClass"/>
        <!-- Checks that import and package statements are not wrapped for readability -->
        <module name="NoLineWrap"/>
        <!-- EmptyBlock and EmptyCatchBlock - Checks for empty control statements, which avoids logic errors and silent removal of error tracking information -->
        <module name="EmptyBlock">
            <property name="option" value="TEXT"/>
            <property name="tokens"
                      value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
        </module>
        <module name="EmptyCatchBlock">
            <property name="exceptionVariableName" value="expected"/>
        </module>
        <!-- NeedsBraces, LeftCurly, and RightCurly check that braces are present for control statements, and are consistently placed within the code base -->
        <module name="NeedBraces"/>
        <module name="LeftCurly"/>
        <module name="RightCurly">
            <property name="id" value="RightCurlySame"/>
            <property name="tokens"
                      value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
                    LITERAL_DO"/>
        </module>
        <module name="RightCurly">
            <property name="id" value="RightCurlyAlone"/>
            <property name="option" value="alone"/>
            <property name="tokens"
                      value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
                    INSTANCE_INIT"/>
        </module>
        <!-- Checks that whitespace is consistently used around things like braces and other constructs -->
        <module name="WhitespaceAround">
            <property name="allowEmptyConstructors" value="true"/>
            <property name="allowEmptyMethods" value="true"/>
            <property name="allowEmptyTypes" value="true"/>
            <property name="allowEmptyLoops" value="true"/>
            <message key="ws.notFollowed"
                     value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
            <message key="ws.notPreceded"
                     value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
        </module>
        <!-- Checks that only one statement (; terminated command) is present on each line for more consistent readability -->
        <module name="OneStatementPerLine"/>
        <!-- Checks that variables are each declared in a separate statement and line for more consistent readability -->
        <module name="MultipleVariableDeclarations"/>
        <!-- Enforces a consistent methodology of array declaration within the application -->
        <module name="ArrayTypeStyle"/>
        <!-- Checks for missing "default" clauses in switch statements, as this is a logic bugs -->
        <module name="MissingSwitchDefault"/>
        <!-- Checks for switch statements with associated code, but no ending control statement (continue, break, etc), as this is a logic bug -->
        <module name="FallThrough"/>
        <!-- Checks that Long constant values are defined with an upper-case 'L', as opposed to lower-case (lower can easily be confused for a one) -->
        <module name="UpperEll"/>
        <!-- Enforces consistent following of Java Language Specification modifier order guidelines -->
        <module name="ModifierOrder"/>
        <!-- SeparatorWrap enforces consistent styling of line wraps for given characters (newline before or after the character, etc) for readability -->
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapDot"/>
            <property name="tokens" value="DOT"/>
            <property name="option" value="nl"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapComma"/>
            <property name="tokens" value="COMMA"/>
            <property name="option" value="EOL"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapEllipsis"/>
            <property name="tokens" value="ELLIPSIS"/>
            <property name="option" value="EOL"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapArrayDeclarator"/>
            <property name="tokens" value="ARRAY_DECLARATOR"/>
            <property name="option" value="EOL"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapMethodRef"/>
            <property name="tokens" value="METHOD_REF"/>
            <property name="option" value="nl"/>
        </module>
        <!-- PackageName, TypeName, MemberName, ParameterName, CatchParameterName, LocalVariableName, MethodTypeParameterName and MethodName -->
        <!-- Enforce standardized naming patterns for each of the mentioned Java elements -->
        <module name="PackageName">
            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
            <message key="name.invalidPattern"
                     value="Package name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="TypeName">
            <message key="name.invalidPattern"
                     value="Type name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="MemberName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
            <message key="name.invalidPattern"
                     value="Member name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="ParameterName">
            <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
            <message key="name.invalidPattern"
                     value="Parameter name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="CatchParameterName">
            <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
            <message key="name.invalidPattern"
                     value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="LocalVariableName">
            <property name="tokens" value="VARIABLE_DEF"/>
            <property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
            <message key="name.invalidPattern"
                     value="Local variable name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="MethodTypeParameterName">
            <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
            <message key="name.invalidPattern"
                     value="Method type name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <module name="MethodName">
            <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
            <message key="name.invalidPattern"
                     value="Method name ''{0}'' must match pattern ''{1}''."/>
        </module>
        <!-- Enforces that no 'finalize' method overrides exist, as these behave inconsistently and in-performantly -->
        <module name="NoFinalizer"/>
        <!-- MethodParamPad, NoWhitespaceBefore, ParenPad - Enforces consistent styling and whitespace use for readability -->
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceBefore">
            <property name="tokens"
                      value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS, METHOD_REF"/>
            <property name="allowLineBreaks" value="true"/>
        </module>
        <module name="ParenPad"/>
        <!-- Enforces consistent annotation placement for readability -->
        <module name="AnnotationLocation">
            <property name="id" value="AnnotationLocationMostCases"/>
            <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
        </module>
        <module name="AnnotationLocation">
            <property name="id" value="AnnotationLocationVariables"/>
            <property name="tokens" value="VARIABLE_DEF"/>
            <property name="allowSamelineMultipleAnnotations" value="true"/>
        </module>
    </module>
</module>