From ae1320aef5898cfba7493189405eb078558816c2 Mon Sep 17 00:00:00 2001 From: IamZhenHong <109903639+IamZhenHong@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:12:22 +0800 Subject: [PATCH] Added checkstyle --- build.gradle | 6 + config/checkstyle/checkstyle.xml | 434 ++++++++++++++++++ config/checkstyle/suppressions.xml | 10 + duke.txt | 3 +- src/main/java/duke/Command/DeleteCommand.java | 2 +- src/main/java/duke/Command/FindCommand.java | 6 +- src/main/java/duke/Command/ListCommand.java | 4 +- src/main/java/duke/Duke.java | 5 +- src/main/java/duke/Task/ToDoTask.java | 2 - src/test/java/duke/UiTest.java | 6 +- 10 files changed, 464 insertions(+), 14 deletions(-) create mode 100644 config/checkstyle/checkstyle.xml create mode 100644 config/checkstyle/suppressions.xml diff --git a/build.gradle b/build.gradle index 9f9bb9e3d5..85054838e9 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,8 @@ plugins { id 'java' id 'application' id 'com.github.johnrengelman.shadow' version '7.1.2' + id 'checkstyle' + } repositories { @@ -45,3 +47,7 @@ shadowJar { run{ standardInput = System.in } + +checkstyle { + toolVersion = '10.2' +} \ No newline at end of file diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..d1399810b5 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,434 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> + +<!-- + This configuration file enforces rules for the coding standard at + https://se-education.org/guides/conventions/java/intermediate.html +--> + +<module name="Checker"> + + <module name="FileTabCharacter"> + <!-- Checks that there are no tab characters in the file. --> + </module> + + <module name="NewlineAtEndOfFile"> + <!-- Accept LF, CR or CRLF to accomodate devs who prefer different line endings --> + <property name="lineSeparator" value="lf_cr_crlf"/> + </module> + + <module name="RegexpSingleline"> + <!-- Checks that FIXME is not used in comments. TODO is preferred. --> + <property name="format" value="((//.*)|(\*.*))FIXME" /> + <property name="message" value='TODO is preferred to FIXME."' /> + </module> + + <module name="SuppressionFilter"> + <property name="file" value="${config_loc}/suppressions.xml"/> + </module> + + <module name="LineLength"> + <!-- Checks if a line is too long. --> + <property name="max" value="120"/> + </module> + + <!-- All Java AST specific tests live under TreeWalker module. --> + <module name="TreeWalker"> + + <!-- Required to allow exceptions in code style --> + <module name="SuppressionCommentFilter"> + <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/> + <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/> + <property name="checkFormat" value="$1"/> + </module> + + <!-- + IMPORT CHECKS + --> + + <!-- Checks the ordering of import statements follow the rules that the default Eclipse formatter uses. + The order rule "STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE" consists of: + 1. STATIC: static imports + 2. STANDARD_JAVA_PACKAGE: standard java/javax imports + 3. SPECIAL_IMPORTS: defined as org imports + 4. THIRD_PARTY_PACKAGE: defined as com imports + --> + <module name="CustomImportOrder"> + <property name="customImportOrderRules" + value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE"/> + <property name="specialImportsRegExp" value="^org\."/> + <property name="thirdPartyPackageRegExp" value="^com\."/> + <property name="sortImportsInGroupAlphabetically" value="true"/> + </module> + + <!-- Checks for redundant import statements. + An import statement is redundant if: + * It is a duplicate of another import. This is, when a class is imported more than once. + * The class non-statically imported is from the java.lang package, e.g. importing java.lang.String. + * The class non-statically imported is from the same package as the current package. + --> + <module name="RedundantImport"/> + + <!-- Checks for unused import statements. + An import statement is unused if: + It's not referenced in the file. + --> + <module name="UnusedImports"/> + + <module name="AvoidStarImport"/> + + <!-- + NAMING CHECKS + --> + + <!-- Validate abbreviations (consecutive capital letters) length in identifier name --> + <module name="AbbreviationAsWordInName"> + <property name="ignoreFinal" value="false"/> + <property name="allowedAbbreviationLength" value="1"/> + </module> + + <module name="PackageName"> + <!-- Validates identifiers for package names against the supplied expression. --> + <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/> + <property name="severity" value="warning"/> + </module> + + <module name="TypeName"> + <!-- Validates static, final fields against the expression "^[A-Z][a-zA-Z0-9]*$". --> + <metadata name="altname" value="TypeName"/> + <property name="severity" value="warning"/> + </module> + + <module name="ConstantName"> + <!-- Validates non-private, static, final fields against the expression "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". --> + <metadata name="altname" value="ConstantName"/> + <property name="applyToPrivate" value="false"/> + <message key="name.invalidPattern" + value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/> + <property name="severity" value="warning"/> + </module> + + <module name="StaticVariableName"> + <!-- Validates static, non-final fields against the supplied expression. --> + <metadata name="altname" value="StaticVariableName"/> + <property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/> + <property name="severity" value="warning"/> + </module> + + <module name="MemberName"> + <!-- Validates non-static members against the supplied expression. --> + <metadata name="altname" value="MemberName"/> + <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> + <property name="severity" value="warning"/> + </module> + + <module name="MethodName"> + <!-- Validates identifiers for method names against the supplied expression. --> + <metadata name="altname" value="MethodName"/> + <property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-z][a-zA-Z0-9]+){0,2}$"/> + </module> + + <module name="ParameterName"> + <!-- Validates identifiers for method parameters against the expression "^[a-z][a-zA-Z0-9]*$". --> + <property name="severity" value="warning"/> + </module> + + <module name="LocalFinalVariableName"> + <!-- Validates identifiers for local final variables against the expression "^[a-z][a-zA-Z0-9]*$". --> + <property name="severity" value="warning"/> + </module> + + <module name="LocalVariableName"> + <!-- Validates identifiers for local variables against the expression "^[a-z][a-zA-Z0-9]*$". --> + <property name="severity" value="warning"/> + </module> + + + <!-- + LENGTH and CODING CHECKS + --> + + <!-- Checks that array type declarations follow Java Style + Java style: public static void main(String[] args) // Allowed + C style: public static void main(String args[]) // Not allowed + --> + <module name="ArrayTypeStyle"/> + + <!-- Checks if a catch block is empty and does not contain any comments. --> + <module name="EmptyCatchBlock"/> + + <module name="LeftCurly"> + <!-- Checks for placement of the left curly brace ('{'). --> + <property name="severity" value="warning"/> + </module> + + <module name="RightCurly"> + <!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on + the same line. e.g., the following example is fine: + <pre> + if { + ... + } else + </pre> + --> + <!-- This next example is not fine: + <pre> + if { + ... + } + else + </pre> + --> + <property name="severity" value="warning"/> + </module> + + <!-- Checks for braces around loop blocks --> + <module name="NeedBraces"> + <!-- + if (true) return 1; // Not allowed + + if (true) { return 1; } // Not allowed + + else if { + return 1; // else if should always be multi line + } + + if (true) + return 1; // Not allowed + --> + <property name="allowEmptyLoopBody" value="true"/> + </module> + + <!-- Checks that each variable declaration is in its own statement and on its own line. --> + <module name="MultipleVariableDeclarations"/> + + <module name="OneStatementPerLine"/> + + <!-- Checks that long constants are defined with an upper ell.--> + <module name="UpperEll" /> + + <module name="FallThrough"> + <!-- Warn about falling through to the next case statement. Similar to + javac -Xlint:fallthrough, but the check is suppressed if a single-line comment + on the last non-blank line preceding the fallen-into case contains 'fall through' (or + some other variants which we don't publicized to promote consistency). + --> + <property name="reliefPattern" + value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/> + </module> + + <module name="MissingSwitchDefault"/> + + <!-- Checks that Class variables should never be declared public. --> + <module name="VisibilityModifier"> + <property name="protectedAllowed" value="true"/> + <property name="allowPublicFinalFields" value="true"/> + <property name="ignoreAnnotationCanonicalNames" value="RegisterExtension, TempDir"/> + </module> + + <!-- + ORDER CHECKS + --> + + <!-- Checks that the order of at-clauses follows the tagOrder default property value order. + @author, @version, @param, @return, @throws, @exception, @see, @since, @serial, @serialField, @serialData, @deprecated + --> + <module name="AtclauseOrder"/> + + <!-- Checks if the Class and Interface declarations is organized in this order + 1. Class (static) variables. Order: public, protected, package level (no access modifier), private. + 2. Instance variables. Order: public, protected, package level (no access modifier), private. + 3. Constructors + 4. Methods + --> + <module name ="DeclarationOrder"/> + + <!-- Checks that default is after all cases in a switch statement --> + <module name="DefaultComesLast"/> + + <module name="ModifierOrder"> + <!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and + 8.4.3. The prescribed order is: + public, protected, private, abstract, static, final, transient, volatile, + synchronized, native, strictfp + --> + </module> + + <module name="OverloadMethodsDeclarationOrder"/> + + <!-- + WHITESPACE CHECKS + --> + + <!-- Checks that comments are indented relative to their position in the code --> + <module name="CommentsIndentation"/> + + <module name="WhitespaceAround"> + <!-- Checks that various tokens are surrounded by whitespace. + This includes most binary operators and keywords followed + by regular or curly braces. + --> + <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, + BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, + EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, + LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, + LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, + MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, + RCURLY, SL, SLIST, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/> + <!-- Allow empty constructors e.g. MyClass() {} --> + <property name="allowEmptyConstructors" value="true" /> + <!-- Allow empty methods e.g. void func() {} --> + <property name="allowEmptyMethods" value="true" /> + <!-- Allow empty types e.g. class Foo {}, enum Foo {} --> + <property name="allowEmptyTypes" value="true" /> + <!-- Allow empty loops e.g. for (int i = 1; i > 1; i++) {} --> + <property name="allowEmptyLoops" value="true" /> + <!-- Allow empty lambdas e.g. () -> {} --> + <property name="allowEmptyLambdas" value="true" /> + </module> + + <module name="WhitespaceAfter"> + <!-- Checks that commas, semicolons and typecasts are followed by whitespace. --> + <property name="tokens" value="COMMA, SEMI, TYPECAST"/> + </module> + + <module name="NoWhitespaceAfter"> + <!-- Checks that there is no whitespace after various unary operators. Linebreaks are allowed. --> + <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, + UNARY_PLUS"/> + <property name="allowLineBreaks" value="true"/> + </module> + + <!-- No trailing whitespace --> + <module name="Regexp"> + <property name="format" value="[ \t]+$"/> + <property name="illegalPattern" value="true"/> + <property name="message" value="Trailing whitespace"/> + </module> + + <module name="OperatorWrap"> + <!-- Checks that the non-assignment type operator is at the next line in a line wrap. + This includes "?", ":", "==", "!=", "/", "+", "-", "*", "%", ">>", ">>>", + ">=", ">", "<<", "<=", "<", "^", "|", "||", "&", "&&", "instanceof", + "&" when used in a generic upper or lower bounds constraints, + e.g. <T extends Foo & Bar> + "::" when used as a reference to a method or constructor without arguments. + e.g. String::compareToIgnoreCase + --> + <property name="tokens" value="QUESTION, COLON, EQUAL, NOT_EQUAL, DIV, PLUS, MINUS, STAR, MOD, SR, BSR, + GE, GT, SL, LE, LT, BXOR, BOR, LOR, BAND, LAND, LITERAL_INSTANCEOF, TYPE_EXTENSION_AND, METHOD_REF"/> + <property name="option" value="nl"/> + </module> + <module name="OperatorWrap"> + <!-- Checks that the assignment type operator is at the previous end of line in a line wrap. + This includes "=", "/=", "+=", "-=", "*=", "%=", ">>=", ">>>=", "<<=", "^=", "&=". + --> + <property name="tokens" value="ASSIGN, DIV_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN, STAR_ASSIGN, MOD_ASSIGN, + SR_ASSIGN, BSR_ASSIGN, SL_ASSIGN, BXOR_ASSIGN, BOR_ASSIGN, BAND_ASSIGN"/> + <property name="option" value="eol"/> + </module> + + <module name="SeparatorWrap"> + <!-- Checks that the ".", "@" is at the next line in a line wrap. --> + <property name="tokens" value="DOT, AT"/> + <property name="option" value="nl"/> + </module> + <module name="SeparatorWrap"> + <!-- Checks that the ",", "]", "[", "...", ";", "(" is at the previous end of line in a line wrap. --> + <property name="tokens" value="COMMA, RBRACK, ARRAY_DECLARATOR, ELLIPSIS, SEMI, LPAREN"/> + <property name="option" value="eol"/> + </module> + + <module name="Indentation"> + <property name="caseIndent" value="0" /> + <property name="throwsIndent" value="8" /> + </module> + + <module name="NoWhitespaceBefore"> + <!-- Checks that there is no whitespace before various unary operators. Linebreaks are allowed. --> + <property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/> + <property name="allowLineBreaks" value="true"/> + </module> + + <module name="NoWhitespaceBeforeCaseDefaultColon"/> + + <!-- Checks that there is no whitespace between method/constructor name and open parenthesis. --> + <module name="MethodParamPad"/> + + <module name="ParenPad"> + <!-- Checks that there is no whitespace before close parenthesis or after open parenthesis. --> + <property name="severity" value="warning"/> + </module> + + <!-- Checks that non-whitespace characters are separated by no more than one whitespace character. + a = 1; // Allowed + a = 1; // Not allowed (more than one space before =) + --> + <module name="SingleSpaceSeparator"> + <!-- Validate whitespace surrounding comments as well. + + a = 1; // Allowed (single space before start of comment) + a = 1; /* Allowed (single space before start of comment) */ + /* Allowed (single space after end of comment) */ a = 1; + a = 1; // Not allowed (more than one space before start of comment) + a = 1; /* Not allowed (more than one space before start of comment) */ + /* Not allowed (more than one space after end of comment) */ a = 1; + + This doesn't validate whitespace within comments so a comment /* like this */ is allowed. + --> + <property name="validateComments" value="true"/> + </module> + + <!-- + JAVADOC CHECKS + --> + + <!-- Checks that all block-tags are ordered correctly. --> + <module name="AtclauseOrder"/> + + <!-- Checks that Javadoc block tags appear only at the beginning of the line. --> + <module name="JavadocBlockTagLocation"/> + + <!-- Checks that all Javadoc comments start from the second line. --> + <module name="JavadocContentLocationCheck" /> + + <!-- Checks that each line in Javadoc has leading asterisks. --> + <module name="JavadocMissingLeadingAsterisk"/> + + <!-- Checks that each non-empty line in Javadoc has whitespace after leading asterisk. --> + <module name="JavadocMissingWhitespaceAfterAsterisk"/> + + <!-- Checks that for block tags, indentation of continuation lines is at least 4 spaces. --> + <module name="JavadocTagContinuationIndentation"/> + + <!-- Checks the Javadoc's format for every class, enumeration and interface. --> + <module name="JavadocType"> + <property name="allowMissingParamTags" value="true"/> + </module> + + <!-- Checks the Javadoc's format for every public method (excluding getters, setters and constructors). --> + <module name="JavadocMethod"> + <property name="allowedAnnotations" value="Override, Test, BeforeAll, BeforeEach, AfterAll, AfterEach, Subscribe"/> + <property name="accessModifiers" value="public"/> + <property name="validateThrows" value="false"/> + <property name="allowMissingParamTags" value="true"/> + <property name="allowMissingReturnTag" value="true"/> + <property name="tokens" value="METHOD_DEF, ANNOTATION_FIELD_DEF"/> + </module> + + <module name="InvalidJavadocPosition"/> + + <!-- Checks that every public method (excluding getters, setters and constructors) has a header comment. --> + <module name="MissingJavadocMethodCheck"> + <property name="minLineCount" value="1"/> + <property name="allowMissingPropertyJavadoc" value="true"/> + <property name="ignoreMethodNamesRegex" value="(set.*|get.*|main)"/> + </module> + + <!-- Checks that every public class, enumeration and interface has a header comment. --> + <module name="MissingJavadocType"/> + + </module> +</module> \ No newline at end of file diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 0000000000..dcaa1af3c3 --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> + +<!DOCTYPE suppressions PUBLIC + "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" + "https://checkstyle.org/dtds/suppressions_1_2.dtd"> + +<suppressions> + <suppress checks="JavadocType" files=".*Test\.java"/> + <suppress checks="MissingJavadocMethodCheck" files=".*Test\.java"/> +</suppressions> \ No newline at end of file diff --git a/duke.txt b/duke.txt index cc6ac03d1d..c21a555b24 100644 --- a/duke.txt +++ b/duke.txt @@ -1,4 +1,5 @@ -E | 0 | a | 1100 | 1100 +E | 1 | a | 1100 | 1100 T | 0 | a D | 0 | a | 1100 T | 0 | a +T | 0 | a diff --git a/src/main/java/duke/Command/DeleteCommand.java b/src/main/java/duke/Command/DeleteCommand.java index 7696a75f7d..3acfb83a90 100644 --- a/src/main/java/duke/Command/DeleteCommand.java +++ b/src/main/java/duke/Command/DeleteCommand.java @@ -3,7 +3,7 @@ import duke.TaskList; import duke.DukeException; import duke.Task.Task; -import java.util.ArrayList; + /** * Represents a command to delete a task from the task list. diff --git a/src/main/java/duke/Command/FindCommand.java b/src/main/java/duke/Command/FindCommand.java index 24ae77eb6f..e66b33625f 100644 --- a/src/main/java/duke/Command/FindCommand.java +++ b/src/main/java/duke/Command/FindCommand.java @@ -1,10 +1,10 @@ package duke.Command; import duke.TaskList; -import duke.Ui; -import duke.Storage; + + import duke.Task.Task; import java.util.ArrayList; -import duke.Command.Command; + import duke.DukeException; public class FindCommand extends Command{ diff --git a/src/main/java/duke/Command/ListCommand.java b/src/main/java/duke/Command/ListCommand.java index 918a9212dd..46526cdd7b 100644 --- a/src/main/java/duke/Command/ListCommand.java +++ b/src/main/java/duke/Command/ListCommand.java @@ -1,8 +1,8 @@ package duke.Command; import duke.TaskList; -import duke.DukeException; -import duke.Command.Command; + + /** * Represents a command to list all tasks in the task list. diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1ad5d43d73..a64ad4c850 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -3,10 +3,9 @@ import java.util.ArrayList; import java.util.Scanner; import duke.Command.Command; -import duke.Storage; + import duke.Task.Task; -import duke.TaskList; -import duke.Ui; + /** * The Duke class represents a task management application. diff --git a/src/main/java/duke/Task/ToDoTask.java b/src/main/java/duke/Task/ToDoTask.java index 9ceda94109..233032dc40 100644 --- a/src/main/java/duke/Task/ToDoTask.java +++ b/src/main/java/duke/Task/ToDoTask.java @@ -1,7 +1,5 @@ package duke.Task; -import duke.Task.Task; - /** * Represents a ToDo task. * Inherits from the Task class. diff --git a/src/test/java/duke/UiTest.java b/src/test/java/duke/UiTest.java index c92c6070ee..c7a6689e88 100644 --- a/src/test/java/duke/UiTest.java +++ b/src/test/java/duke/UiTest.java @@ -1,12 +1,14 @@ package duke; -import duke.Ui; -import org.junit.jupiter.api.*; + +import org.junit.jupiter.api.AfterEach; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.PrintStream; import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class UiTest {