diff --git a/.ci/travis.sh b/.ci/travis.sh new file mode 100755 index 0000000000..eda7a5040d --- /dev/null +++ b/.ci/travis.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# Attention, there is no "-x" to avoid problems on Travis +set -e + +case $1 in + +pr-description) + .ci/xtr_pr-description.sh + ;; + +eclipse-cs) + cd sevntu-checks + mvn -e clean install -Dmaven.test.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true + cd .. + git clone https://github.com/checkstyle/eclipse-cs.git + cd eclipse-cs/ + git checkout 8.10.0 + mvn -e install + cd ../ + cd eclipsecs-sevntu-plugin + mvn -e verify + mvn -e javadoc:javadoc + ;; + +maven-plugin) + cd sevntu-checks + mvn -e clean install -Dmaven.test.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true + cd .. + cd sevntu-checkstyle-maven-plugin + mvn -e verify + mvn -e javadoc:javadoc + ;; + +idea-extension) + cd sevntu-checks + mvn -e clean install -Dmaven.test.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true + cd .. + cd sevntu-checkstyle-idea-extension + mvn -e verify + mvn -e javadoc:javadoc + ;; + +sonar-plugin) + cd sevntu-checks + mvn -e clean install -Dmaven.test.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true + cd .. + cd sevntu-checkstyle-sonar-plugin + mvn -e verify + mvn -e javadoc:javadoc + ;; + +sevntu-checks) + cd sevntu-checks + mvn -e -Pcoverall install + mvn -e verify -Pno-validations,selftesting + mvn -e javadoc:javadoc + if [[ $TRAVIS == 'true' ]]; then + mvn -e -Pcoverall jacoco:report coveralls:report + fi + ;; + +all-sevntu-checks-contribution) + wget -q \ + https://raw.githubusercontent.com/checkstyle/contribution/master/checkstyle-tester/checks-sevntu-error.xml + xmlstarlet sel --net --template -m .//module -v "@name" -n checks-sevntu-error.xml \ + | grep -vE "Checker|TreeWalker|Filter|Holder" | grep -v "^$" \ + | sed "s/com\.github\.sevntu\.checkstyle\.checks\..*\.//" \ + | sort | uniq | sed "s/Check$//" > web.txt + xmlstarlet sel --net --template -m .//module -v "@name" -n sevntu-checks/sevntu-checks.xml \ + | grep -vE "Checker|TreeWalker|Filter|Holder" | grep -v "^$" \ + | sed "s/com\.github\.sevntu\.checkstyle\.checks\..*\.//" \ + | sort | uniq | sed "s/Check$//" > file.txt + diff -u web.txt file.txt + ;; + +checkstyle-regression) + git clone https://github.com/checkstyle/checkstyle + cd sevntu-checks + mvn -e install -DskipTests -Dcheckstyle.skip=true -Dcobertura.skip=true + mvn -e test -Dtest=CheckstyleRegressionTest#setupFiles -Dregression-path=../ + cd ../ + cd checkstyle + mvn -e clean verify -e -DskipTests -DskipITs -Dpmd.skip=true \ + -Dfindbugs.skip=true -Dcobertura.skip=true \ + -Dmaven.sevntu-checkstyle-check.checkstyle.version=8.10 + ;; + +eclipse-analysis) + cd sevntu-checks + mvn -e clean compile exec:exec -Peclipse-compiler + ;; + + +*) + echo "Unexpected argument: $1" + sleep 5s + false + ;; + +esac diff --git a/.ci/xtr_pr-description.sh b/.ci/xtr_pr-description.sh new file mode 100755 index 0000000000..bfaebb6e11 --- /dev/null +++ b/.ci/xtr_pr-description.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Attention, there is no "-x" to avoid problems on Travis +set -e + +if [[ ! $TRAVIS_PULL_REQUEST =~ ^([0-9]*)$ ]]; then exit 0; fi +LINK_COMMITS=https://api.github.com/repos/sevntu-checkstyle/sevntu.checkstyle/pulls/$TRAVIS_PULL_REQUEST/commits +COMMITS=$(curl -s -H "Authorization: token $READ_ONLY_TOKEN" $LINK_COMMITS | jq '.[0] | .commit.message') +echo 'Commit messages from github: '${COMMITS:0:60}... +ISSUE_NUMBER=$(echo $COMMITS | sed -e 's/^.*Issue //' | sed -e 's/:.*//') +echo 'Issue number: '$ISSUE_NUMBER && RESULT=0 +if [[ $ISSUE_NUMBER =~ ^#[0-9]+$ ]]; then + LINK_PR=https://api.github.com/repos/sevntu-checkstyle/sevntu.checkstyle/pulls/$TRAVIS_PULL_REQUEST + LINK_ISSUE=https://api.github.com/repos/sevntu-checkstyle/sevntu.checkstyle/issues/${ISSUE_NUMBER:1} + REGEXP=($ISSUE_NUMBER\|https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/${ISSUE_NUMBER:1}) + PR_DESC=$(curl -s -H "Authorization: token $READ_ONLY_TOKEN" $LINK_PR | jq '.body' | grep -E $REGEXP | cat ) + echo 'PR Description grepped:'${PR_DESC:0:80} + if [[ -z $PR_DESC ]]; then + echo 'Please put a reference to an Issue in the PR description, this will bind the Issue to your PR in Github' && RESULT=1; + fi + LABEL_APRV=$(curl -s -H "Authorization: token $READ_ONLY_TOKEN" $LINK_ISSUE | jq '.labels [] | .name' | grep approved | cat | wc -l ) + if [[ $LABEL_APRV == 0 ]]; then + echo 'You are providing a PR for an Issue that is not approved yet, please ask admins to approve your Issue first' && RESULT=1; + fi + fi +if [[ $RESULT == 0 ]]; then + echo 'PR validation succeeded.'; +else + echo 'PR validation failed.' && false; +fi diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000000..508ae63860 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,11 @@ +Please read http://checkstyle.sourceforge.net/report_issue.html + +**Note:** Sevntu checks are in a different JAR from the main Checkstyle JAR and cannot be run without the main JAR. +The command to run sevntu in the Command Line Interface (CLI) is slightly different as noted below: +``` +java -classpath sevntu-checks-X.XX.X.jar;checkstyle-X.XX-all.jar com.puppycrawl.tools.checkstyle.Main -c config.xml YOUR_FILE.java +``` + +Please provide issue report in format that we request, EACH DETAIL MAKE A HUGE HELP. + +Issues that are not following the guidelines, will be processed with last priority. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..04fbe2217f --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,29 @@ +/var/tmp $ javac YOUR_FILE.java + +[[PLACE YOUR OUTPUT HERE]] + +/var/tmp $ cat YOUR_FILE.java + +[[PLACE YOU OUTPUT HERE]] + +/var/tmp $ cat config.xml + +[[PLACE YOUR OUTPUT HERE]] + +For Linux users: + +`/var/tmp $ java -classpath sevntu-checks-X.XX.X.jar:checkstyle-X.XX-all.jar com.puppycrawl.tools.checkstyle.Main -c config.xml YOUR_FILE.java` + +For Windows users: + +`C:\tmp> java -classpath sevntu-checks-X.XX.X.jar;checkstyle-X.XX-all.jar com.puppycrawl.tools.checkstyle.Main -c config.xml YOUR_FILE.java` + +[[PLACE YOUR OUTPUT HERE]] + +--------------- + +Describe what you expect in detail. + +-------------- + +Still not clear ??? - see example - https://github.com/sevntu-checkstyle/sevntu.checkstyle/wiki/How-to-report-the-issue-(example) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..ab236e32fa --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ +Mandatory to understand and do: +0) Issue you are trying to fix/resolve has to have "approved" label. +1) Put in description of Pull Request reference to issue if it exists. Example: "Issue: #XXXXXX" +2) Commit message should adhere to the following rules: + a) Must match one of the following patterns:\n" + ^Issue #\\d+: .*$ + ^Pull #\\d+: .*$ + ^(minor|config|infra|doc|spelling): .*$ + b) It contains only one line of text + c) Must not end with a period, space, or tab + +To avoid multiple iterations of fixes and CIs failures, please read http://checkstyle.sourceforge.net/contributing.html + +ATTENTION: We are not merging Pull Requests that not passing our CIs, but we help to resolve issues. + +Thanks for reading, remove whole this message and type what you need. diff --git a/.gitignore b/.gitignore index f9ce6766f6..1c9d6f1567 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,11 @@ bin/ # No Github Pages gh-pages/ -# No Eclipse settings +# No Eclipse files .settings/ .checkstyle +.classpath +.project # No IntelliJ Idea project files .idea/ diff --git a/.travis.yml b/.travis.yml index fb8534f514..ad00bba2ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,102 @@ language: java sudo: false -jdk: - - oraclejdk8 - -before_install: git clone git://git.code.sf.net/p/eclipse-cs/git eclipse-cs-git - && cd eclipse-cs-git/ && git checkout 7.2.0 - && cd net.sf.eclipsecs.parent/ && mvn install - && cd ../../ - -install: cd sevntu-checks && mvn clean install && mvn javadoc:javadoc - && cd ../eclipsecs-sevntu-plugin && mvn verify && mvn javadoc:javadoc - && cd ../sevntu-checkstyle-maven-plugin && mvn verify && mvn javadoc:javadoc - && cd ../sevntu-checkstyle-idea-extension && mvn verify && mvn javadoc:javadoc - && cd ../sevntu-checkstyle-sonar-plugin && mvn verify && mvn javadoc:javadoc - && cd ../sevntu-checks && mvn jacoco:report coveralls:jacoco - && cd ../sevntu-checks && mvn verify -Pselftesting - -after_success: - cache: directories: - ~/.m2 +addons: + apt: + packages: + - xmlstarlet + branches: only: - master +install: + - + matrix: fast_finish: true + include: + # eclipse-cs + - jdk: oraclejdk8 + env: + - DESC="eclipse-cs" + - CMD="./.ci/travis.sh eclipse-cs" + + # maven-plugin + - jdk: oraclejdk8 + env: + - DESC="maven-plugin" + - CMD="./.ci/travis.sh maven-plugin" + + # idea-extension + - jdk: oraclejdk8 + env: + - DESC="idea-extension" + - CMD="./.ci/travis.sh idea-extension" + + # sonar-plugin + - jdk: oraclejdk8 + env: + - DESC="sonar-plugin" + - CMD="./.ci/travis.sh sonar-plugin" + + # checks + - jdk: oraclejdk8 + env: + - DESC="checks" + - CMD="./.ci/travis.sh sevntu-checks" + + # Ensure that all sevntu checks are used in contribution + - jdk: oraclejdk8 + env: + - DESC="All sevntu checks should be used in contribution" + - CMD="./.ci/travis.sh all-sevntu-checks-contribution" + + # regression on checkstyle + - jdk: oraclejdk8 + env: + - DESC="checkstyle-regression" + - CMD="./.ci/travis.sh checkstyle-regression" + + # eclipse static analysis + - jdk: oraclejdk8 + env: + - DESC="eclipse-analysis" + - CMD="./.ci/travis.sh eclipse-analysis" + + # testing of PR format + - env: + - DESC="test Issue ref in PR description" + - CMD="./.ci/travis.sh pr-description" + + +script: + - SKIP_FILES1=".github|codeship-*|buddy.yml|appveyor.yml|circleci|distelli-manifest.yml" + - SKIP_FILES2="|fast-forward-merge.sh|LICENSE|LICENSE.apache20|README.md|release.sh|RIGHTS.antlr" + - SKIP_FILES3="|shippable.yml|shippable.sh|wercker.yml|wercker.sh|intellij-idea-inspections.xml" + - SKIP_FILES=$SKIP_FILES1$SKIP_FILES2$SKIP_FILES3 + - | + if [[ $SKIP_CI != 'false' ]]; then + if [[ $(git diff --name-only HEAD HEAD~1 | grep -vE "$SKIP_FILES" \ + | cat | wc -c | sed 's/^ *//' ) > 0 ]]; then + SKIP_CI="false" + else + SKIP_CI="true" + fi + fi + - echo "SKIP_CI="$SKIP_CI + - | + set -e + if [[ $SKIP_CI == 'false' ]]; + then + eval $CMD; + echo "eval of CMD is completed" + else + echo "CI is skipped" + fi + +after_success: diff --git a/README.textile b/README.textile index 16b23b159a..0582db5eb8 100644 --- a/README.textile +++ b/README.textile @@ -1,11 +1,20 @@ -h3. Information "!https://secure.travis-ci.org/sevntu-checkstyle/sevntu.checkstyle.png!":http://travis-ci.org/sevntu-checkstyle/sevntu.checkstyle/builds !https://coveralls.io/repos/sevntu-checkstyle/sevntu.checkstyle/badge.svg?branch=master&service=github(Coverage Status)!:https://coveralls.io/github/sevntu-checkstyle/sevntu.checkstyle?branch=master !https://img.shields.io/sonar/http/sonarqube.com/com.github.sevntu.checkstyle:sevntu-checks/tech_debt.svg?label=SonarQube%20tech%20debt!:https://sonarqube.com/overview?id=com.github.sevntu.checkstyle%3Asevntu-checks +h3. Information "!https://secure.travis-ci.org/sevntu-checkstyle/sevntu.checkstyle.png!":http://travis-ci.org/sevntu-checkstyle/sevntu.checkstyle/builds !https://coveralls.io/repos/sevntu-checkstyle/sevntu.checkstyle/badge.svg?branch=master&service=github(Coverage Status)!:https://coveralls.io/github/sevntu-checkstyle/sevntu.checkstyle?branch=master !https://sonarcloud.io/api/project_badges/measure?project=com.github.sevntu.checkstyle%3Asevntu-checks&metric=sqale_index!:https://sonarqube.com/dashboard?id=com.github.sevntu.checkstyle%3Asevntu-checks + +sevntu-checks: !https://maven-badges.herokuapp.com/maven-central/com.github.sevntu-checkstyle/sevntu-checks/badge.svg!:https://search.maven.org/#search|gav|1|g%3A%22com.github.sevntu-checkstyle%22%20AND%20a%3A%22sevntu-checks%22 +sevntu-checkstyle-idea-extension:!https://maven-badges.herokuapp.com/maven-central/com.github.sevntu-checkstyle/sevntu-checkstyle-idea-extension/badge.svg!:https://search.maven.org/#search|gav|1|g%3A%22com.github.sevntu-checkstyle%22%20AND%20a%3A%22sevntu-checkstyle-idea-extension%22 +sevntu-checkstyle-maven-plugin:!https://maven-badges.herokuapp.com/maven-central/com.github.sevntu-checkstyle/sevntu-checkstyle-maven-plugin/badge.svg!:https://search.maven.org/#search|gav|1|g%3A%22com.github.sevntu-checkstyle%22%20AND%20a%3A%22sevntu-checkstyle-maven-plugin%22 +sevntu-checkstyle-sonar-plugin:!https://maven-badges.herokuapp.com/maven-central/com.github.sevntu-checkstyle/sevntu-checkstyle-sonar-plugin/badge.svg!:https://search.maven.org/#search|gav|1|g%3A%22com.github.sevntu-checkstyle%22%20AND%20a%3A%22sevntu-checkstyle-sonar-plugin%22 +eclipsecs-sevntu-plugin: "all versions":https://github.com/sevntu-checkstyle/sevntu.checkstyle/tree/gh-pages/update-site/plugins + +All sevntu artifact on maven repo: https://repo1.maven.org/maven2/com/github/sevntu-checkstyle/ + Additional(non-standard) checks for Checkstyle that are compiled as: - extension to "maven-checkstyle-plugin":http://maven.apache.org/plugins/maven-checkstyle-plugin/ (how to use: "in general":http://maven.apache.org/plugins/maven-checkstyle-plugin/examples/custom-developed-checkstyle.html, "maven, ant, gradle example":https://github.com/sevntu-checkstyle/checkstyle-samples). - extension to "Sonar Checkstyle Plugin":http://docs.codehaus.org/display/SONAR/Checkstyle+Plugin (how to use: "instructions with pictures":https://github.com/sevntu-checkstyle/sevntu.checkstyle/wiki/How-to-integrate-sevntu-checks-into-SonarQubeTM-%28user%27s-guide%29). - extension to "CheckStyle-IDEA":http://plugins.jetbrains.com/plugin/1065 (how to use: "instructions with pictures":https://github.com/sevntu-checkstyle/sevntu.checkstyle/wiki/How-to-use-SevNTU-Checkstyle-in-Intellij-IDEA). - extension to "Checkstyle Beans, NetBeans":http://plugins.netbeans.org/plugin/3413/checkstyle-beans (how to use: "instructions with pictures":https://github.com/sevntu-checkstyle/sevntu.checkstyle/wiki/How-to-use-SevNTU-Checkstyle-in-NetBeans). -- extension to "Checkstyle Eclipse plugin":http://eclipse-cs.sourceforge.net/ how to use: install from EclipseCS "update site": +- extension to "Checkstyle Eclipse plugin":http://eclipse-cs.sourceforge.net/ how to use: install from EclipseCS "update site": !https://cloud.githubusercontent.com/assets/812984/2935361/20e479c8-d805-11e3-9391-f41cc4aa979c.png! h3. Related Projects @@ -14,7 +23,7 @@ h3. Related Projects h3. Contributors -"Roman Ivanov":https://github.com/romani, "Ivan Sopov":https://github.com/isopov, "Ruslan Diachenko":https://github.com/rdiachenko, Danil Lopatin, "Daniil Yaroslavtsev":https://github.com/daniilyar, "Yuriy Balahonov":https://github.com/balakhonov, Dmitriy Antonenko, +"Roman Ivanov":https://github.com/romani, "Ivan Sopov":https://github.com/isopov, "Ruslan Diachenko":https://github.com/rdiachenko, Danil Lopatin, "Daniil Yaroslavtsev":https://github.com/daniilyar, "Yuriy Balakhonov":https://github.com/balakhonov, Dmitriy Antonenko, Hidoyatov Victor, Troshin Sergey, Svinukhov Vladimir, "Ilia Dubinin":https://github.com/sabaka, Dmitry Gridyushko, "Vadym Chekrii":https://github.com/vchekrii, "Vadim Panasiuk":https://github.com/VadimPanasiuk, "Aleksey Grigirov":https://github.com/KTannenberg, Alexander Berezovsky, "Sergey Burtsev":https://github.com/burtsevsergey, "Baratali Izmailov":https://github.com/baratali, "Max Vetrenko":https://github.com/maxvetrenko, "Pavel Baranchikov":https://github.com/pbaranchikov , "Ashutosh Agarwal":https://github.com/Radsaggi, "Alexey Nesterenko":https://github.com/alexkravin. , ...... for whole list please look at "contributors list":https://github.com/sevntu-checkstyle/sevntu.checkstyle/network/members . diff --git a/deploy-all.sh b/deploy-all.sh index ae43129a1b..e43f538b1d 100755 --- a/deploy-all.sh +++ b/deploy-all.sh @@ -1,2 +1,4 @@ -#!/bin/sh -sh deploy.sh --all +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +$CURRENT_DIR/deploy.sh --all diff --git a/deploy.sh b/deploy.sh index dab444d2a9..f39722354e 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,7 +1,10 @@ -#!/bin/sh +#!/usr/bin/env bash -EXEC_DIR=`dirname $0` -REPO_HOME_DIR=`cd "$EXEC_DIR" ; pwd` +SEVNTU_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +GH_SEVNTU_DIR="/tmp/sevntu.checkstyle.gh" +PROJECT_NAME="sevntu.checkstyle" +GH_SEVNTU_HOMR_DIR="$GH_SEVNTU_DIR/$PROJECT_NAME" +GITHUB_PROJECT="sevntu-checkstyle/$PROJECT_NAME" usage="$(basename "$0") [--help --all --eclipse-cs --sonar --maven --idea] where: @@ -12,6 +15,8 @@ where: --sonar deploy only 'sevntu-checkstyle-sonar-plugin' project; --maven deploy only 'sevntu-checkstyle-maven-plugin' project; --idea deploy only 'sevntu-checkstyle-idea-extension' project; + --maven-central deploy to maven central; + --gh-pages deploy only gh-pages binaries with version argument; " @@ -23,112 +28,164 @@ For new version deploy please do: prepareForDeploy() { - #clean - rm -rf $REPO_HOME_DIR/gh-pages + echo "Preparing for Deployment" + if [ ! -d $GH_SEVNTU_DIR ]; then + mkdir $GH_SEVNTU_DIR + fi + + cd $GH_SEVNTU_DIR - #prepare folders for update-site and our release maven repository - mkdir $REPO_HOME_DIR/gh-pages - cd $REPO_HOME_DIR/gh-pages + if [ ! -d "$GH_SEVNTU_DIR/$PROJECT_NAME/.git" ]; then + git clone https://github.com/$GITHUB_PROJECT.git - git init - git remote add origin https://github.com/sevntu-checkstyle/sevntu.checkstyle.git - git fetch origin gh-pages:refs/remotes/origin/gh-pages - git checkout gh-pages + cd $GH_SEVNTU_HOMR_DIR + else + cd $GH_SEVNTU_HOMR_DIR + + git fetch origin + fi - cd $REPO_HOME_DIR + git reset --hard HEAD + git clean -f -d + git checkout origin/gh-pages return } deployIdea() { - cd $REPO_HOME_DIR/sevntu-checkstyle-idea-extension/ - mvn clean deploy + echo "Deploying Idea" + cd $SEVNTU_DIR/sevntu-checkstyle-idea-extension/ + mvn clean deploy -Plocal-deploy -DdeployDir=$GH_SEVNTU_HOMR_DIR if [ "$?" != "0" ] then - echo "build for $REPO_HOME_DIR/sevntu-checkstyle-idea-extension/" + echo "build for $SEVNTU_DIR/sevntu-checkstyle-idea-extension/" exit 1 fi - cd $REPO_HOME_DIR/gh-pages + cd $GH_SEVNTU_HOMR_DIR echo "$manualDeploy" return } deployEclipse() { - cd $REPO_HOME_DIR - #echo -n "Enter version number: " - #read version - #mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=$version -f eclipse-pom.xml - mvn clean install -f eclipse-pom.xml + echo "Deploying Eclipse" + cd $SEVNTU_DIR + #echo -n "Enter version number: " + #read version + #mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=$version -f eclipse-pom.xml + mvn clean install -f eclipse-pom.xml -Plocal-deploy if [ "$?" != "0" ] then echo "build for eclipse-pom.xml." exit 1 fi - cd $REPO_HOME_DIR/update-site - mvn wagon:upload - cd ../gh-pages + cd $SEVNTU_DIR/update-site + mvn wagon:upload -DdeployDir=$GH_SEVNTU_HOMR_DIR + cd $GH_SEVNTU_HOMR_DIR echo "$manualDeploy" return } deployMavenLibrary() { - # As we do not use SNAPSHOT qualifier for developemnt in pom.xml - # we have to deploy library sevntu-checks always even it overides existing binaries in maven repository - # for relase build - it will not override binaries + echo "Deploying Sevntu Checks" + # As we do not use SNAPSHOT qualifier for development in pom.xml + # we have to deploy library sevntu-checks always even it overrides existing binaries in maven repository + # for release build - it will not override binaries # for test build - it will override as we need to be sure that in repository, # we have previous release version but compiled with from new code - cd $REPO_HOME_DIR/sevntu-checks - mvn clean javadoc:javadoc deploy + cd $SEVNTU_DIR/sevntu-checks + mvn clean javadoc:javadoc deploy -Plocal-deploy -DdeployDir=$GH_SEVNTU_HOMR_DIR if [ "$?" != "0" ] then - echo "build for $REPO_HOME_DIR/sevntu-checks." + echo "build for $SEVNTU_DIR/sevntu-checks." exit 1 fi # deployment of Javadoc to static site - cp -rf target/site/apidocs ../gh-pages - - cd $REPO_HOME_DIR + cp -rf target/site/apidocs $GH_SEVNTU_HOMR_DIR # no need push to repository only library it should be done together with IDE plugins release - #cd ../gh-pages + #cd $GH_SEVNTU_HOMR_DIR #echo "$manualDeploy" return } +deployToMavenCentral() + { + echo "Deploying All to Maven Central" + # As we do not use SNAPSHOT qualifier for development in pom.xml + # we have to deploy library sevntu-checks always even it overrides existing binaries in maven repository + # for release build - it will not override binaries + # for test build - it will override as we need to be sure that in repository, + # we have previous release version but compiled with from new code + cd $SEVNTU_DIR/sevntu-checks + mvn clean deploy -DskipStaging=false -Pgpg + if [ "$?" != "0" ] + then + echo "build for $SEVNTU_DIR/sevntu-checks." + exit 1 + fi + + cd $SEVNTU_DIR/sevntu-checkstyle-maven-plugin/ + mvn clean deploy -DskipStaging=false -Pgpg + + cd $SEVNTU_DIR/sevntu-checkstyle-idea-extension/ + mvn clean deploy -DskipStaging=false -Pgpg + + cd $SEVNTU_DIR/sevntu-checkstyle-sonar-plugin/ + mvn clean deploy -DskipStaging=false -Pgpg + + return + } + deployMavenPlugin() { - cd $REPO_HOME_DIR/sevntu-checkstyle-maven-plugin/ - mvn clean deploy + echo "Deploying Maven Plugin" + cd $SEVNTU_DIR/sevntu-checkstyle-maven-plugin/ + mvn clean deploy -Plocal-deploy -DdeployDir=$GH_SEVNTU_HOMR_DIR if [ "$?" != "0" ] then - echo "build for $REPO_HOME_DIR/sevntu-checkstyle-maven-plugin/." + echo "build for $SEVNTU_DIR/sevntu-checkstyle-maven-plugin/." exit 1 fi - cd $REPO_HOME_DIR/gh-pages + cd $GH_SEVNTU_HOMR_DIR echo "$manualDeploy" return } deploySonar() { - cd $REPO_HOME_DIR/sevntu-checkstyle-sonar-plugin/ - mvn clean install wagon:upload-single + echo "Deploying Sonar" + cd $SEVNTU_DIR/sevntu-checkstyle-sonar-plugin/ + mvn clean install wagon:upload-single -DdeployDir=$GH_SEVNTU_HOMR_DIR if [ "$?" != "0" ] then - echo "build for $REPO_HOME_DIR/sevntu-checkstyle-sonar-plugin/" + echo "build for $SEVNTU_DIR/sevntu-checkstyle-sonar-plugin/" exit 1 fi - cd $REPO_HOME_DIR/gh-pages + cd $GH_SEVNTU_HOMR_DIR echo "$manualDeploy" return } +deployToGhPages() + { + echo "Deploying GH Pages" + cd $GH_SEVNTU_HOMR_DIR + + sed -i "/
Checks that the parts of a class(main, nested, member inner) declaration appear in the rules order set by user using regular expressions.
The check forms line which consists of class member annotations, modifiers,type and name from your code and compares it with your RegExp.
The rule consists of:*ClassMember(RegExp)To set class order use the following notation of the class members (case insensitive):
Use separator ' ', '.', '\s'
between declaration in the RegExp. Whitespace should be added after each modifier.
Example: Field(public .*final .*) Field(public final .*) Field(public\s*
final .*)
NOTICE!It is important to write exact order of modifiers in rules. So ruleField(public final)
does not match to final public value;
.ModifierOrderCheckis recommended to use.
If you set empty RegExp e.g. Field()
, it means that class member doesn't have modifiers(default modifier) and checking the type and name of member doesn't occur.
Between the declaration of a array and generic can't be whitespaces.E.g.: ArrayList<String[]> someName
Use the separator '###' between the class declarations.
For Example:
Field(private static final long serialVersionUID) ###Field(public static final .*) ### Field(.*private .*) ### Ctor(.*) ###GetterSetter(.*) ### Method(.*public .*final .*|@Ignore.*public .*) ###Method(public static .*(final|(new|edit|create).*).*) ###InnerClass(public abstract .*) ### InnerInterface(.*) ### InnerEnum(.*)
What is group of getters and setters(GetterSetter
)?
It is ordered sequence of getters and setters like:
public int getValue() { log.info("Getting value"); return value;} *public void setValue(int newValue) { value = newValue;} *public Object getObj() { return obj;} *public void setObj(Object obj) { if (obj != null) { this.obj = obj; } else { throw new IllegalArgumentException("Null value"); }} *...
Getter is public method that returns class field. Name of getter should be'getFieldName' in camel case.
Setter is public method with one parameter that assigns this parameter to class field. Name of setter should be 'setFieldName' in camel case.
Setter of field X should be right after getter of field X.
*@author Danil Lopatin@author Baratali Izmailov +CustomDeclarationOrderCheck.desc =Checks that the parts of a class(main, nested, member inner) declaration appear in the rules order set by user using regular expressions.
The check forms line which consists of class member annotations, modifiers,type and name from your code and compares it with your RegExp.
The rule consists of:*ClassMember(RegExp)To set class order use the following notation of the class members (case insensitive):
Use separator ' ', '.', '\s'
between declaration in the RegExp. Whitespace should be added after each modifier.
Example: Field(public .*final .*) Field(public final .*) Field(public\s*
final .*)
NOTICE!It is important to write exact order of modifiers in rules. So ruleField(public final)
does not match to final public value;
.ModifierOrderCheckis recommended to use.
If you set empty RegExp e.g. Field()
, it means that class member doesn't have modifiers(default modifier) and checking the type and name of member doesn't occur.
Between the declaration of a array and generic can't be whitespaces.E.g.: ArrayList<String[]> someName
Use the separator '###' between the class declarations.
For Example:
Field(private static final long serialVersionUID) ###Field(public static final .*) ### Field(.*private .*) ### Ctor(.*) ###GetterSetter(.*) ### Method(.*public .*final .*|@Ignore.*public .*) ###Method(public static .*(final|(new|edit|create).*).*) ###InnerClass(public abstract .*) ### InnerInterface(.*) ### InnerEnum(.*)
What is group of getters and setters(GetterSetter
)?
It is ordered sequence of getters and setters like:
public int getValue() { log.info("Getting value"); return value;} *public void setValue(int newValue) { value = newValue;} *public Object getObj() { return obj;} *public void setObj(Object obj) { if (obj != null) { this.obj = obj; } else { throw new IllegalArgumentException("Null value"); }} *...
Getter is public method that returns class field. Name of getter should be'getFieldName' in camel case.
Setter is public method with one parameter that assigns this parameter to class field. Name of setter should be 'setFieldName' in camel case.
Setter of field X should be right after getter of field X.
*@author Danil Lopatin@author Baratali Izmailov CustomDeclarationOrderCheck.fieldPrefix = Prefix of field's name. CustomDeclarationOrderCheck.customDeclarationOrder = Regular expression, which sets the order of the parts of a class(main, nested, member inner). CustomDeclarationOrderCheck.caseSensitive = Set false to ignore case. @@ -52,6 +52,11 @@ ForbidCertainImportsCheck.packageNameRegexp = Package name regexp. ForbidCertainImportsCheck.forbiddenImportsRegexp = Regexp for matching forbidden imports ForbidCertainImportsCheck.forbiddenImportsExcludesRegexp = Regexp for excluding imports from checking +ForbidCertainMethodCheck.name = Forbid Certain Method +ForbidCertainMethodCheck.desc = Forbids certain method usage.For example:
"java.lang.NullPointerException" will forbid the NPE instantiation.
Note: className should to be full: use "java.lang.NullPointerException" instead of "NullpointerException".
ForbidInstantiationCheck.forbiddenClasses = ClassNames for objects that are forbidden to instantiate. @@ -95,10 +100,10 @@ MultipleStringLiteralsExtendedCheck.desc = Checks for multiple occurrences of th MultipleStringLiteralsExtendedCheck.ignoreOccurrenceContext = Token type names where duplicate strings are ignored even if they don't match ignoredStringsRegexp. This allows you to exclude syntactical contexts like Annotations or static initializers from the check. MultipleStringLiteralsExtendedCheck.ignoreStringsRegexp = Regexp pattern for ignored strings (with quotation marks) MultipleStringLiteralsExtendedCheck.name = Multiple String Literals Extended -MultipleStringLiteralsExtendedCheck.highlightAllDuplicates = Check to highlight all dublicates +MultipleStringLiteralsExtendedCheck.highlightAllDuplicates = Check to highlight all duplicates TernaryPerExpressionCountCheck.name = Ternary Per Expression Count -TernaryPerExpressionCountCheck.desc = Restricts the number of ternary operators in expression to a specific limit.String str = null;
String x = str != null ? "A" : "B" + str == null ? "C" : "D";
System.out.println(x);
callString = "{? = call " +
(StringUtils.hasLength(catalogNameToUse) ? catalogNameToUse + "." : "") +
(StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") +
procedureNameToUse + "(";
int a = (d == 5) ? d : f
+
((d == 6) ? g : k);
String str = null;
String x = str != null ? "A" : "B" + str == null ? "C" : "D";
System.out.println(x);
callString = "{? = call " +
(StringUtils.hasLength(catalogNameToUse) ? catalogNameToUse + "." : "") +
(StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") +
procedureNameToUse + "(";
int a = (d == 5) ? d : f
+
((d == 6) ? g : k);
Checks for the presence of useless single catc UselessSingleCatchCheck.name = Useless single catch check UselessSuperCtorCallCheck.name = Useless super constructor call -UselessSuperCtorCallCheck.desc =
Checks for useless "super()" calls in ctors.
"super()" call could be considered by Check as "useless" in two cases:
Case 1. no-argument "super()" is called from class ctor if class is not derived, for example:
class Dummy {
Dummy() {
super();
}
"super()" call is useless because class "Dummy" is not derived.Case 2. no-argument "super()" is called without parameters from class ctor if class is derived, for example:
class Derived extends Base {
Derived() {
super();
}
}
Java compiler automatically inserts a call to the no-args constructor of the super class, so there is no need to call super ctor explicitly. Check has options "allowCallToNoArgsSuperCtor" and "allowCallToNoArgsSuperCtorIfMultiplePublicCtor" to adjust check behavior for such cases(see Check`s options description for details).Check has following options:
"allowCallToNoArgsSuperCtor" - if this option set to true, Check will not generate violations when "super()" called inside derived class. This option defaults to "false". If for example this option set to "true", then Check will not generate violation for cases like following:
class Base {
public Base() {
}
}
class Derived extends Base {
public Derived() {
super();
}
}
"allowCallToNoArgsSuperCtorIfMultiplePublicCtor" - if this option set to "true",then Check will not generate violation when "super()" called inside class ctor when class has multiple public ctors(however, setting this option to"true" will not prevent Check from logging violation if class does not extend anything). This option defaults to "false". This option may be usefull for cases in which class`s ctors just forward its arguments to super ctors, thus removing "super()" in this case will make default ctors look not like others.For example:
class Base {
public Base() {
}
public Base(int i) {
}
}
class Derived extends Base {
public Derived() {
super(); // this "super()" will not be considered useless if option is set to true,
// because "Derived" has multiple public ctors.
}
public Derived(int i) {
super(i); // this "super()" will not be considered useless if option is set to true,
// because "Derived" has multiple public ctors.
}
}
class NotDerived{
public NotDerived() {
super(); // this "super()" will be considered useless regardless of option value,
// because "NotDerived" does not extend anything.
}
public NotDerived(int i) {
super(); // this "super()" will be considered useless regardless of option value,
// because "NotDerived" does not extend anything.
}
}
@author Zuy Alexey
+UselessSuperCtorCallCheck.desc = Checks for useless "super()" calls in ctors.
"super()" call could be considered by Check as "useless" in two cases:
Case 1. no-argument "super()" is called from class ctor if class is not derived, for example:
class Dummy {
Dummy() {
super();
}
"super()" call is useless because class "Dummy" is not derived.Case 2. no-argument "super()" is called without parameters from class ctor if class is derived, for example:
class Derived extends Base {
Derived() {
super();
}
}
Java compiler automatically inserts a call to the no-args constructor of the super class, so there is no need to call super ctor explicitly. Check has options "allowCallToNoArgsSuperCtor" and "allowCallToNoArgsSuperCtorIfMultiplePublicCtor" to adjust check behavior for such cases(see Check`s options description for details).Check has following options:
"allowCallToNoArgsSuperCtor" - if this option set to true, Check will not generate violations when "super()" called inside derived class. This option defaults to "false". If for example this option set to "true", then Check will not generate violation for cases like following:
class Base {
public Base() {
}
}
class Derived extends Base {
public Derived() {
super();
}
}
"allowCallToNoArgsSuperCtorIfMultiplePublicCtor" - if this option set to "true",then Check will not generate violation when "super()" called inside class ctor when class has multiple public ctors(however, setting this option to"true" will not prevent Check from logging violation if class does not extend anything). This option defaults to "false". This option may be useful for cases in which class`s ctors just forward its arguments to super ctors, thus removing "super()" in this case will make default ctors look not like others.For example:
class Base {
public Base() {
}
public Base(int i) {
}
}
class Derived extends Base {
public Derived() {
super(); // this "super()" will not be considered useless if option is set to true,
// because "Derived" has multiple public ctors.
}
public Derived(int i) {
super(i); // this "super()" will not be considered useless if option is set to true,
// because "Derived" has multiple public ctors.
}
}
class NotDerived{
public NotDerived() {
super(); // this "super()" will be considered useless regardless of option value,
// because "NotDerived" does not extend anything.
}
public NotDerived(int i) {
super(); // this "super()" will be considered useless regardless of option value,
// because "NotDerived" does not extend anything.
}
}
@author Zuy Alexey
UselessSuperCtorCallCheck.allowCallToNoArgsSuperCtor = Allow calls to no-arguments super constructor from derived class.
UselessSuperCtorCallCheck.allowCallToNoArgsSuperCtorIfMultiplePublicCtor = Allow calls to no-arguments super constructor from derived class if it has multiple public constructors.
@@ -180,3 +185,9 @@ WhitespaceBeforeArrayInitializerCheck.desc = This checks enforces whitespace bef
EnumTrailingCommaAndSemicolonCheck.name = Enum Trailing Comma
EnumTrailingCommaAndSemicolonCheck.desc = This checks enforces a trailing comma at the end of a line in an enum constant definition.
+
+MoveVariableInsideIfCheck.name = Move Variable Inside If Check
+MoveVariableInsideIfCheck.desc = Checks if a variable is only used inside if statements and asks for it's declaration to be moved there too.
+
+RequireFailForTryCatchInJunitCheck.name = Require Fail For Try/Catch in JUnit Check
+RequireFailForTryCatchInJunitCheck.desc = Checks if a try/catch block has a junit fail assertion inside the try for a junit method.
diff --git a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.xml b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.xml
index 3455bd9e37..19351db51c 100644
--- a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.xml
+++ b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.xml
@@ -1,7 +1,7 @@
+"http://checkstyle.org/eclipse-cs/dtds/checkstyle-metadata_1_1.dtd">
Joshua Bloch, "Effective Java (2nd edition)" Item 28: page 137 :
"Do not use wildcard types as return types. Rather than providing additional flexibility for your users, it would force them to use wildcard types in client code. Properly used, wildcard types are nearly invisible to users of a class. They cause methods to accept the parameters they should accept and reject those they should reject. If the user of a class has to think about wildcard types, there is probably something wrong with the class\u2019s API."
@@ -50,3 +50,8 @@ HideUtilityClassConstructorCheck.desc = Make sure that utility classes (classes InnerClassCheck.name = Inner Class InnerClassCheck.desc = Check nested (internal) classes to be declared at the bottom of the class after all methods (fields) declaration. + +CheckstyleTestMakeupCheck.name = Checkstyle Test Makeup +CheckstyleTestMakeupCheck.desc = Custom check to ensure Checkstyle tests are designed correctly. +CheckstyleTestMakeupCheck.createMethodRegexp = Regular expression for matching a create configuration method by name. +CheckstyleTestMakeupCheck.verifyMethodRegexp = Regular expression for matching a verify method by name. diff --git a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/design/checkstyle-metadata.xml b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/design/checkstyle-metadata.xml index 15f325fdc0..b55cc10551 100644 --- a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/design/checkstyle-metadata.xml +++ b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/design/checkstyle-metadata.xml @@ -1,7 +1,7 @@ +"http://checkstyle.org/eclipse-cs/dtds/checkstyle-metadata_1_1.dtd">Check forces enum values to match the specific pattern. According to "Java Coding Style" by Achut Reddy p 3.3 constants include "all static final object reference types that are never followed by " ." (dot).", i.e. enums, which are followed by dot while used in the code are to be treated as static object references, while enums, that are not used with following dot, should be treated as constants.
Enums are defined to be used as class have some own methods. This condition is used to distinguish between Values Enumeration and Class Enumeration. Values Enumeration looks like the following:
enum SimpleErrorEnum\n {\n FIRST_SIMPLE, SECOND_SIMPLE, THIRD_SIMPLE;\n }
While Class Enumeration has some methods, for example:
enum SimpleErrorEnum\n {\n FIRST_SIMPLE, SECOND_SIMPLE, THIRD_SIMPLE;\n \n public String toString() {\n return Integer.toString(ordinal() + 10);\n }\n }
Name format for Class Enumeration is specified with setObjFormat(String) , while format for enum constants - with setConstFormat(String)
To avoid assuming enum as static object reference, while using some specific methods, setExcludes(List) can be used. For example to make enum in the previous example a constant set Excludes property to a value toString
By default toString is used as an exclusion.
-EnumValueNameCheck.constFormat = Regex for Values Enumeration names to conform -EnumValueNameCheck.objFormat = Regex for Class Enumeration names to conform -EnumValueNameCheck.excludes = Exclude method and field names regexp list (comma-separated) +EnumValueNameCheck.desc = Checks that enumeration value names conform to a format specified by the format property. +EnumValueNameCheck.format = Regex for enumeration value names to conform -UniformEnumConstantNameCheck.name = Enum values name +UniformEnumConstantNameCheck.name = Uniform Enum values name UniformEnumConstantNameCheck.desc = Check forces enum values to match one of the specified patterns and forces all the values to follow only one of the specified patterns. UniformEnumConstantNameCheck.formats = Regex list that enum value names should conform diff --git a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/naming/checkstyle-metadata.xml b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/naming/checkstyle-metadata.xml index 7cfc921795..d96cd7fce5 100644 --- a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/naming/checkstyle-metadata.xml +++ b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/naming/checkstyle-metadata.xml @@ -1,7 +1,7 @@ +"http://checkstyle.org/eclipse-cs/dtds/checkstyle-metadata_1_1.dtd">- * To forbid any array-valued element, frobiddenElementValueRegexp option should be: "\{.*\}". + * To forbid any array-valued element, forbiddenElementValueRegexp option should be: "\{.*\}". *
*
* Config
@@ -110,8 +110,10 @@
*
* @author Sergey Drozd
* @author Richard Veach
+ * @since 1.22.0
*/
public class ForbidAnnotationElementValueCheck extends AbstractCheck {
+
/** Message key. */
public static final String MSG_KEY = "annotation.forbid.element.value";
@@ -165,6 +167,16 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST ast) {
if (getAnnotationName(ast).equals(annotationName)) {
@@ -322,7 +334,7 @@ private static String getExpressionText(DetailAST expression) {
}
/**
- * Gets String-represented array from provided left brace
+ * Gets String-represented array from provided left brace.
*
* @param brace
* DetailAST node of type {@link TokenTypes#ANNOTATION_ARRAY_INIT}
@@ -386,4 +398,5 @@ private static String getElementName(DetailAST memberValuePair) {
final DetailAST elementName = memberValuePair.findFirstToken(TokenTypes.IDENT);
return elementName.getText();
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/annotation/RequiredParameterForAnnotationCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/annotation/RequiredParameterForAnnotationCheck.java
index 02b3533382..219f9adfbc 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/annotation/RequiredParameterForAnnotationCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/annotation/RequiredParameterForAnnotationCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -95,9 +95,11 @@
*
*
* @author Andrew Uljanenko
+ * @since 1.13.0
*/
public class RequiredParameterForAnnotationCheck extends AbstractCheck {
+
/**
* Key for error message.
*/
@@ -145,12 +147,16 @@ public int[] getRequiredTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST annotationNode) {
final String annotationNameCheck = getAnnotationName(annotationNode);
if (annotationNameCheck.equals(this.annotationName)) {
-
final Set
- * But in Java, in IF condition it is impossible to use assignment,
- * so that habit become unnecessary and do damage readability of code.
+ * If comparing values, C(C++) developers prefer to put the constant first in the equality check,
+ * to prevent situations of assignment rather than equality checking. It is easy to write "="
+ * instead of "==", and no compile error will be produced but condition will work in a different
+ * way then intended. However, in Java it is impossible to use assignment inside the
+ *
- * In C(C++), comparison for null is tricky, and it is easy to write "=" instead of "==",
- * and no complication error will be but condition will work in different way
+ * This check was extended to include all equality checks like ">", ">=", "<", "<="
+ * for users who prefer constants always be on the right-hand side for any condition.
*
@@ -51,8 +54,10 @@
* if
condition, so that habit becomes unnecessary and does damage to the readability
+ * of the code.
*
- * Return true, if inner class contain override method readObject() and - * writeObject(); - *
+ * Return {@code true}, if inner class contain override method {@code readObject()} and + * {@code writeObject()}. + * * @param classNode * the start node of class definition. * @return The boolean value. True, if method was override. @@ -188,9 +199,8 @@ private static boolean hasCorrectParameter(DetailAST methodNode, } /** - *- * Return true, if class implement Serializable interface; - *
+ * Return {@code true}, if class implement Serializable interface. + * * @param classDefNode * - the start node for class definition. * @return boolean value. True, if class implements Serializable interface. @@ -218,6 +228,7 @@ private static boolean isSerializable(DetailAST classDefNode) { * */ private final class SiblingIterator { + /** * *Next. @@ -262,5 +273,7 @@ public DetailAST nextSibling() { } return result; } + } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidHidingCauseExceptionCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidHidingCauseExceptionCheck.java index 970933cea9..2b9d316891 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidHidingCauseExceptionCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidHidingCauseExceptionCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -63,8 +63,10 @@ * @author Daniil * Yaroslavtsev * @author Ilja Dubinin + * @since 1.8.0 */ public class AvoidHidingCauseExceptionCheck extends AbstractCheck { + /** * A key is pointing to the warning message text in "messages.properties" * file. @@ -79,8 +81,17 @@ public int[] getDefaultTokens() { } @Override - public void visitToken(DetailAST detailAST) { + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + + @Override + public void visitToken(DetailAST detailAST) { final String originExcName = detailAST .findFirstToken(TokenTypes.PARAMETER_DEF).getLastChild() .getText(); @@ -132,7 +143,6 @@ private static boolean isContainsCaughtExc(ListLITERAL_THROW
literals
*/
private List* Disallow some set of modifiers for Java types specified by regexp. + *
** Field modifiers types according to Java Spec: * (https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1) + *
** Example 1: Forbid use of 'static' modifiers for 'ULCComponents' * (http://ulc.canoo.com/ulccommunity/Contributions/Extensions/GoodPractices.html) + *
* ** Never keep instances of ULC classes in static variables (ULCIcons neither!). They cannot be * shared between different sessions. + *
** So we can disallow "static" modifier for all ULC* components by setting up an * "forbiddenClassesRegexpStatic" option to "ULC.+" regexp String. + *
* ** Configuration: + *
** <module name="TreeWalker"> * <module name="AvoidModifiersForTypesCheck"> @@ -74,15 +80,17 @@ * Example 2: Forbid using annotation for fields: (e.g.* + *@Autowired
). This * can be done by setting up the "forbiddenClassesRegexpAnnotation" option to "Person" regexp * String. + * * ** Configuration: + *
** <module name="TreeWalker"> * <module name="AvoidModifiersForTypesCheck"> * <property name="forbiddenClassesRegexpAnnotation" value="Person"/> * </module> - * <module> + * </module> ** *@@ -102,13 +110,16 @@ * produce logs that are hard to investigate as logging class does not contains that code and search * should be done in other classes or in hierarchy (if filed is public or accessible by other * protected or package). + * ** @author Daniil * Yaroslavtsev + * @since 1.8.0 */ public class AvoidNotShortCircuitOperatorsForBooleanCheck extends AbstractCheck { @@ -101,12 +102,25 @@ public final int[] getDefaultTokens() { } @Override - public final void visitToken(final DetailAST detailAST) { + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override + public final void visitToken(final DetailAST detailAST) { DetailAST currentNode = detailAST; // look for EXPR which is always around BOR/BAND... operators while (currentNode != null && currentNode.getType() != TokenTypes.EXPR) { currentNode = currentNode.getParent(); + + if (currentNode.getType() == TokenTypes.PARAMETER_DEF) { + currentNode = null; + } } if (currentNode != null && isBooleanExpression(currentNode)) { @@ -144,7 +158,10 @@ public final boolean isBooleanExpression(final DetailAST node) { while (curNode.getType() != TokenTypes.CTOR_DEF && curNode.getType() != TokenTypes.METHOD_DEF - && curNode.getType() != TokenTypes.CLASS_DEF) { + && curNode.getType() != TokenTypes.CLASS_DEF + && curNode.getType() != TokenTypes.INTERFACE_DEF + && curNode.getType() != TokenTypes.ANNOTATION_DEF + && curNode.getType() != TokenTypes.ENUM_DEF) { curNode = curNode.getParent(); } @@ -152,7 +169,6 @@ public final boolean isBooleanExpression(final DetailAST node) { for (DetailAST currentNode : getChildren(curNode.getLastChild())) { if (currentNode.getLineNo() < line && currentNode.getType() == TokenTypes.VARIABLE_DEF) { - if (isBooleanType(currentNode)) { booleanVariablesNames.add(currentNode.findFirstToken( TokenTypes.IDENT).getText()); @@ -161,7 +177,6 @@ public final boolean isBooleanExpression(final DetailAST node) { } boolean result = false; - for (String name : childNames) { if (booleanVariablesNames.contains(name)) { result = true; @@ -180,9 +195,7 @@ public final boolean isBooleanExpression(final DetailAST node) { */ public final List* This check can be activated by setting up the "forbiddenClassesRegexpPublic", * "forbiddenClassesRegexpPackagePrivate" and "forbiddenClassesRegexpProtected" options to "Logger" * regexp String. + *
* ** Configuration: + *
** <module name="TreeWalker"> * <module name="AvoidModifiersForTypesCheck"> @@ -116,7 +127,7 @@ * <property name="forbiddenClassesRegexpPublic" value="Logger"/> * <property name="forbiddenClassesRegexpPackagePrivate" value="Logger"/> * <module> - * <module> + * </module> ** *@@ -132,9 +143,10 @@ * * } *- *+ * * @author Daniil Yaroslavtsev * @author Yasser Aziza + * @since 1.8.0 */ public class AvoidModifiersForTypesCheck extends AbstractCheck { @@ -384,12 +396,21 @@ public int[] getDefaultTokens() { return new int[] {TokenTypes.VARIABLE_DEF }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST ast) { final String classNameAndPath = getClassNameAndPath(ast); if (classNameAndPath != null) { - final String className = getClassName(classNameAndPath); final Set
modifiersSet = getModifiers(ast); @@ -516,7 +537,7 @@ private static String getClassName(final String classNameAndPath) { * Gets the modifiers of the defined variable (annotation, public, private, final, static, * transient or volatile). * @param variableDefAst - * A DeatilAST node is related to the variable definition + * A DetailAST node is related to the variable definition * (VARIABLE_DEF type) * @return List of token types is related to the given variable modifiers. */ diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidNotShortCircuitOperatorsForBooleanCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidNotShortCircuitOperatorsForBooleanCheck.java index 489f7d6532..87df5a07e9 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidNotShortCircuitOperatorsForBooleanCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/AvoidNotShortCircuitOperatorsForBooleanCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -69,6 +69,7 @@ * getSupportedOperandsNames( final DetailAST exprParentAST) { - for (DetailAST currentNode : getChildren(exprParentAST)) { - if (currentNode.getNumberOfChildren() > 0 && currentNode.getType() != TokenTypes.METHOD_CALL) { getSupportedOperandsNames(currentNode); @@ -192,10 +205,6 @@ public final List getSupportedOperandsNames( && currentNode.getParent().getType() != TokenTypes.DOT) { supportedOperands.add(currentNode.getText()); } - - if (currentNode.getNextSibling() != null) { - currentNode = currentNode.getNextSibling(); - } } return supportedOperands; } @@ -208,9 +217,7 @@ public final List getSupportedOperandsNames( * "true" or "false" keywords and false otherwise. */ public final boolean hasTrueOrFalseLiteral(final DetailAST parentAST) { - for (DetailAST currentNode : getChildren(parentAST)) { - if (currentNode.getNumberOfChildren() > 0) { hasTrueOrFalseLiteral(currentNode); } @@ -221,10 +228,6 @@ public final boolean hasTrueOrFalseLiteral(final DetailAST parentAST) { hasTrueOrFalseLiteral = true; } - if (currentNode.getNextSibling() != null) { - currentNode = currentNode.getNextSibling(); - } - if (hasTrueOrFalseLiteral) { break; } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ConfusingConditionCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ConfusingConditionCheck.java index 4f1a893b79..c1dea6c8ba 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ConfusingConditionCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ConfusingConditionCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -48,7 +48,7 @@ * and swapped code in "if" and "else" block: * * - * if (a == b && c == d) + * if (a == b || c == d) * { * smth2(); * } @@ -59,8 +59,10 @@ ** * @author Vadim Panasiuk + * @since 1.9.0 */ public class ConfusingConditionCheck extends AbstractCheck { + /** * The key is pointing to the message text String in * "messages.properties file".This message used for common cases. @@ -157,6 +159,16 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST literalIf) { if (isIfEndsWithElse(literalIf) @@ -166,7 +178,7 @@ public void visitToken(DetailAST literalIf) { if (isRatioBetweenIfAndElseBlockSuitable(literalIf) && !(ignoreNullCaseInIf && isIfWithNull(literalIf)) && isConditionAllNegative(literalIf)) { - log(literalIf.getLineNo(), MSG_KEY); + log(literalIf, MSG_KEY); } } } @@ -231,9 +243,9 @@ private boolean isRatioBetweenIfAndElseBlockSuitable(DetailAST literalIf) { boolean result = true; final DetailAST lastChildAfterIf = literalIf.getLastChild(); - final int linesOfCodeInIfBlock = getAmounOfCodeRowsInBlock(literalIf); - final int linesOfCodeInElseBlock = getAmounOfCodeRowsInBlock(lastChildAfterIf); + final int linesOfCodeInElseBlock = getAmountOfCodeRowsInBlock(lastChildAfterIf); if (linesOfCodeInElseBlock > 0) { + final int linesOfCodeInIfBlock = getAmountOfCodeRowsInBlock(literalIf); result = linesOfCodeInIfBlock / linesOfCodeInElseBlock < multiplyFactorForElseBlocks; } return result; @@ -245,23 +257,51 @@ private boolean isRatioBetweenIfAndElseBlockSuitable(DetailAST literalIf) { * @param detailAST The token to examine. * @return linesOfCodeInIfBlock line of code in block. */ - private static int getAmounOfCodeRowsInBlock(DetailAST detailAST) { + private static int getAmountOfCodeRowsInBlock(DetailAST detailAST) { + final DetailAST firstBrace = getFirstBrace(detailAST); + int linesOfCodeInIfBlock; + + if (firstBrace == null) { + linesOfCodeInIfBlock = 0; + } + else { + final DetailAST lastBrace = firstBrace.getLastChild(); + linesOfCodeInIfBlock = lastBrace.getLineNo() + - firstBrace.getLineNo(); + // If the closing brace on a separate line - ignore this line. + if (lastBrace.getLineNo() != lastBrace.getParent().getLineNo()) { + linesOfCodeInIfBlock -= 1; + } + } + + return linesOfCodeInIfBlock; + } + + /** + * Retrieves the first, opening brace of an {@code if} or {@code else} statement. + * @param detailAST The token to examine. + * @return The opening brace token or {@code null} if it doesn't exist. + */ + private static DetailAST getFirstBrace(DetailAST detailAST) { DetailAST firstBrace = null; + if (detailAST.getType() == TokenTypes.LITERAL_ELSE) { firstBrace = detailAST.getFirstChild(); + + if (firstBrace.getType() == TokenTypes.LITERAL_IF) { + firstBrace = getFirstBrace(firstBrace); + } } - else if (detailAST.getType() == TokenTypes.LITERAL_IF) { + else { firstBrace = detailAST.getFirstChild().getNextSibling() .getNextSibling().getNextSibling(); } - final DetailAST lastBrace = firstBrace.getLastChild(); - int linesOfCodeInIfBlock = lastBrace.getLineNo() - - firstBrace.getLineNo(); - // If the closing brace on a separate line - ignore this line. - if (lastBrace.getLineNo() != lastBrace.getParent().getLineNo()) { - linesOfCodeInIfBlock -= 1; + + if (firstBrace != null && firstBrace.getType() != TokenTypes.SLIST) { + firstBrace = null; } - return linesOfCodeInIfBlock; + + return firstBrace; } /** diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/CustomDeclarationOrderCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/CustomDeclarationOrderCheck.java index e95b2e7635..63ef20bd58 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/CustomDeclarationOrderCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/CustomDeclarationOrderCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -32,8 +32,6 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import org.apache.commons.beanutils.ConversionException; - import com.puppycrawl.tools.checkstyle.api.AbstractCheck; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; @@ -42,6 +40,7 @@ ** Checks that the parts of a class(main, nested, member inner) declaration * appear in the rules order set by user using regular expressions. + *
** The check forms line which consists of class member annotations, modifiers, * type and name from your code and compares it with your RegExp. @@ -55,7 +54,7 @@ * insensitive): *
*
- "Field" to denote the Fields
- *- "DeclareAnnonClassField" to denote the fields keeping objects of anonymous classes
+ *- "DeclareAnonClassField" to denote the fields keeping objects of anonymous classes
*- "Ctor" to denote the Constructors
*- "Method" to denote the Methods
*- "GetterSetter" to denote the group of getter and setter methods
@@ -116,8 +115,11 @@ * * *What is group of getters and setters(
+ * *GetterSetter
)?* It is ordered sequence of getters and setters like: + *
+ * ** public int getValue() { * log.info("Getting value"); @@ -150,8 +152,10 @@ * * @author Danil Lopatin * @author Baratali Izmailov + * @since 1.8.0 */ public class CustomDeclarationOrderCheck extends AbstractCheck { + /** * A key is pointing to the warning message text in "messages.properties" * file. @@ -194,28 +198,40 @@ public class CustomDeclarationOrderCheck extends AbstractCheck { */ public static final String MSG_KEY_INVALID_SETTER = "custom.declaration.order.invalid.setter"; + /** Macro string for inner enumeration. */ private static final String INNER_ENUM_MACRO = "InnerEnum"; + /** Macro string for inner interface. */ private static final String INNER_INTERFACE_MACRO = "InnerInterface"; + /** Macro string for inner class. */ private static final String INNER_CLASS_MACRO = "InnerClass"; + /** Macro string for constructor. */ private static final String CTOR_MACRO = "Ctor"; + /** Macro string for method. */ private static final String METHOD_MACRO = "Method"; - private static final String ANNON_CLASS_FIELD_MACRO = "DeclareAnnonClassField"; + /** Macro string for anonymous class field. */ + private static final String ANON_CLASS_FIELD_MACRO = "DeclareAnonClassField"; + /** Macro string for field. */ private static final String FIELD_MACRO = "Field"; + /** Macro string for getter and setter. */ private static final String GETTER_SETTER_MACRO = "GetterSetter"; + /** Macro string for main method. */ private static final String MAIN_METHOD_MACRO = "MainMethod"; + /** Prefix for boolean getter method name. */ private static final String BOOLEAN_GETTER_PREFIX = "is"; + /** Prefix for getter method name. */ private static final String GETTER_PREFIX = "get"; + /** Prefix for setter method name. */ private static final String SETTER_PREFIX = "set"; /** Default format for custom declaration check. */ @@ -335,14 +351,22 @@ else if (currentRule.hasRule(GETTER_SETTER_MACRO)) { return tokenTypes; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST ast) { switch (ast.getType()) { - case TokenTypes.CLASS_DEF: if (!isClassDefInMethodDef(ast)) { if (checkInnerClasses && !classDetails.isEmpty()) { - final int position = getPositionInOrderDeclaration(ast); if (position != -1) { @@ -363,7 +387,6 @@ public void visitToken(DetailAST ast) { final DetailAST objBlockAst = ast.getParent(); if (objBlockAst != null && objBlockAst.getType() == TokenTypes.OBJBLOCK) { - final DetailAST classDefAst = objBlockAst.getParent(); if (classDefAst.getType() == TokenTypes.CLASS_DEF @@ -384,7 +407,6 @@ public void visitToken(DetailAST ast) { } } } - } } @@ -392,10 +414,11 @@ public void visitToken(DetailAST ast) { public void leaveToken(DetailAST ast) { if (ast.getType() == TokenTypes.CLASS_DEF && !isClassDefInMethodDef(ast)) { + // -@cs[MoveVariableInsideIf] assignment value is a modification + // call so it can't be moved final ClassDetail classDetail = classDetails.pop(); if (checkGettersSetters) { - final Map* * @author Max Vetrenko - * + * @since 1.11.0 */ public class FinalizeImplementationCheck extends AbstractCheck { @@ -92,14 +93,23 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST methodDefToken) { if (isFinalizeMethodSignature(methodDefToken)) { - final String warningMessage = validateFinalizeMethod(methodDefToken); if (warningMessage != null) { - log(methodDefToken.getLineNo(), warningMessage); + log(methodDefToken, warningMessage); } } } @@ -124,7 +134,6 @@ private static String validateFinalizeMethod(DetailAST finalizeMethodToken) { else { warningMessage = MSG_KEY_MISSED_TRY_FINALLY; } - } else { final DetailAST literalFinally = literalTry @@ -135,7 +144,6 @@ private static String validateFinalizeMethod(DetailAST finalizeMethodToken) { warningMessage = MSG_KEY_MISSED_SUPER_FINALIZE_CALL; } } - } else { warningMessage = MSG_KEY_PUBLIC_FINALIZE; @@ -160,7 +168,7 @@ && isFinalizeMethodName(methodDefToken) && isVoid(methodDefToken) * @param modifierType * modifier type. * @param methodToken - * MODIFIRES Token. + * MODIFIERS Token. * @return true, if finalize() has "protected" access modifier. */ private static boolean hasModifier(int modifierType, DetailAST methodToken) { @@ -207,13 +215,16 @@ private static int getParamsCount(DetailAST methodDefToken) { * @return true, if method has super.finalize() call. */ private static boolean containsSuperFinalizeCall(DetailAST openingBrace) { + boolean result = false; final DetailAST methodCallToken = openingBrace.getFirstChild().getFirstChild(); - if (methodCallToken != null) { + if (methodCallToken != null && methodCallToken.getType() == TokenTypes.METHOD_CALL) { final DetailAST dotToken = methodCallToken.getFirstChild(); - if (dotToken.findFirstToken(TokenTypes.LITERAL_SUPER) != null) { - return true; + if (dotToken.getType() == TokenTypes.DOT + && dotToken.findFirstToken(TokenTypes.LITERAL_SUPER) != null) { + result = true; } } - return false; + return result; } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCCommentsInMethodsCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCCommentsInMethodsCheck.java index 8a92114b3f..6a9b1b8c05 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCCommentsInMethodsCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCCommentsInMethodsCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,8 @@ package com.github.sevntu.checkstyle.checks.coding; -import java.util.Set; +import java.util.ArrayDeque; +import java.util.Deque; import com.puppycrawl.tools.checkstyle.api.AbstractCheck; import com.puppycrawl.tools.checkstyle.api.DetailAST; @@ -31,47 +32,81 @@ * class declaration into the method body you will get an error. * * @author Ilia Dubinin + * @since 1.6.0 */ public class ForbidCCommentsInMethodsCheck extends AbstractCheck { + /** * Warning message key. */ public static final String MSG_KEY = "forbid.c.comments.in.the.method.body"; - /** - * Set contains C style comments from current file. - */ - private SetgettersSetters = classDetail.getWrongOrderedGettersSetters(); @@ -406,7 +429,7 @@ public void leaveToken(DetailAST ast) { /** * Parse input current declaration rule and create new instance of - * FormatMather with matcher + * FormatMather with matcher. * * @param currentState input string with MemberDefinition and RegExp. * @return new FormatMatcher with parsed and compile rule @@ -418,7 +441,7 @@ private FormatMatcher parseInputDeclarationRule(final String currentState) { final int classMember = convertMacroToTokenType(macro); if (classMember == -1) { // if Class Member has been specified wrong - throw new ConversionException("Unable to parse " + macro); + throw new IllegalArgumentException("Unable to parse " + macro); } // parse regExp @@ -448,7 +471,7 @@ private static int convertMacroToTokenType( String inputMemberName) { int result = -1; if (FIELD_MACRO.equalsIgnoreCase(inputMemberName) - || ANNON_CLASS_FIELD_MACRO.equalsIgnoreCase(inputMemberName)) { + || ANON_CLASS_FIELD_MACRO.equalsIgnoreCase(inputMemberName)) { result = TokenTypes.VARIABLE_DEF; } else if (GETTER_SETTER_MACRO.equalsIgnoreCase(inputMemberName) @@ -549,11 +572,10 @@ private boolean isWrongPosition(final int position) { */ private void logWrongOrderedSetters(Map gettersSetters) { for (Entry entry: gettersSetters.entrySet()) { - final DetailAST setterAst = entry.getKey(); final DetailAST getterAst = entry.getValue(); - log(setterAst.getLineNo(), + log(setterAst, MSG_KEY_INVALID_SETTER, getIdentifier(setterAst), getIdentifier(getterAst)); @@ -600,10 +622,9 @@ private int getPositionInOrderDeclaration(final DetailAST ast) { final FormatMatcher currentRule = customOrderDeclaration.get(index); if (currentRule.getClassMember() == ast.getType() && currentRule.getRegexp().matcher(modifiers).find()) { - if (currentRule.hasRule(ANNON_CLASS_FIELD_MACRO) + if (currentRule.hasRule(ANON_CLASS_FIELD_MACRO) || currentRule.hasRule(GETTER_SETTER_MACRO) || currentRule.hasRule(MAIN_METHOD_MACRO)) { - final String methodName = getIdentifier(ast); final ClassDetail classDetail = classDetails.peek(); @@ -689,14 +710,10 @@ private static boolean isSetterName(String methodName) { private boolean isGetterCorrect(DetailAST methodDef, String methodPrefix) { boolean result = false; - final String methodName = getIdentifier(methodDef); - final String methodNameWithoutPrefix = getNameWithoutPrefix(methodName, methodPrefix); - final DetailAST parameters = methodDef.findFirstToken(TokenTypes.PARAMETERS); // no parameters if (parameters.getChildCount() == 0) { - final DetailAST statementsAst = methodDef.findFirstToken(TokenTypes.SLIST); if (statementsAst != null) { final DetailAST returnStatementAst = statementsAst @@ -705,6 +722,9 @@ private boolean isGetterCorrect(DetailAST methodDef, String methodPrefix) { if (returnStatementAst != null) { final DetailAST exprAst = returnStatementAst.getFirstChild(); final String returnedFieldName = getNameOfGetterField(exprAst); + final String methodName = getIdentifier(methodDef); + final String methodNameWithoutPrefix = getNameWithoutPrefix(methodName, + methodPrefix); if (returnedFieldName != null && !localVariableHidesField(statementsAst, returnedFieldName) && verifyFieldAndMethodName(returnedFieldName, @@ -750,15 +770,13 @@ private static boolean localVariableHidesField(DetailAST slist, private boolean isSetterCorrect(DetailAST methodDefAst, String methodPrefix) { boolean result = false; - final String methodName = getIdentifier(methodDefAst); - final String setterFieldName = fieldPrefix - + getNameWithoutPrefix(methodName, methodPrefix); - final DetailAST methodTypeAst = methodDefAst.findFirstToken(TokenTypes.TYPE); - if (methodTypeAst.branchContains(TokenTypes.LITERAL_VOID)) { - + if (methodTypeAst.findFirstToken(TokenTypes.LITERAL_VOID) != null) { final DetailAST statementsAst = methodDefAst.findFirstToken(TokenTypes.SLIST); + final String methodName = getIdentifier(methodDefAst); + final String setterFieldName = fieldPrefix + + getNameWithoutPrefix(methodName, methodPrefix); result = statementsAst != null && !localVariableHidesField(statementsAst, setterFieldName) @@ -801,7 +819,7 @@ private static String getCombinedModifiersList(final DetailAST ast) { } while (astNode.getType() != TokenTypes.IDENT) { - if (astNode != null && astNode.getFirstChild() != null) { + if (astNode.getFirstChild() != null) { modifiers.append(getModifiersAsText(astNode.getFirstChild())); modifiers.append(" "); } @@ -868,11 +886,12 @@ private static String getNameWithoutPrefix(String name, String prefix) { * @return identifier of AST, null if AST does not have name. */ private static String getIdentifier(final DetailAST ast) { + String result = null; final DetailAST ident = ast.findFirstToken(TokenTypes.IDENT); if (ident != null) { - return ident.getText(); + result = ident.getText(); } - return null; + return result; } /** @@ -886,7 +905,6 @@ private static boolean isFieldUpdate(DetailAST statementsAst, String fieldName) DetailAST currentStatement = statementsAst.getFirstChild(); while (currentStatement != null && currentStatement != statementsAst) { - String nameOfSetterField = null; if (currentStatement.getType() == TokenTypes.ASSIGN) { nameOfSetterField = getNameOfAssignedField(currentStatement); @@ -928,7 +946,6 @@ private static String getNameOfAssignedField(DetailAST assignAst) { if (assignAst.getChildCount() > 0 && (assignAst.getLastChild().getType() == TokenTypes.IDENT || assignAst.getLastChild().getType() == TokenTypes.METHOD_CALL)) { - final DetailAST methodCallDot = assignAst.getFirstChild(); if (methodCallDot.getChildCount() == 2 && "this".equals(methodCallDot.getFirstChild().getText())) { @@ -960,9 +977,8 @@ private static String getNameOfSuperClassUpdatedField(DetailAST methodCallAst) { } /** - * - * Gets name of the field, that was used in calling setter from a super class - *
+ * Gets name of the field, that was used in calling setter from a super class. + * * @param methodCallDotAst The token to examine. * @return * name of field in method parameter. @@ -1007,9 +1023,7 @@ private static String getNameOfGetterField(DetailAST expr) { final DetailAST exprFirstChild = expr.getFirstChild(); if (exprFirstChild.getType() == TokenTypes.IDENT) { - nameOfGetterField = exprFirstChild.getText(); - } else if (exprFirstChild.getType() == TokenTypes.DOT && exprFirstChild.getChildCount() == 2 @@ -1068,9 +1082,8 @@ private static boolean isMainMethodModifiers(final DetailAST methodAST) { */ private static boolean isVoidType(final DetailAST methodAST) { boolean result = true; - DetailAST methodTypeAST = null; if (hasChildToken(methodAST, TokenTypes.TYPE)) { - methodTypeAST = methodAST.findFirstToken(TokenTypes.TYPE); + final DetailAST methodTypeAST = methodAST.findFirstToken(TokenTypes.TYPE); result = hasChildToken(methodTypeAST, TokenTypes.LITERAL_VOID); } return result; @@ -1169,6 +1182,7 @@ private static boolean hasChildToken(DetailAST ast, int tokenType) { * Private class for members of class and their patterns. */ private static final class FormatMatcher { + /** The regexp to match against. */ private Pattern regExp; /** The Member of Class. */ @@ -1235,7 +1249,7 @@ private void updateRegexp(final String newFormat, final int compileFlags) { this.format = newFormat; } catch (final PatternSyntaxException ex) { - throw new ConversionException("unable to parse " + newFormat, ex); + throw new IllegalArgumentException("unable to parse " + newFormat, ex); } } @@ -1252,12 +1266,14 @@ public boolean hasRule(String ruleCheck) { public String toString() { return rule; } + } /** * Class to keep current position and collect getters, setters. */ private static class ClassDetail { + /** * Current position in custom order declaration. */ @@ -1319,13 +1335,12 @@ public MapgetWrongOrderedGettersSetters() { /** * Compare order of getters and setters. Order should be like "getX; setX; getY; setY; ...". * If it is wrong order, then wrong ordered setters and getters will be returned as map. - * @param allGettersSetters collection of all gettter and setters + * @param allGettersSetters collection of all getter and setters * @param index index from upper loo * @return Map with setter AST as key and getter AST as value. */ private static Map getWrongOrderedGettersSetters( List allGettersSetters, int index) { - final DetailAST getterAst = allGettersSetters.get(index); final String getterName = getIdentifier(getterAst); String getterField = null; @@ -1345,9 +1360,8 @@ else if (isBooleanGetterName(getterName)) { // method is NOT getter final DetailAST setterAst = allGettersSetters.get(j); final String setterName = getIdentifier(setterAst); - String setterField = null; if (isSetterName(setterName)) { - setterField = getNameWithoutPrefix( + final String setterField = getNameWithoutPrefix( getIdentifier(setterAst), SETTER_PREFIX); // if fields are same and setter is sibling with getter @@ -1394,6 +1408,7 @@ private boolean containsSetter(String methodName) { } return result; } + } } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/DiamondOperatorForVariableDefinitionCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/DiamondOperatorForVariableDefinitionCheck.java index 78339c8fea..c92a6906dc 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/DiamondOperatorForVariableDefinitionCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/DiamondOperatorForVariableDefinitionCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,7 @@ * * * @author Aleksey Nesterenko + * @since 1.12.0 */ public class DiamondOperatorForVariableDefinitionCheck extends AbstractCheck { @@ -53,17 +54,24 @@ public int[] getDefaultTokens() { } @Override - public void visitToken(DetailAST variableDefNode) { + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override + public void visitToken(DetailAST variableDefNode) { final DetailAST assignNode = variableDefNode.findFirstToken(TokenTypes.ASSIGN); if (assignNode != null) { - final DetailAST newNode = assignNode.getFirstChild().getFirstChild(); // we check only creation by NEW if (newNode.getType() == TokenTypes.LITERAL_NEW) { - final DetailAST variableDefNodeType = variableDefNode.findFirstToken(TokenTypes.TYPE); final DetailAST varDefArguments = getFirstTypeArgumentsToken(variableDefNodeType); @@ -73,7 +81,6 @@ public void visitToken(DetailAST variableDefNode) { && newNode.getLastChild().getType() != TokenTypes.OBJBLOCK // arrays can not be generics && newNode.findFirstToken(TokenTypes.ARRAY_DECLARATOR) == null) { - final DetailAST typeArgs = getFirstTypeArgumentsToken(newNode); if (varDefArguments.equalsTree(typeArgs)) { @@ -96,12 +103,10 @@ private static DetailAST getFirstTypeArgumentsToken(DetailAST rootToken) { if (resultNode.getType() == TokenTypes.DOT) { resultNode = resultNode.getFirstChild().getNextSibling(); } - if (resultNode.getType() != TokenTypes.TYPE_ARGUMENTS) { - final DetailAST childNode = getFirstTypeArgumentsToken(resultNode); + final DetailAST childNode = getFirstTypeArgumentsToken(resultNode); - if (childNode == null) { - resultNode = resultNode.getNextSibling(); - } + if (childNode == null) { + resultNode = resultNode.getNextSibling(); } } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EitherLogOrThrowCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EitherLogOrThrowCheck.java index 2e6e402957..f44c4c50c9 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EitherLogOrThrowCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EitherLogOrThrowCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,7 @@ * * * Examples: + *
* ** catch (NoSuchMethodException e) { @@ -70,6 +71,7 @@ ** What check can detect:
*
* Loggers + **
*- logger is declared as class field
*- logger is declared as method's local variable
@@ -86,6 +88,7 @@ ** What check can not detect:
*
+ **
*- loggers that is used like method's return value. Example: * @@ -103,6 +106,7 @@ *
* Default parameters are: + *
**
- loggerFullyQualifiedClassName - fully qualified class name of * logger type. Default value is "org.slf4j.Logger".
@@ -114,8 +118,10 @@ * different loggers, then create another instance of this check. * * @author Baratali Izmailov + * @since 1.9.0 */ public class EitherLogOrThrowCheck extends AbstractCheck { + /** * Key for error message. */ @@ -204,6 +210,16 @@ public int[] getDefaultTokens() { TokenTypes.METHOD_DEF, }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(final DetailAST ast) { switch (ast.getType()) { @@ -246,6 +262,7 @@ && isLoggerVariableDefinition(ast)) { } /** + * Checks if AST object is logger import. * @param importAst * DetailAST of import statement. * @return true if import equals logger full class name. @@ -333,7 +350,7 @@ && isLoggerVariableDefinition(variableDefAst)) { */ private void processCatchNode(final DetailAST catchAst) { boolean isLoggingExceptionFound = false; - int loggingExceptionLineNumber = 0; + DetailAST loggingExceptionAst = null; final ListexceptionVariableNames = new LinkedList<>(); final String catchParameterName = getCatchParameterName(catchAst); final DetailAST statementsAst = @@ -365,7 +382,7 @@ && isInstanceCreationBasedOnException( && (isLoggingExceptionArgument(currentStatementAst, catchParameterName) || isPrintStackTrace(currentStatementAst, catchParameterName))) { isLoggingExceptionFound = true; - loggingExceptionLineNumber = currentStatementAst.getLineNo(); + loggingExceptionAst = currentStatementAst; } break; // throw exception @@ -377,7 +394,7 @@ && isInstanceCreationBasedOnException( if (exceptionVariableNames.contains(getIdentifier(thrownExceptionAst)) || isInstanceCreationBasedOnException( thrownExceptionAst, catchParameterName)) { - log(loggingExceptionLineNumber, MSG_KEY); + log(loggingExceptionAst, MSG_KEY); break; } } @@ -567,11 +584,11 @@ private static boolean isPrintStackTrace(final DetailAST expressionAst, /** * Verify that method is invoked on aUsedInstanceName. - * @param usedInstanseName name of instance. + * @param usedInstanceName name of instance. * @param methodCallAst DetailAST of METHOD_CALL. * @return true if method is invoked on aUsedInstanceName. */ - private static boolean isInstanceMethodCall(final String usedInstanseName, + private static boolean isInstanceMethodCall(final String usedInstanceName, final DetailAST methodCallAst) { boolean result = false; if (methodCallAst != null @@ -582,7 +599,7 @@ private static boolean isInstanceMethodCall(final String usedInstanseName, if (firstDotIndex != -1) { final String usedObjectName = methodCallIdent.substring(0, firstDotIndex); - if (usedObjectName.equals(usedInstanseName)) { + if (usedObjectName.equals(usedInstanceName)) { result = true; } } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EmptyPublicCtorInClassCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EmptyPublicCtorInClassCheck.java index 6cc4c4f67a..4e7c0ce04c 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EmptyPublicCtorInClassCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/EmptyPublicCtorInClassCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -37,6 +37,7 @@ * * * Example 1. Check will generate violation for this code: + *
* ** class Dummy { @@ -47,6 +48,7 @@ * ** * @author Zuy Alexey + * @since 1.13.0 */ public class EmptyPublicCtorInClassCheck extends AbstractCheck { + /** * Violation message key. */ @@ -166,6 +175,16 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void beginTree(DetailAST aRootNode) { singleTypeImports.clear(); @@ -176,7 +195,6 @@ public void beginTree(DetailAST aRootNode) { @Override public void visitToken(DetailAST node) { switch (node.getType()) { - case TokenTypes.IMPORT: final String packageMemberName = getIdentifierName(node); @@ -223,7 +241,7 @@ private static int getClassCtorCount(DetailAST classDefNode) { } /** - * Gets first constructor defininition for class. + * Gets first constructor definition for class. * @param classDefNode * a class definition node. * @return first ctor definition node for class or null if class has no ctor. @@ -408,15 +426,18 @@ private static boolean isOnDemandImport(String importTargetName) { */ private static String joinSingleTypeImportWithIdentifier(String importEntry, String identifierName) { + final String result; final String importEntryLastPart = getSimpleIdentifierNameFromQualifiedName(importEntry); final String annotationNameFirstPart = getQualifiedNameFirstPart(identifierName); if (importEntryLastPart.equals(annotationNameFirstPart)) { - return importEntry + identifierName.substring(annotationNameFirstPart.length()); + result = importEntry + identifierName.substring(annotationNameFirstPart.length()); } else { - return null; + result = null; } + + return result; } /** @@ -465,14 +486,17 @@ private static boolean isOnDemandImport(String importTargetName) { * argument. */ private static String getQualifiedNameFirstPart(String canonicalName) { + final String result; final int firstDotIndex = canonicalName.indexOf('.'); if (firstDotIndex == -1) { - return canonicalName; + result = canonicalName; } else { - return canonicalName.substring(0, firstDotIndex); + result = canonicalName.substring(0, firstDotIndex); } + + return result; } /** @@ -521,4 +545,5 @@ private static String getIdentifierName(DetailAST identifierNode) { return result; } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/FinalizeImplementationCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/FinalizeImplementationCheck.java index c7f1802080..9b48a037a3 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/FinalizeImplementationCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/FinalizeImplementationCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,7 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes; /** + * Validates finalize method implementation. ** Example 2. Check will not generate violation for this code: + *
* ** class Dummy { @@ -55,9 +57,12 @@ * } ** + ** class Dummy has only one ctor, which is not public. + *
** Example 3. Check will not generate violation for this code: + *
* ** class Dummy { @@ -68,7 +73,9 @@ * } ** + ** class Dummy has multiple ctors. + *
** Check has two properties: *
@@ -94,8 +101,10 @@ ** This Check detects 3 most common cases of incorrect finalize() method implementation: *
@@ -50,7 +51,7 @@ * }clangComments; + /** AST to use for null checks because {@link Deque} doesn't allow null elements. */ + private static final DetailAST NULL_AST = new DetailAST(); + + /** Method stack. */ + private final Deque scopeStack = new ArrayDeque<>(); + + /** Reference to current method. */ + private DetailAST methodAst; @Override public int[] getDefaultTokens() { return new int[] { TokenTypes.METHOD_DEF, + TokenTypes.OBJBLOCK, + TokenTypes.BLOCK_COMMENT_BEGIN, }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + + @Override + public boolean isCommentNodesRequired() { + return true; + } + @Override public void beginTree(DetailAST rootAST) { - clangComments = getFileContents().getCComments().keySet(); + methodAst = NULL_AST; } @Override - public void visitToken(DetailAST methodNode) { - if (!clangComments.isEmpty()) { - final DetailAST borders = - methodNode.findFirstToken(TokenTypes.SLIST); - //Could be null when aMethodNode doesn't have body - //(into interface for example) - if (borders != null) { - final int methodBodyBegin = borders.getLineNo(); - final int methodBodyEnd = borders.getLastChild().getLineNo(); - for (final int commentLineNo : clangComments) { - if (commentLineNo > methodBodyBegin - && commentLineNo < methodBodyEnd) { - log(commentLineNo, MSG_KEY); + public void visitToken(DetailAST ast) { + scopeStack.push(methodAst); + + switch (ast.getType()) { + case TokenTypes.METHOD_DEF: + methodAst = ast; + break; + case TokenTypes.OBJBLOCK: + methodAst = NULL_AST; + break; + default: + if (methodAst != NULL_AST) { + final DetailAST lcurly = methodAst.findFirstToken(TokenTypes.SLIST); + if (lcurly != null + && (ast.getLineNo() > lcurly.getLineNo() + || ast.getLineNo() == lcurly.getLineNo() + && ast.getColumnNo() > lcurly.getColumnNo())) { + log(ast, MSG_KEY); } } - } + break; } } + + @Override + public void leaveToken(DetailAST ast) { + methodAst = scopeStack.pop(); + } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainImportsCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainImportsCheck.java index 79eddd1e9f..97a64abb47 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainImportsCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainImportsCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -56,6 +56,7 @@ * * @author Daniil * Yaroslavtsev + * @since 1.8.0 */ public class ForbidCertainImportsCheck extends AbstractCheck { @@ -117,14 +118,6 @@ public void setForbiddenImportsRegexp(String forbiddenImportsRegexp) { } } - /** - * Gets the regexp for excluding imports from checking. - * @return regexp for excluding imports from checking. - */ - public String getForbiddenImportsExcludesRegexp() { - return forbiddenImportsExcludesRegexp.toString(); - } - /** * Sets the regexp for excluding imports from checking. * @param forbiddenImportsExcludesRegexp @@ -140,16 +133,26 @@ public void setForbiddenImportsExcludesRegexp(String @Override public int[] getDefaultTokens() { - final int[] defaultTokens; - if (packageNamesRegexp == null || forbiddenImportsRegexp == null - || forbiddenImportsExcludesRegexp == null) { - defaultTokens = new int[] {}; - } - else { - defaultTokens = new int[] {TokenTypes.PACKAGE_DEF, - TokenTypes.IMPORT, TokenTypes.LITERAL_NEW, }; - } - return defaultTokens; + return new int[] { + TokenTypes.PACKAGE_DEF, + TokenTypes.IMPORT, + TokenTypes.LITERAL_NEW, + }; + } + + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + + @Override + public void beginTree(DetailAST rootAST) { + packageMatches = false; } @Override @@ -163,22 +166,16 @@ public void visitToken(DetailAST ast) { } break; case TokenTypes.IMPORT: - if (packageMatches && forbiddenImportsRegexp != null - && forbiddenImportsExcludesRegexp != null) { - final String importQualifiedText = getText(ast); - if (isImportForbidden(importQualifiedText)) { - log(ast, importQualifiedText); - } + final String importQualifiedText = getText(ast); + if (isImportForbidden(importQualifiedText)) { + log(ast, importQualifiedText); } break; case TokenTypes.LITERAL_NEW: - if (forbiddenImportsRegexp != null - && forbiddenImportsExcludesRegexp != null - && packageMatches - && ast.findFirstToken(TokenTypes.DOT) != null) { - final String importQualifiedText = getText(ast); - if (isImportForbidden(importQualifiedText)) { - log(ast, importQualifiedText); + if (ast.findFirstToken(TokenTypes.DOT) != null) { + final String classQualifiedText = getText(ast); + if (isImportForbidden(classQualifiedText)) { + log(ast, classQualifiedText); } } break; @@ -195,8 +192,11 @@ public void visitToken(DetailAST ast) { * classes package, false otherwise */ private boolean isImportForbidden(String importText) { - return forbiddenImportsRegexp.matcher(importText).matches() - && !forbiddenImportsExcludesRegexp.matcher(importText).matches(); + return packageMatches + && forbiddenImportsRegexp != null + && forbiddenImportsRegexp.matcher(importText).matches() + && (forbiddenImportsExcludesRegexp == null + || !forbiddenImportsExcludesRegexp.matcher(importText).matches()); } /** @@ -207,7 +207,7 @@ private boolean isImportForbidden(String importText) { * import to be warned. */ private void log(DetailAST nodeToWarn, String importText) { - log(nodeToWarn.getLineNo(), MSG_KEY, + log(nodeToWarn, MSG_KEY, getForbiddenImportRegexp(), importText); } @@ -226,12 +226,10 @@ private static String getText(DetailAST packageDefOrImportNode) { if (identNode == null) { final DetailAST parentDotAST = packageDefOrImportNode.findFirstToken(TokenTypes.DOT); - if (parentDotAST != null) { - final FullIdent dottedPathIdent = FullIdent - .createFullIdentBelow(parentDotAST); - final DetailAST nameAST = parentDotAST.getLastChild(); - result = dottedPathIdent.getText() + "." + nameAST.getText(); - } + final FullIdent dottedPathIdent = FullIdent + .createFullIdentBelow(parentDotAST); + final DetailAST nameAST = parentDotAST.getLastChild(); + result = dottedPathIdent.getText() + "." + nameAST.getText(); } else { result = identNode.getText(); diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainMethodCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainMethodCheck.java new file mode 100644 index 0000000000..b45e81586d --- /dev/null +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidCertainMethodCheck.java @@ -0,0 +1,277 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2018 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.github.sevntu.checkstyle.checks.coding; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.github.sevntu.checkstyle.Utils; +import com.puppycrawl.tools.checkstyle.api.AbstractCheck; +import com.puppycrawl.tools.checkstyle.api.CheckstyleException; +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; +import com.puppycrawl.tools.checkstyle.utils.CommonUtils; + +/** + * Check that forbidden method is not used. We can forbid a method by method name and number of + * arguments. + * This can be used to enforce things like: + * + *
+ * Parameters are: + *- exit() method of System class should not be called.
+ *- assertTrue() and assertFalse() methods of Assert class have a 1 arg variant that does not + * provide a helpful message on failure. These methods should not be used. + *
+ *
+ * + *- methodName - Regex to match name of the method to be forbidden. + * When blank or unspecified, all the methods are allowed.
+ *- argumentCount - Number or range to match number of arguments the method takes. + * Multiple numbers/ranges must be comma separated. When unspecified, defaults to "0-". + *
An example configuration: + *
+ * <module name="ForbidCertainMethodCheck"> + * <property name="methodName" value="exit"/> + * </module> + * <module name="ForbidCertainMethodCheck"> + * <property name="methodName" value="assert(True|False)"/> + * <property name="argumentCount" value="1"/> + * </module> + * <module name="ForbidCertainMethodCheck"> + * <property name="methodName" value="assertEquals"/> + * <property name="argumentCount" value="2"/> + * </module> + *+ * Argument count can be bounded range (e.g.: {@code 2-4}) or unbounded range + * (e.g.: {@code -5, 6-}). Unbounded range can be unbounded only on one side. + * Multiple ranges must be comma separated. + * For example, the following will allow only 4 and 8 arguments. + * + *+ * <module name="ForbidCertainMethodCheck"> + * <property name="methodName" value="asList"/> + * <property name="argumentCount" value="-3, 5-7, 9-"/> + * </module> + *+ * + *+ * Note: The check only matches method name. Matching on class/object of the + * method is not done. For e.g. there is no way to forbid only "System.exit()". You can match + * by methodName="exit", but beware that it will violate "System.exit()" and "MySystem.exit()", + * so use it with caution. + *
+ * + * @author Raghav Kumar Gautam + * @since 1.28.0 + */ +public class ForbidCertainMethodCheck extends AbstractCheck { + + /** Key is pointing to the warning message text in "messages.properties" file. */ + public static final String MSG_KEY = "forbid.certain.method"; + /** Regex for splitting string on comma. */ + private static final Pattern COMMA_REGEX = Pattern.compile(","); + + /** Name of the method. */ + private Pattern methodName = CommonUtils.createPattern("^$"); + + /** Range for number of arguments. */ + private String argumentCount = "0-"; + /** Range objects for matching number of arguments. */ + private final ListargumentCountRanges = new ArrayList<>( + Collections.singletonList(new IntRange(0, Integer.MAX_VALUE))); + + /** + * Set method name regex for the forbidden method. + * @param methodName regex for the method name + */ + public void setMethodName(String methodName) { + this.methodName = CommonUtils.createPattern(methodName); + } + + /** + * Set number or range to match number of arguments of the forbidden method. + * Multiple values must be comma separated. + * @param argumentCount range for matching number of arguments + * @throws CheckstyleException when argumentCount is not a valid range + */ + public void setArgumentCount(String argumentCount) throws CheckstyleException { + this.argumentCount = argumentCount; + if (argumentCount.trim().length() > 0) { + final String[] rangeTokens = COMMA_REGEX.split(argumentCount); + argumentCountRanges.clear(); + for (String oneToken : rangeTokens) { + argumentCountRanges.add(IntRange.from(oneToken)); + } + } + else { + throw new CheckstyleException( + "argumentCount must be non-empty, found: " + argumentCount); + } + } + + @Override + public int[] getDefaultTokens() { + return getRequiredTokens(); + } + + @Override + public int[] getAcceptableTokens() { + return getRequiredTokens(); + } + + @Override + public int[] getRequiredTokens() { + return new int[] { + TokenTypes.METHOD_CALL, + }; + } + + @Override + public void visitToken(DetailAST ast) { + switch (ast.getType()) { + case TokenTypes.METHOD_CALL: + final DetailAST dot = ast.getFirstChild(); + // method that looks like: method() + final String methodNameInCode; + if (dot.getType() == TokenTypes.IDENT) { + methodNameInCode = dot.getText(); + } + // method that looks like: obj.method() + else { + methodNameInCode = dot.getLastChild().getText(); + } + final int numArgsInCode = dot.getNextSibling().getChildCount(TokenTypes.EXPR); + if (isForbiddenMethod(methodNameInCode, numArgsInCode)) { + log(ast, MSG_KEY, methodNameInCode, methodName, + numArgsInCode, argumentCount); + } + break; + default: + Utils.reportInvalidToken(ast.getType()); + break; + } + } + + /** + * Check if the method/constructor call against defined rules. + * @param name ruleName of the the method + * @param argCount number of arguments of the method + * @return true if method name and argument matches, false otherwise. + */ + private boolean isForbiddenMethod(String name, int argCount) { + boolean matched = false; + if (methodName.matcher(name).matches()) { + for (IntRange intRange : argumentCountRanges) { + if (intRange.contains(argCount)) { + matched = true; + break; + } + } + } + return matched; + } + + /** + * Represents a range of non-negative integers. + * Range must be bounded on one side or both sides. + * It can't be unbounded on both side. + *
+ * Some examples of valid ranges: + *+ *
+ */ + static class IntRange { + /** Regex for matching range. */ + private static final Pattern RANGE_PATTERN = + Pattern.compile("^\\s*+(\\d*+)\\s*+-\\s*+(\\d*+)\\s*+$"); + /** Lower limit of the range. No lower limit when null. */ + private final int lowerLimit; + /** Upper limit of the range. No upper limit when null. */ + private final int upperLimit; + + /** + * Initialize IntRange object with a lower limit and an upper limit. + * @param lowerLimit lower limit of the range, must be >= 0, null is equivalent to 0 + * @param upperLimit upper limit of the range, null is equivalent to infinity + */ + IntRange(int lowerLimit, int upperLimit) { + this.lowerLimit = lowerLimit; + this.upperLimit = upperLimit; + } + + /** + * Create a range object corresponding to it string representation. + * @param range string representation of the range + * @return IntRange object for the string + * + * @throws CheckstyleException if the specified range is not valid + */ + static IntRange from(String range) throws CheckstyleException { + int lowerLimit = 0; + int upperLimit = Integer.MAX_VALUE; + if (!range.contains("-")) { + lowerLimit = Integer.parseInt(range.trim()); + upperLimit = lowerLimit; + } + else { + final Matcher matcher = RANGE_PATTERN.matcher(range); + if (!matcher.find()) { + throw new CheckstyleException("Specified range is not valid: " + range); + } + final String lowerLimitString = matcher.group(1); + final String upperLimitString = matcher.group(2); + if (lowerLimitString.length() == 0 && upperLimitString.length() == 0) { + throw new CheckstyleException("Specified range is unbounded on both side: " + + range); + } + if (lowerLimitString.length() > 0) { + lowerLimit = Integer.parseInt(lowerLimitString); + } + if (upperLimitString.length() > 0) { + upperLimit = Integer.parseInt(upperLimitString); + } + if (lowerLimit > upperLimit) { + throw new CheckstyleException( + "Lower limit of the range is larger than the upper limit: " + range); + } + } + return new IntRange(lowerLimit, upperLimit); + } + + /** + * Check if range contain given number. Range is closed. + * If lower/upper bound is absent, it is considered unbounded on lower/upper side. + * @param num the number to be checked + * @return true if number is contained in the range, false otherwise + */ + public boolean contains(int num) { + return num >= lowerLimit && num <= upperLimit; + } + } + +} diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidInstantiationCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidInstantiationCheck.java index 228a26b5b3..82eb3766e6 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidInstantiationCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidInstantiationCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -42,6 +42,7 @@ * * @author Daniil * Yaroslavtsev + * @since 1.8.0 */ public class ForbidInstantiationCheck extends AbstractCheck { @@ -99,10 +100,19 @@ public int[] getDefaultTokens() { return new int[] {TokenTypes.IMPORT, TokenTypes.LITERAL_NEW }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST ast) { switch (ast.getType()) { - case TokenTypes.IMPORT: importsList.add(getText(ast)); break; @@ -117,7 +127,6 @@ public void visitToken(DetailAST ast) { final String instanceClassName = getClassName(instanceClass); for (String forbiddenClass : forbiddenClasses) { - if (forbiddenClass.startsWith("java.lang.") && forbiddenClass.endsWith(instanceClassName)) { log(ast, MSG_KEY, instanceClassName); @@ -143,7 +152,6 @@ else if (addedUsingForbiddenImport(instanceClass, Utils.reportInvalidToken(ast.getType()); break; } - } /** @@ -228,7 +236,7 @@ private static String getClassName(final String classNameAndPath) { * - DetailAST node is pointing to import definition or to the "new" * literal node ("IMPORT" or "LITERAL_NEW" node types). * @return Import text without "import" word and semicolons for given - * "IMPORT" node or instanstiated class Name&Path for given + * "IMPORT" node or instantiated class Name&Path for given * "LITERAL_NEW" node. */ private static String getText(final DetailAST ast) { diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidReturnInFinallyBlockCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidReturnInFinallyBlockCheck.java index ef7b1a7a3d..3d3fcdfede 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidReturnInFinallyBlockCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidReturnInFinallyBlockCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,7 +20,6 @@ package com.github.sevntu.checkstyle.checks.coding; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import com.puppycrawl.tools.checkstyle.api.AbstractCheck; @@ -31,14 +30,16 @@ *- 1-10: 1 and 10 and all numbers between 1 and 10
+ *- -10: same as 0-10
+ *- 5-: same as 5-infinity
+ *- 1: same as 1-1
+ ** The finally block is always executed unless there is abnormal program termination, either * resulting from a JVM crash or from a call to System.exit(0). On top of that, any value returned - * from within the finnally block will override the value returned prior to execution of the finally + * from within the finally block will override the value returned prior to execution of the finally * block. This check reports if the finally block contains a return statement. *
* * @author Andrew Uljanenko + * @since 1.13.0 */ public class ForbidReturnInFinallyBlockCheck extends AbstractCheck { + /** * A key is pointing to the warning message text in "messages.properties" * file. @@ -52,6 +53,16 @@ public final int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST finallyNode) { final DetailAST firstSlistNode = finallyNode.findFirstToken(TokenTypes.SLIST); @@ -60,7 +71,7 @@ public void visitToken(DetailAST finallyNode) { for (DetailAST returnNode : listOfReturnNodes) { if (!isReturnInMethodDefinition(returnNode)) { - log(finallyNode.getLineNo(), MSG_KEY); + log(finallyNode, MSG_KEY); } } } @@ -76,7 +87,8 @@ private ListgetReturnNodes(DetailAST node) { DetailAST child = node.getFirstChild(); while (child != null) { if (child.getType() == TokenTypes.LITERAL_RETURN) { - return Collections.singletonList(child); + result.add(child); + break; } result.addAll(getReturnNodes(child)); child = child.getNextSibling(); @@ -101,4 +113,5 @@ private static boolean isReturnInMethodDefinition(DetailAST returnNode) { } return result; } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidThrowAnonymousExceptionsCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidThrowAnonymousExceptionsCheck.java index 743d0f0423..fba33e11d0 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidThrowAnonymousExceptionsCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ForbidThrowAnonymousExceptionsCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,8 @@ /** * - * This Check warns on throwing anonymous exception.
* Examples: *
+ * This Check warns on throwing anonymous exception. + ** catch (Exception e) { @@ -57,8 +58,10 @@ ** + *
* @author Aleksey Nesterenko * @author Max Vetrenko + * @since 1.11.0 */ public class ForbidThrowAnonymousExceptionsCheck extends AbstractCheck { + /** * Warning message key. */ @@ -89,6 +92,16 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST literalThrowOrVariableDefAst) { switch (literalThrowOrVariableDefAst.getType()) { @@ -113,7 +126,7 @@ private void identifyThrowingAnonymousException(DetailAST throwDefAst) { if (throwingLiteralNewAst != null && hasObjectBlock(throwingLiteralNewAst)) { - log(throwDefAst.getLineNo(), MSG_KEY); + log(throwDefAst, MSG_KEY); } else if (throwingLiteralNewAst == null) { final DetailAST throwingExceptionNameAst = getThrowingExceptionNameAst(throwDefAst @@ -121,7 +134,7 @@ else if (throwingLiteralNewAst == null) { if (throwingExceptionNameAst != null && anonymousExceptions.contains(throwingExceptionNameAst .getText())) { - log(throwDefAst.getLineNo(), MSG_KEY); + log(throwDefAst, MSG_KEY); } } } @@ -129,7 +142,7 @@ else if (throwingLiteralNewAst == null) { /** * Analyzes variable definition for anonymous exception definition. if found * - adds it to list of anonymous exceptions - * @param variableDefAst The token to exmaine. + * @param variableDefAst The token to examine. */ private void lookForAnonymousExceptionDefinition(DetailAST variableDefAst) { @@ -157,7 +170,7 @@ && hasObjectBlock(variableLiteralNewAst)) { /** * Gets the literal new node from variable definition node or throw node. - * @param literalThrowOrVariableDefAst The token to exmaine. + * @param literalThrowOrVariableDefAst The token to examine. * @return the specified node. */ private static DetailAST @@ -168,7 +181,7 @@ && hasObjectBlock(variableLiteralNewAst)) { /** * Retrieves the AST node which contains the name of throwing exception. - * @param expressionAst The token to exmaine. + * @param expressionAst The token to examine. * @return the specified node. */ private static DetailAST @@ -178,7 +191,7 @@ && hasObjectBlock(variableLiteralNewAst)) { /** * Checks if definition with a literal new has an ObjBlock. - * @param literalNewAst The token to exmaine. + * @param literalNewAst The token to examine. * @return true if the new has an object block. */ private static boolean hasObjectBlock(DetailAST literalNewAst) { @@ -188,7 +201,7 @@ private static boolean hasObjectBlock(DetailAST literalNewAst) { /** * Checks if variable name is definitely an exception name. It is so if * variable type ends with "Exception" suffix - * @param variableNameAst The token to exmaine. + * @param variableNameAst The token to examine. * @return true if the name is an exception. */ private boolean isExceptionName(DetailAST variableNameAst) { diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/IllegalCatchExtendedCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/IllegalCatchExtendedCheck.java index 173bd94d6c..73642e3c4a 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/IllegalCatchExtendedCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/IllegalCatchExtendedCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,23 +19,35 @@ package com.github.sevntu.checkstyle.checks.coding; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +import com.puppycrawl.tools.checkstyle.api.AbstractCheck; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.FullIdent; import com.puppycrawl.tools.checkstyle.api.TokenTypes; -import com.puppycrawl.tools.checkstyle.checks.coding.AbstractIllegalCheck; import com.puppycrawl.tools.checkstyle.utils.CheckUtils; /** * Catching java.lang.Exception, java.lang.Error or java.lang.RuntimeException * is almost never acceptable. * @author Simon Harris + * @since 1.8.0 */ -public final class IllegalCatchExtendedCheck extends AbstractIllegalCheck { +public final class IllegalCatchExtendedCheck extends AbstractCheck { + /** * Warning message key. */ public static final String MSG_KEY = "illegal.catch"; + /** Illegal class names. */ + private final SetillegalClassNames = Arrays.stream( + new String[] {"Exception", "Error", "RuntimeException", "Throwable", + "java.lang.Error", "java.lang.Exception", "java.lang.RuntimeException", + "java.lang.Throwable", }).collect(Collectors.toSet()); + /** Disable warnings for "catch" blocks containing * throwing an exception. */ private boolean allowThrow = true; @@ -44,18 +56,24 @@ public final class IllegalCatchExtendedCheck extends AbstractIllegalCheck { * rethrowing an exception. */ private boolean allowRethrow = true; - /** Creates new instance of the check. */ - public IllegalCatchExtendedCheck() { - super(new String[] { - "Exception", - "Error", - "RuntimeException", - "Throwable", - "java.lang.Error", - "java.lang.Exception", - "java.lang.RuntimeException", - "java.lang.Throwable", - }); + /** + * Set the list of illegal classes. + * + * @param classNames + * array of illegal exception classes + */ + public void setIllegalClassNames(final String... classNames) { + illegalClassNames.clear(); + for (final String name : classNames) { + illegalClassNames.add(name); + final int lastDot = name.lastIndexOf('.'); + if (lastDot > 0 + && lastDot < name.length() - 1) { + final String shortName = name + .substring(name.lastIndexOf('.') + 1); + illegalClassNames.add(shortName); + } + } } /** @@ -83,6 +101,11 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + @Override public int[] getRequiredTokens() { return getDefaultTokens(); @@ -107,10 +130,7 @@ public void visitToken(DetailAST detailAST) { // For warnings disable first lvl child must be an EXPR and // second lvl child must be IDENT or LITERAL_NEW with // appropriate boolean flags. - final boolean noWarning = throwAST != null - && firstLvlChild != null - && secondLvlChild != null - && firstLvlChild.getType() == TokenTypes.EXPR + final boolean noWarning = secondLvlChild != null && ((allowThrow && secondLvlChild.getType() == TokenTypes.IDENT) || (allowRethrow && secondLvlChild.getType() == TokenTypes.LITERAL_NEW)); @@ -133,7 +153,6 @@ public DetailAST getThrowAST(DetailAST parentAST) { final DetailAST[] asts = getChilds(parentAST); for (DetailAST currentNode : asts) { - if (currentNode.getType() != TokenTypes.PARAMETER_DEF && currentNode.getNumberOfChildren() > 0) { result = getThrowAST(currentNode); @@ -166,4 +185,15 @@ private static DetailAST[] getChilds(DetailAST node) { return result; } + /** + * Checks if given class is illegal. + * + * @param ident + * ident to check. + * @return true if given ident is illegal. + */ + protected boolean isIllegalClassName(final String ident) { + return illegalClassNames.contains(ident); + } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java index 4b150cbe52..d28acecdc3 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -26,30 +26,47 @@ /** * * This check prevents the placement of local variables and fields after calling - * methods in '&&' and '||' conditions. + * methods and instanceof in '&&' and '||' conditions. *
** For example: if(getProperty() && property) ==> if(property && getProperty()), * and similarly for any expression. *
* @author Ilia Dubinin + * @since 1.8.0 */ public class LogicConditionNeedOptimizationCheck extends AbstractCheck { + /** * The key is pointing to the warning message text in "messages.properties" * file. */ public static final String MSG_KEY = "logic.condition.need.optimization"; + /** Integer for the 3rd position. */ + private static final int THIRD_POSITION = 3; + /** Number of operands positions in start/stop array. */ + private static final int OPERAND_SIZE = 4; + @Override public int[] getDefaultTokens() { return new int[] {TokenTypes.LAND, TokenTypes.LOR }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST detailAST) { if (needOptimization(detailAST)) { - log(detailAST.getLineNo(), MSG_KEY, + log(detailAST, MSG_KEY, detailAST.getText(), detailAST.getLineNo(), detailAST.getColumnNo()); } @@ -64,23 +81,108 @@ public void visitToken(DetailAST detailAST) { * @return - boolean variable */ private static boolean needOptimization(DetailAST logicNode) { - final DetailAST secondOperand = getSecondOperand(logicNode); - return !secondOperand.branchContains(TokenTypes.METHOD_CALL) - && logicNode.branchContains(TokenTypes.METHOD_CALL); + final DetailAST[] operands = getOperands(logicNode); + final boolean firstInstanceOf = branchContains(operands, 1, TokenTypes.LITERAL_INSTANCEOF); + final boolean secondTypeCast = branchContains(operands, 2, TokenTypes.TYPECAST); + final boolean result; + + if (firstInstanceOf && secondTypeCast) { + result = false; + } + else { + result = !branchContains(operands, 2, TokenTypes.METHOD_CALL) + && !branchContains(operands, 2, TokenTypes.LITERAL_INSTANCEOF) + && (firstInstanceOf + || branchContains(operands, 1, TokenTypes.METHOD_CALL)); + } + + return result; } /** *- * Return second operand of current logic operator. + * Return operands of current logic operator. *
* @param logicNode - current logic operator - * @return second operand + * @return operands */ - private static DetailAST getSecondOperand(DetailAST logicNode) { - DetailAST child = logicNode.getLastChild(); - if (child.getType() == TokenTypes.RPAREN) { - child = child.getPreviousSibling(); + private static DetailAST[] getOperands(DetailAST logicNode) { + final DetailAST[] results = new DetailAST[OPERAND_SIZE]; + DetailAST node = logicNode.getFirstChild(); + + // start of first + results[0] = node; + + int parenthesis = 0; + + do { + if (node.getType() == TokenTypes.LPAREN) { + parenthesis++; + } + else { + if (node.getType() == TokenTypes.RPAREN) { + parenthesis--; + } + if (parenthesis == 0) { + // end of first + results[1] = node; + } + } + + node = node.getNextSibling(); + } while (parenthesis > 0); + + // start of second + results[2] = node; + results[THIRD_POSITION] = logicNode.getLastChild(); + + return results; + } + + /** + * Checks if the node range contains a token of the provided type. + * @param operands the list operands in order of start and stop + * @param setNumber to retrieve the 1st or 2nd operand + * @param type a TokenType + * @return true if and only if the node range + * contains a token of type {@code type}. + */ + private static boolean branchContains(DetailAST[] operands, int setNumber, int type) { + final boolean result; + + if (setNumber == 1) { + result = branchContains(operands[0], operands[1], type); } - return child; + else { + result = branchContains(operands[2], operands[THIRD_POSITION], type); + } + + return result; } + + /** + * Checks if the node range contains a token of the provided type. + * @param start the token to start checking with (inclusive) + * @param end the token to end with (inclusive) + * @param type a TokenType + * @return true if and only if the node range + * contains a token of type {@code type}. + */ + private static boolean branchContains(DetailAST start, DetailAST end, int type) { + boolean result = false; + DetailAST current = start; + + while (true) { + result = current.branchContains(type); + + if (current == end || result) { + break; + } + + current = current.getNextSibling(); + } + + return result; + } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MapIterationInForEachLoopCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MapIterationInForEachLoopCheck.java index d7d2519a51..6540a6a48d 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MapIterationInForEachLoopCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MapIterationInForEachLoopCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -36,13 +36,14 @@ /** ** This check can help you to write the whole for-each map iteration more - * correctly: + * correctly. *
** 1. If you iterate over a map using map.keySet() or map.entrySet(), but your * code uses only map values, Check will propose you to use map.values() instead * of map.keySet() or map.entrySet(). Replacing map.keySet() or map.entrySet() * with map.values() for such cases can a bit improve an iteration performance. + *
** Bad: *
@@ -71,9 +72,11 @@ * } ** 2. If you iterate over a map using map.entrySet(), but never call * entry.getValue(), Check will propose you to use map.keySet() instead of * map.entrySet(). to iterate over map keys only. + *
** Bad: *
@@ -95,10 +98,12 @@ * } *
* 3. If you iterate over a map with map.keySet() and use both keys and values, * check will propose you to use map.entrySet() to improve an iteration * performance by avoiding search operations inside a map. For this case, * iteration can significantly grow up a performance. + *
** Bad: *
@@ -120,6 +125,7 @@ * } * * @author Max Vetrenko + * @since 1.11.0 */ public class MapIterationInForEachLoopCheck extends AbstractCheck { @@ -273,6 +279,16 @@ public int[] getDefaultTokens() { return new int[] {TokenTypes.LITERAL_FOR, TokenTypes.IMPORT, TokenTypes.VARIABLE_DEF, }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void beginTree(DetailAST ast) { qualifiedImportList.clear(); @@ -282,7 +298,6 @@ public void beginTree(DetailAST ast) { @Override public void visitToken(DetailAST ast) { switch (ast.getType()) { - case TokenTypes.IMPORT: final String qualifiedMapImportText = getMapImportQualifiedName(ast); if (qualifiedMapImportText != null) { @@ -330,14 +345,10 @@ private String validate(DetailAST forLiteralNode) { final DetailAST forEachNode = forLiteralNode.findFirstToken(TokenTypes.FOR_EACH_CLAUSE); final DetailAST keySetOrEntrySetNode = getKeySetOrEntrySetNode(forEachNode); - boolean isMapClassField = false; // Search for keySet or entrySet if (keySetOrEntrySetNode != null) { - if (keySetOrEntrySetNode.getPreviousSibling().getChildCount() != 0) { - isMapClassField = true; - } - final DetailAST variableDefNode = forEachNode.getFirstChild(); - final String keyOrEntryVariableName = variableDefNode.getLastChild().getText(); + final boolean isMapClassField = keySetOrEntrySetNode.getPreviousSibling() + .getChildCount() != 0; final String currentMapVariableName; @@ -351,6 +362,8 @@ private String validate(DetailAST forLiteralNode) { final DetailAST forEachOpeningBrace = forLiteralNode.getLastChild(); if (!isMapPassedIntoAnyMethod(forEachOpeningBrace)) { + final DetailAST variableDefNode = forEachNode.getFirstChild(); + final String keyOrEntryVariableName = variableDefNode.getLastChild().getText(); if (proposeKeySetUsage && KEY_SET_METHOD_NAME.equals( @@ -370,7 +383,7 @@ else if (proposeEntrySetUsage) { /** * Checks if the not is a for each. - * @param forNode The token to exmaine. + * @param forNode The token to examine. * @return true if is for each. */ private static boolean isForEach(DetailAST forNode) { @@ -400,10 +413,22 @@ private DetailAST getKeySetOrEntrySetNode(DetailAST forEachNode) { || ENTRY_SET_METHOD_NAME.equals(identNode.getText())) { final String mapClassName; if (isMapClassField) { - mapClassName = identNode.getPreviousSibling().getLastChild().getText(); + final DetailAST lastChild = identNode.getPreviousSibling().getLastChild(); + if (lastChild == null) { + mapClassName = null; + } + else { + mapClassName = lastChild.getText(); + } } else { - mapClassName = identNode.getPreviousSibling().getText(); + final DetailAST previousSibling = identNode.getPreviousSibling(); + if (previousSibling == null) { + mapClassName = null; + } + else { + mapClassName = previousSibling.getText(); + } } if (mapNamesList.contains(mapClassName)) { keySetOrEntrySetNode = identNode; @@ -422,14 +447,16 @@ private DetailAST getKeySetOrEntrySetNode(DetailAST forEachNode) { * @return true, if any Method Call contains Map Parameter. */ private boolean isMapPassedIntoAnyMethod(DetailAST forEachOpeningBraceNode) { + boolean result = false; final List+ * Checks if a variable is only used inside if statements and asks for it's + * declaration to be moved there too. + *
+ *+ * Rationale: Code inside if/else statements are only executed when those specific block + * conditions evaluate to true. Moving variables inside these blocks prevents the code from being + * executed when the value of the variable is not even being used. It also helps limit the scope + * of the variables from being too broad to confuse new readers. Suppressing variables with false + * violations because of the check's limitations (stated below) also help clearly state the + * purpose of the variable as a temporary storage for a current/future changing value. + *
+ *+ * An example of how to configure the check is: + *
+ *+ * <module name="MoveVariableInsideIfCheck"/> + *+ *
+ * which will produce the following violation: + *
+ *+ * String variable = input.substring(1); // violation - variable is only used inside if block + * + * if (condition) { + * return method(variable); + * } + * + * return ""; + *+ *
+ * The code can be written as the following to avoid a violation: + *
+ *+ * if (condition) { + * String variable = input.substring(1); + * return method(variable); + * } + * + * return ""; + *+ *
+ * No violations will be produced if a variable is used in same scope as declaration, condition of + * block, or if used in multiple blocks. + *
+ *+ * String variable = input.substring(1); + * + * if (condition && variable.charAt(0) == 'T') { + * return method(variable); + * } + * else { + * return method2(variable); + * } + * + * return ""; + *+ *
+ * Limitations: The check can not determine if the value of variable being stored is changed after + * the declaration. Variables like this can't be moved, or may be too complex to move, and thus + * should be suppressed. + *
+ *+ * Case #1: + *
+ *+ * final String variable = list.remove(0); // false positive - list is modified with storing value + * final String next = list.get(0); // expecting above list modification + * + * if (next.equals(input)) { + * list.add(variable); + * } + *+ *
+ * Case #2: + *
+ *+ * final String variable = field.get(0); // false positive - field is modified later, before block + * + * modifyField(); // field is modified inside this method + * + * if (condition) { + * field.add(variable); + * } + *+ * + * @author Richard Veach + * @since 1.24.0 + */ +public class MoveVariableInsideIfCheck extends AbstractCheck { + + /** + * A key is pointing to the warning message text in "messages.properties" + * file. + */ + public static final String MSG_KEY = "move.variable.inside"; + + @Override + public int[] getDefaultTokens() { + return new int[] {TokenTypes.VARIABLE_DEF}; + } + + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + + @Override + public void visitToken(DetailAST ast) { + if (ScopeUtils.isLocalVariableDef(ast)) { + validateLocalVariable(ast); + } + } + + /** + * Examines the local variable for violations to be moved inside an nest if + * statement. + * + * @param ast The local variable to examine. + */ + private void validateLocalVariable(DetailAST ast) { + final Holder holder = new Holder(ast); + + for (DetailAST child = ast.getNextSibling(); (!holder.exit) && (child != null); + child = child.getNextSibling()) { + switch (child.getType()) { + case TokenTypes.LITERAL_IF: + validateIf(holder, child); + break; + default: + validateOther(holder, child); + break; + } + } + + if (holder.blockNode != null) { + log(ast, MSG_KEY, holder.variableName, holder.blockNode.getLineNo()); + } + } + + /** + * Examines an if statement to see how many times the specified variable + * identifier was used inside it. + * + * @param holder The object holder with the specified variable to check and + * it's current state. + * @param ifNodeGiven The current if node to examine. + */ + private static void validateIf(Holder holder, DetailAST ifNodeGiven) { + DetailAST ifNode = ifNodeGiven; + + // -@cs[SingleBreakOrContinue] Too complex to break apart + while (true) { + // check condition + final DetailAST rparen = ifNode.findFirstToken(TokenTypes.RPAREN); + final boolean usedInCondition = holder.hasIdent( + ifNode.findFirstToken(TokenTypes.LPAREN), rparen); + + if (usedInCondition) { + holder.setExit(); + break; + } + + final DetailAST elseNode = ifNode.getLastChild(); + + // check body of if + final DetailAST body = rparen.getNextSibling(); + final DetailAST bodyEnd; + + if (body.getType() == TokenTypes.SLIST) { + bodyEnd = body.getLastChild(); + } + else { + bodyEnd = elseNode; + } + + final boolean used = holder.hasIdent(body, bodyEnd); + + if (used) { + holder.setBlockNode(ifNode); + + if (holder.exit) { + break; + } + } + + if (elseNode.getType() != TokenTypes.LITERAL_ELSE) { + break; + } + + ifNode = elseNode.getFirstChild(); + + if (ifNode.getType() != TokenTypes.LITERAL_IF) { + // check body of else + + validateElseOfIf(holder, ifNode, elseNode); + break; + } + } + } + + /** + * Examines the else of an if statement to see how many times the specified + * variable identifier was used inside it. + * + * @param holder The object holder with the specified variable to check and + * it's current state. + * @param ifNode The if node of the specified else. + * @param elseNode The current else node to examine. + */ + private static void validateElseOfIf(Holder holder, DetailAST ifNode, DetailAST elseNode) { + final boolean used; + + if (ifNode.getType() == TokenTypes.SLIST) { + used = holder.hasIdent(ifNode.getFirstChild(), ifNode.getLastChild()); + } + else { + used = holder.hasIdent(ifNode, elseNode.getLastChild()); + } + + if (used) { + holder.setBlockNode(elseNode); + } + } + + /** + * Examines other nodes to see how many times a variable was used inside it. + * If the variable is used, no violations are reported for it. + * + * @param holder The object holder with the specified variable to check and + * it's current state. + * @param child The current node to examine. + */ + private static void validateOther(Holder holder, DetailAST child) { + final boolean used = holder.hasIdent(child, child.getNextSibling()); + + if (used) { + holder.setExit(); + } + } + + /** + * The holder of information for the specified variable. + * + * @author Richard Veach + */ + private static class Holder { + + /** The name of the variable being examined. */ + private String variableName; + /** Switch to trigger ending examining more nodes. */ + private boolean exit; + /** The node to report violations on. */ + private DetailAST blockNode; + + /** + * Default constructor for the class. + * + * @param ast The variable the holder is for. + */ + Holder(DetailAST ast) { + variableName = ast.findFirstToken(TokenTypes.IDENT).getText(); + } + + /** + * Sets the specified node that is to be reported for the violation for + * the block. If there is already a node being reported, then no nodes + * are reported. + * + * @param blockNode The given block node to report for. + */ + public void setBlockNode(DetailAST blockNode) { + if (this.blockNode != null) { + setExit(); + } + else { + this.blockNode = blockNode; + } + } + + /** Sets the state to exit examining further nodes. */ + public void setExit() { + blockNode = null; + exit = true; + } + + /** + * Checks if any of the nodes between the given start and end are an + * identifier with the name of the variable. + * + * @param start The node to start examining from. + * @param end The last node to stop examining once reached. If null, + * then the last node is when we leave the start node. + * @return true if the identifier has been found, otherwise false. + */ + public boolean hasIdent(DetailAST start, DetailAST end) { + boolean found = false; + DetailAST curNode = start; + + // -@cs[SingleBreakOrContinue] Too complex to break apart + while (curNode != null) { + if ((curNode.getType() == TokenTypes.IDENT) + && (variableName.equals(curNode.getText()))) { + found = true; + break; + } + + if (curNode == end) { + break; + } + + DetailAST toVisit = curNode.getFirstChild(); + + while (toVisit == null) { + toVisit = curNode.getNextSibling(); + + if (toVisit == null) { + if (end == null) { + break; + } + + curNode = curNode.getParent(); + } + } + + curNode = toVisit; + } + + return found; + } + + } + +} diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MultipleStringLiteralsExtendedCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MultipleStringLiteralsExtendedCheck.java index 0fa59db06a..fee8a6cf3a 100755 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MultipleStringLiteralsExtendedCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/MultipleStringLiteralsExtendedCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -36,8 +36,10 @@ * Checks for multiple occurrences of the same string literal within a single file. * * @author Daniel Grenner + * @since 1.5.3 */ public class MultipleStringLiteralsExtendedCheck extends AbstractCheck { + /** * A key is pointing to the warning message text in "messages.properties" * file. @@ -48,7 +50,7 @@ public class MultipleStringLiteralsExtendedCheck extends AbstractCheck { * The found strings and their positions. <String, ArrayList>, with * the ArrayList containing StringInfo objects. */ - private final Map
*
@@ -69,6 +70,7 @@
* matching annotation, it is considered to be a test. This option defaults to
* "Test|org.junit.Test". For example, if this option set to "Test", then class
* "SomeClass" is considered to be a test.
+ *
*
*
*
@@ -95,6 +97,7 @@
* Following configuration will adjust Check to look for classes annotated with
* annotation "RunWith" or classes with methods annotated with "Test" and verify
* that classes names end with "Test" or "Tests".
+ *
*
*
* <module name="NameConventionForJUnit4TestClassesCheck">
@@ -105,8 +108,10 @@
*
*
* @author Zuy Alexey
+ * @since 1.13.0
*/
public class NameConventionForJunit4TestClassesCheck extends AbstractCheck {
+
/**
* Violation message key.
*/
@@ -195,6 +200,16 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST classDefNode) {
if ((isClassDefinitionAnnotated(classDefNode) || isAtleastOneMethodAnnotated(classDefNode))
@@ -222,19 +237,21 @@ private boolean isClassDefinitionAnnotated(DetailAST classDefNode) {
* defined annotation
*/
private boolean isAtleastOneMethodAnnotated(DetailAST classDefNode) {
+ boolean result = false;
DetailAST classMemberNode =
classDefNode.findFirstToken(TokenTypes.OBJBLOCK).getFirstChild();
while (classMemberNode != null) {
if (classMemberNode.getType() == TokenTypes.METHOD_DEF
&& hasAnnotation(classMemberNode, methodAnnotationNameRegex)) {
- return true;
+ result = true;
+ break;
}
classMemberNode = classMemberNode.getNextSibling();
}
- return false;
+ return result;
}
/**
@@ -331,11 +348,14 @@ private static String getIdentifierName(DetailAST identifierNode) {
* against regex.
*/
private static boolean isMatchesRegex(Pattern regexPattern, String str) {
+ final boolean result;
if (regexPattern != null) {
- return regexPattern.matcher(str).matches();
+ result = regexPattern.matcher(str).matches();
}
else {
- return false;
+ result = false;
}
+ return result;
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NoNullForCollectionReturnCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NoNullForCollectionReturnCheck.java
index 88c21af32f..3c21887950 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NoNullForCollectionReturnCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NoNullForCollectionReturnCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -49,17 +49,17 @@
* TreeSet, Vector, Collection, List, Map, Set.
*
* @author Ilja Dubinin
+ * @since 1.9.0
*/
public class NoNullForCollectionReturnCheck extends AbstractCheck {
+
/**
* Warning message key.
*/
public static final String MSG_KEY = "no.null.for.collections";
/**
- *
* Default list of collection implementing classes.
- *
*/
private static final String DEFAULT_COLLECTIONS = "AbstractCollection AbstractList "
+ "AbstractQueue AbstractSequentialList AbstractSet ArrayBlockingQueue ArrayDeque "
@@ -70,9 +70,7 @@ public class NoNullForCollectionReturnCheck extends AbstractCheck {
+ "LinkedList LinkedTransferQueue PriorityBlockingQueue PriorityQueue RoleList "
+ "RoleUnresolvedList Stack SynchronousQueue TreeSet Vector Collection List Map Set";
/**
- *
* List of collection, that will be check.
- *
*/
private Set collectionList = new HashSet<>();
@@ -128,6 +126,16 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void beginTree(DetailAST rootAST) {
methodDefs.clear();
@@ -149,7 +157,7 @@ public void visitToken(DetailAST detailAST) {
&& (hasNullLiteralInReturn(detailAST)
|| (searchThroughMethodBody
&& isReturnedValueBeNull(detailAST)))) {
- log(detailAST.getLineNo(), MSG_KEY);
+ log(detailAST, MSG_KEY);
}
}
break;
@@ -269,7 +277,7 @@ private static LinkedList getAllSubblocks(DetailAST blockDef) {
subblocks.addAll(getChildren(blockBody, TokenTypes.LITERAL_TRY));
final List nestedSubblocks = new LinkedList<>();
for (DetailAST currentSubblock : subblocks) {
- if (currentSubblock.branchContains(TokenTypes.SLIST)) {
+ if (currentSubblock.findFirstToken(TokenTypes.SLIST) != null) {
nestedSubblocks.addAll(getAllSubblocks(currentSubblock));
}
}
@@ -352,7 +360,7 @@ private static List getChildren(DetailAST root, int type) {
*/
private static DetailAST getMethodDef(DetailAST returnLit) {
DetailAST methodDef = returnLit;
- while (methodDef.getType() != TokenTypes.METHOD_DEF) {
+ while (methodDef != null && methodDef.getType() != TokenTypes.METHOD_DEF) {
methodDef = methodDef.getParent();
}
return methodDef;
@@ -373,4 +381,5 @@ private static DetailAST getBlockBody(DetailAST blockDef) {
}
return blockBody;
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java
index 5023a8d08c..a3821a152e 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -138,6 +138,7 @@
* int passingBinary = 0b0000_1111;
*
* @author Cheng-Yu Pai
+ * @since 1.18.0
*/
public class NumericLiteralNeedsUnderscoreCheck extends AbstractCheck {
@@ -151,6 +152,7 @@ public class NumericLiteralNeedsUnderscoreCheck extends AbstractCheck {
* Type of numeric literal.
*/
protected enum NumericType {
+
/**
* Denotes a decimal literal. For example, 1.2f
*/
@@ -165,6 +167,7 @@ protected enum NumericType {
* Denotes a binary literal. For example, 0b0011
*/
BINARY,
+
}
/**
@@ -337,10 +340,20 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(final DetailAST ast) {
if (!passesCheck(ast)) {
- log(ast.getLineNo(), MSG_KEY);
+ log(ast, MSG_KEY);
}
}
@@ -356,8 +369,10 @@ private static boolean isField(final DetailAST ast) {
current = current.getParent();
}
return current.getType() == TokenTypes.VARIABLE_DEF
- && current.branchContains(TokenTypes.LITERAL_STATIC)
- && current.branchContains(TokenTypes.FINAL);
+ && current.findFirstToken(TokenTypes.MODIFIERS)
+ .findFirstToken(TokenTypes.LITERAL_STATIC) != null
+ && current.findFirstToken(TokenTypes.MODIFIERS)
+ .findFirstToken(TokenTypes.FINAL) != null;
}
/**
@@ -542,23 +557,23 @@ else if ("0b".equals(prefix)) {
*/
private static boolean numericSegmentPassesRequirement(String numericSegment,
int minLength, int symbolsUntilUnderscore) {
- if (numericSegment.length() < minLength) {
- return true;
- }
- final char underscore = '_';
- int symbolCount = 0;
boolean passes = true;
- for (int i = 0; i < numericSegment.length(); i++) {
- final char current = numericSegment.charAt(i);
- if (symbolCount >= symbolsUntilUnderscore && current != underscore) {
- passes = false;
- break;
- }
- if (current == underscore) {
- symbolCount = 0;
- }
- else {
- symbolCount++;
+ if (numericSegment.length() >= minLength) {
+ final char underscore = '_';
+ int symbolCount = 0;
+
+ for (int i = 0; i < numericSegment.length(); i++) {
+ final char current = numericSegment.charAt(i);
+ if (symbolCount >= symbolsUntilUnderscore && current != underscore) {
+ passes = false;
+ break;
+ }
+ if (current == underscore) {
+ symbolCount = 0;
+ }
+ else {
+ symbolCount++;
+ }
}
}
return passes;
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/OverridableMethodInConstructorCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/OverridableMethodInConstructorCheck.java
index 73daf0883c..426f3b1b52 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/OverridableMethodInConstructorCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/OverridableMethodInConstructorCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -29,8 +29,10 @@
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
/**
+ * Detects overridable methods in constructors.
*
* This check prevents any calls to overridable methods that are take place in:
+ *
* -
* Any constructor body (verification is always done by default and not
* configurable).
@@ -81,6 +83,7 @@
*
* Notes:
This check doesn`t handle the situation when there
* is a call to an overloaded method(s).
Here`s an example:
+ *
*
* public class Test {
*
@@ -124,6 +127,7 @@
* @author Daniil
* Yaroslavtsev
* @author Ilja Dubinin
+ * @since 1.8.0
*/
public class OverridableMethodInConstructorCheck extends AbstractCheck {
@@ -176,7 +180,7 @@ public class OverridableMethodInConstructorCheck extends AbstractCheck {
private DetailAST curMethodDef;
/**
- * A current root of the synthax tree is being processed.
+ * A current root of the syntax tree is being processed.
* */
private DetailAST treeRootAST;
@@ -252,6 +256,16 @@ public int[] getDefaultTokens() {
return new int[] {TokenTypes.CTOR_DEF, TokenTypes.METHOD_DEF};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void beginTree(DetailAST rootAST) {
treeRootAST = rootAST;
@@ -259,13 +273,10 @@ public void beginTree(DetailAST rootAST) {
@Override
public void visitToken(final DetailAST detailAST) {
-
final DetailAST classDef = getClassDef(detailAST);
if (classDef != null && !hasModifier(classDef, TokenTypes.FINAL)) {
-
switch (detailAST.getType()) {
-
case TokenTypes.CTOR_DEF:
logWarnings(detailAST, KEY_CTOR);
break;
@@ -306,7 +317,6 @@ && realizesAnInterface(classDef, Serializable.class.getSimpleName())) {
* "messages.properties" file.
*/
private void logWarnings(final DetailAST detailAST, final String key) {
-
final List methodCallsToWarnList =
getOverridables(detailAST);
@@ -337,7 +347,6 @@ private void logWarnings(final DetailAST detailAST, final String key) {
* constructor body.
*/
private List getOverridables(final DetailAST parentAST) {
-
final List result =
new LinkedList<>();
final List methodCallsList = getMethodCallsList(parentAST);
@@ -366,7 +375,6 @@ && isOverridableMethodCall(curNode)) {
* overridable method call and false otherwise.
*/
private boolean isOverridableMethodCall(final DetailAST methodCallAST) {
-
boolean result = false;
visitedMethodCalls.add(methodCallAST);
@@ -408,7 +416,6 @@ && isOverridableMethodCall(curNode)) {
* current parent node.
*/
private List getMethodCallsList(final DetailAST parentAST) {
-
final List result = new LinkedList<>();
for (DetailAST curNode : getChildren(parentAST)) {
@@ -432,7 +439,6 @@ private List getMethodCallsList(final DetailAST parentAST) {
* @return The method name is related to the current METHOD_CALL DetailAST.
*/
private String getMethodName(final DetailAST methodCallAST) {
-
String result = null;
final DetailAST ident = methodCallAST.findFirstToken(TokenTypes.IDENT);
@@ -444,7 +450,6 @@ private String getMethodName(final DetailAST methodCallAST) {
final DetailAST childAST = methodCallAST.getFirstChild();
if (childAST != null && childAST.getType() == TokenTypes.DOT) {
-
final DetailAST firstChild = childAST.getFirstChild();
final DetailAST lastChild = childAST.getLastChild();
@@ -478,7 +483,6 @@ else if (firstChild.getType() == TokenTypes.IDENT
* node.
*/
private DetailAST getMethodDef(final DetailAST methodCallAST) {
-
DetailAST result = null;
curMethodDef = null;
@@ -486,20 +490,18 @@ private DetailAST getMethodDef(final DetailAST methodCallAST) {
final String methodName = getMethodName(methodCallAST);
if (methodName != null) {
-
final DetailAST curClassAST = getClassDef(methodCallAST);
final DetailAST callsChild = methodCallAST.getFirstChild();
- final String variableTypeName;
+ final String variableTypeName = getVariableType(methodCallAST);
- if (callsChild.getType() != TokenTypes.DOT
- || (variableTypeName = getVariableType(methodCallAST)) == null
+ if (variableTypeName == null
+ || callsChild.getType() != TokenTypes.DOT
|| isItTypeOfCurrentClass(variableTypeName, curClassAST)
|| isItCallMethodViaKeywordThis(variableTypeName, curClassAST)) {
getMethodDef(curClassAST, methodName);
}
if (curMethodDefCount == 0) {
-
final List baseClasses = getBaseClasses(curClassAST);
for (DetailAST curBaseClass : baseClasses) {
@@ -555,7 +557,6 @@ private List getMethodDef(final DetailAST parentAST,
List definitionsList = new LinkedList<>();
for (DetailAST curNode : getChildren(parentAST)) {
-
if (curNode.getNumberOfChildren() > 0) {
if (curNode.getType() == TokenTypes.METHOD_DEF) {
final String curMethodName = curNode.findFirstToken(
@@ -603,7 +604,6 @@ else if (dotChild.getType() == TokenTypes.DOT) {
typeName = dotChild.getFirstChild().getText()
+ PATH_SEPARATOR + dotChild.getLastChild().getText();
}
-
}
return typeName;
}
@@ -651,14 +651,13 @@ else if (dotChild.getType() == TokenTypes.DOT) {
}
/**
- * Gets the count of parameters for current method definitioin or
+ * Gets the count of parameters for current method definition or
* method call.
* @param methodDefOrCallAST METHOD_DEF or METHOD_CALL
* DetailAST node
* @return the count of parameters for current method.
*/
private static int getMethodParamsCount(DetailAST methodDefOrCallAST) {
-
int result = 0;
DetailAST paramsParentAST = null;
@@ -696,7 +695,6 @@ else if (methodDefOrCallAST.getType() == TokenTypes.METHOD_DEF) {
*/
private static boolean hasModifier(final DetailAST methodOrClassDefAST,
int modifierType) {
-
boolean result = false;
final DetailAST modifiers = methodOrClassDefAST
.findFirstToken(TokenTypes.MODIFIERS);
@@ -722,7 +720,6 @@ private static boolean hasModifier(final DetailAST methodOrClassDefAST,
* node named aMethodNode.
* */
private static DetailAST getClassDef(final DetailAST methodNode) {
-
DetailAST curNode = methodNode;
while (curNode != null && curNode.getType() != TokenTypes.CLASS_DEF) {
@@ -736,14 +733,13 @@ private static DetailAST getClassDef(final DetailAST methodNode) {
* Gets the CLASS_DEF DetailAST node for the class is named "aClassName".
*
* @param rootNode
- * A root node of synthax tree is being processed.
+ * A root node of syntax tree is being processed.
* @param className
* The name of class to search.
* @return The CLASS_DEF DetailAST node which is related to the class is
* named "aClassName".
*/
private static DetailAST getClassDef(DetailAST rootNode, String className) {
-
DetailAST curNode = rootNode;
while (curNode != null) {
@@ -781,7 +777,6 @@ private static DetailAST getClassDef(DetailAST rootNode, String className) {
*/
private boolean realizesAnInterface(final DetailAST classDefNode,
final String interfaceName) {
-
boolean result = false;
final List classWithBaseClasses =
getBaseClasses(classDefNode);
@@ -810,7 +805,6 @@ private boolean realizesAnInterface(final DetailAST classDefNode,
*/
private static boolean implementsAnInterface(final DetailAST classDefAST,
final String interfaceName) {
-
boolean result = false;
final DetailAST implClause = classDefAST
.findFirstToken(TokenTypes.IMPLEMENTS_CLAUSE);
@@ -837,7 +831,6 @@ private static boolean implementsAnInterface(final DetailAST classDefAST,
* processed and all it`s base classes.
*/
private List getBaseClasses(final DetailAST classDefNode) {
-
final List result = new LinkedList<>();
String baseClassName = getBaseClassName(classDefNode);
@@ -847,7 +840,15 @@ private List getBaseClasses(final DetailAST classDefNode) {
result.add(curClass);
baseClassName = getBaseClassName(curClass);
if (baseClassName != null) {
- curClass = getClassDef(treeRootAST, baseClassName);
+ final DetailAST nextClass = getClassDef(treeRootAST, baseClassName);
+
+ // prevent infinite loop with similar named classes
+ if (nextClass == curClass) {
+ curClass = null;
+ }
+ else {
+ curClass = nextClass;
+ }
}
else {
break;
@@ -865,7 +866,6 @@ private List getBaseClasses(final DetailAST classDefNode) {
* @return The name of a base class for current class.
*/
private static String getBaseClassName(final DetailAST classDefNode) {
-
String result = null;
final DetailAST extendsClause = classDefNode
.findFirstToken(TokenTypes.EXTENDS_CLAUSE);
@@ -903,11 +903,12 @@ private static List getChildren(final DetailAST node) {
}
/**
- * Class that incapsulates the DetailAST node related to the method call
+ * Class that encapsulates the DetailAST node related to the method call
* that leads to call of the overridable method and the name of
* overridable method.
*/
private final class OverridableMetCall {
+
/**
* DetailAST node is related to the method call that leads to
* call of the overridable method.
@@ -931,6 +932,7 @@ private OverridableMetCall(DetailAST methodCallAST,
this.metCallAST = methodCallAST;
this.overridableMetName = overridableMetName;
}
+
}
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RedundantReturnCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RedundantReturnCheck.java
index 8d53df0422..70ed96d9d4 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RedundantReturnCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RedundantReturnCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -76,6 +76,7 @@
* @author Troshin Sergey
* @author Max Vetrenko
* @author Alexey Nesterenko
+ * @since 1.8.0
*/
public class RedundantReturnCheck extends AbstractCheck {
@@ -107,8 +108,17 @@ public int[] getDefaultTokens() {
}
@Override
- public void visitToken(DetailAST ast) {
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+ @Override
+ public void visitToken(DetailAST ast) {
final DetailAST blockAst = ast.getLastChild();
switch (ast.getType()) {
@@ -139,8 +149,8 @@ public void visitToken(DetailAST ast) {
* @return true if the block can be ignored.
*/
private boolean ignoreLonelyReturn(DetailAST objectBlockAst) {
-
return allowReturnInEmptyMethodsAndConstructors
+ && objectBlockAst.getFirstChild() != null
&& objectBlockAst.getFirstChild().getType()
== TokenTypes.LITERAL_RETURN;
}
@@ -160,7 +170,6 @@ private static boolean hasNonEmptyBody(DetailAST defAst) {
* @return true if void method has non-empty body.
*/
private static boolean isVoidMethodWithNonEmptyBody(DetailAST methodDefAst) {
-
return methodDefAst.getLastChild().getType() == TokenTypes.SLIST
&& methodDefAst.findFirstToken(TokenTypes.TYPE)
.findFirstToken(TokenTypes.LITERAL_VOID) != null
@@ -174,7 +183,7 @@ private static boolean isVoidMethodWithNonEmptyBody(DetailAST methodDefAst) {
*/
private void log(List redundantReturnsAst) {
for (DetailAST redundantLiteralReturnAst : redundantReturnsAst) {
- log(redundantLiteralReturnAst.getLineNo(), MSG_KEY);
+ log(redundantLiteralReturnAst, MSG_KEY);
}
}
@@ -186,25 +195,21 @@ private void log(List redundantReturnsAst) {
* @return list of redundant returns or empty list if none were found
*/
private static List getRedundantReturns(DetailAST objectBlockAst) {
-
final List redundantReturns = new ArrayList<>();
final int placeForRedundantReturn = objectBlockAst
.getLastChild().getPreviousSibling().getType();
if (placeForRedundantReturn == TokenTypes.LITERAL_RETURN) {
-
final DetailAST lastChildAst = objectBlockAst.getLastChild();
final DetailAST redundantReturnAst = lastChildAst.getPreviousSibling();
redundantReturns.add(redundantReturnAst);
-
}
else if (placeForRedundantReturn == TokenTypes.LITERAL_TRY
&& !getRedundantReturnsInTryCatchBlock(objectBlockAst
.findFirstToken(TokenTypes.LITERAL_TRY)).isEmpty()) {
-
final List redundantsAst = getRedundantReturnsInTryCatchBlock(objectBlockAst
.findFirstToken(TokenTypes.LITERAL_TRY));
@@ -221,7 +226,6 @@ else if (placeForRedundantReturn == TokenTypes.LITERAL_TRY
* @return list of redundant returns or empty list if none were found
*/
private static List getRedundantReturnsInTryCatchBlock(DetailAST tryAst) {
-
final List redundantReturns = new ArrayList<>();
DetailAST tryBlockAst = null;
@@ -262,7 +266,6 @@ private static List getRedundantReturnsInTryCatchBlock(DetailAST tryA
// if redundant return is in finally block
if (blockAst.getNextSibling() != null) {
-
final DetailAST afterCatchBlockAst = blockAst.getNextSibling().getLastChild()
.getLastChild();
@@ -285,7 +288,6 @@ private static DetailAST getNextCatchBlock(DetailAST blockAst) {
DetailAST catchBlockAst = null;
if (blockAst.getNextSibling() != null
&& blockAst.getNextSibling().getType() == TokenTypes.LITERAL_CATCH) {
-
catchBlockAst = blockAst.getNextSibling();
}
return catchBlockAst;
@@ -298,11 +300,9 @@ private static DetailAST getNextCatchBlock(DetailAST blockAst) {
* @return redundant literal return if found, else null.
*/
private static DetailAST getRedundantReturnInBlock(DetailAST statementAst) {
-
DetailAST redundantReturnAst = null;
if (statementAst != null) {
-
if (statementAst.getType() == TokenTypes.LITERAL_RETURN) {
redundantReturnAst = statementAst;
}
@@ -328,24 +328,21 @@ private static DetailAST getRedundantReturnInBlock(DetailAST statementAst) {
private static DetailAST findRedundantReturnInCatch(DetailAST lastStatementInCatchBlockAst) {
DetailAST redundantReturnAst = null;
DetailAST currentNodeAst = lastStatementInCatchBlockAst;
- DetailAST toVisitAst = currentNodeAst;
DetailAST returnAst = null;
- while (toVisitAst != null) {
-
- toVisitAst = Utils.getNextSubTreeNode(toVisitAst, currentNodeAst);
-
- if (toVisitAst != null
- && (toVisitAst.getParent().getParent().getNextSibling() == null
- || toVisitAst.getParent().getParent().getNextSibling().getType()
- == TokenTypes.RCURLY)
- && toVisitAst.getType() == TokenTypes.LITERAL_RETURN
- && toVisitAst.getParent().getNextSibling() == null) {
+ DetailAST toVisitAst = Utils.getNextSubTreeNode(currentNodeAst, currentNodeAst);
+ while (toVisitAst != null) {
+ if (toVisitAst.getType() == TokenTypes.OBJBLOCK) {
+ while (toVisitAst.getNextSibling() == null) {
+ toVisitAst = toVisitAst.getParent();
+ }
+ toVisitAst = toVisitAst.getNextSibling();
+ }
+ else if (isFinalReturn(toVisitAst)) {
returnAst = toVisitAst;
while (toVisitAst != null
&& toVisitAst.getParent() != currentNodeAst.getLastChild()) {
-
toVisitAst = toVisitAst.getParent();
}
@@ -355,9 +352,25 @@ private static DetailAST findRedundantReturnInCatch(DetailAST lastStatementInCat
toVisitAst = returnAst;
}
+
+ toVisitAst = Utils.getNextSubTreeNode(toVisitAst, currentNodeAst);
}
currentNodeAst = Utils.getNextSubTreeNode(currentNodeAst, lastStatementInCatchBlockAst);
return redundantReturnAst;
}
+
+ /**
+ * Checks if the {@code ast} is the final return statement.
+ * @param ast the AST to examine.
+ * @return {@code true} if the {@code ast} is the final return statement.
+ */
+ private static boolean isFinalReturn(DetailAST ast) {
+ return (ast.getParent().getParent().getNextSibling() == null
+ || ast.getParent().getParent().getNextSibling().getType()
+ == TokenTypes.RCURLY)
+ && ast.getType() == TokenTypes.LITERAL_RETURN
+ && ast.getParent().getNextSibling() == null;
+ }
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RequireFailForTryCatchInJunitCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RequireFailForTryCatchInJunitCheck.java
new file mode 100644
index 0000000000..374fb60b9e
--- /dev/null
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/RequireFailForTryCatchInJunitCheck.java
@@ -0,0 +1,249 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2018 the original author or authors.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.github.sevntu.checkstyle.checks.coding;
+
+import com.github.sevntu.checkstyle.Utils;
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.FullIdent;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.AnnotationUtility;
+
+/**
+ *
+ * Checks if a try/catch block has a junit fail assertion inside the try for a junit method.
+ *
+ *
+ * Rationale: Tests should not complete the try block naturally if they are expecting a failure.
+ * If the try completes normally the test will pass successfully and skip over any assertions in
+ * the catch block.
+ * If tests are not expecting exceptions, then they should remove the catch block and propagate
+ * the exception to the junit caller which will display the full exception to the user.
+ *
+ *
+ * A junit test method is identified by the annotations placed on it. It is only considered a junit
+ * method if it contains the annotation 'org.junit.Test'. This check doesn't examine methods called
+ * by a test method. It must contain the annotation. Failures are identified by the
+ * method call to the method 'org.junit.Assert.fail'.
+ *
+ *
+ * An example of how to configure the check is:
+ *
+ *
+ * <module name="RequireFailForTryCatchInJunitCheck"/>
+ *
+ *
+ * which will cause a violation in the example below:
+ *
+ *
+ * @Test
+ * public void testMyCase() {
+ * try { // violation here as try block has no 'Assert.fail()'.
+ * verifySomeResult();
+ * }
+ * catch (IllegalArgumentException ex) {
+ * assertEquals("expected exception message",
+ * "Some message that is expected", ex.getMessage());
+ * }
+ * }
+ *
+ * @author Richard Veach
+ * @since 1.25.0
+ */
+public class RequireFailForTryCatchInJunitCheck extends AbstractCheck {
+
+ /**
+ * Violation message key.
+ */
+ public static final String MSG_KEY = "require.fail";
+
+ /**
+ * Fully qualified junit test annotation.
+ */
+ private static final String FQ_JUNIT_TEST = "org.junit.Test";
+ /**
+ * JUnit's fail assertion method name.
+ */
+ private static final String FAIL = "fail";
+
+ /**
+ * {@code true} if the junit test is imported.
+ */
+ private boolean importTest;
+ /**
+ * {@code true} if the junit assert is imported.
+ */
+ private boolean importAssert;
+ /**
+ * {@code true} if the junit fail assertion method is statically imported.
+ */
+ private boolean importStaticFail;
+
+ @Override
+ public int[] getDefaultTokens() {
+ return getRequiredTokens();
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return getRequiredTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return new int[] {
+ TokenTypes.IMPORT,
+ TokenTypes.STATIC_IMPORT,
+ TokenTypes.LITERAL_TRY,
+ };
+ }
+
+ @Override
+ public void beginTree(DetailAST rootAST) {
+ importTest = false;
+ importAssert = false;
+ importStaticFail = false;
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ switch (ast.getType()) {
+ case TokenTypes.IMPORT:
+ final String imprt = getImportText(ast);
+
+ if (FQ_JUNIT_TEST.equals(imprt)) {
+ importTest = true;
+ }
+ if ("org.junit.Assert".equals(imprt)) {
+ importAssert = true;
+ }
+ break;
+ case TokenTypes.STATIC_IMPORT:
+ final String staticImprt = getImportText(ast);
+
+ if ("org.junit.Assert.fail".equals(staticImprt)) {
+ importStaticFail = true;
+ }
+ break;
+ case TokenTypes.LITERAL_TRY:
+ examineTry(ast);
+ break;
+ default:
+ Utils.reportInvalidToken(ast.getType());
+ break;
+ }
+ }
+
+ /**
+ * Examines the try block for violations.
+ * @param ast The try block to examine.
+ */
+ private void examineTry(DetailAST ast) {
+ final DetailAST method = getMethod(ast);
+
+ if (isTestMethod(method)
+ && ast.findFirstToken(TokenTypes.LITERAL_CATCH) != null) {
+ final DetailAST last = ast.findFirstToken(TokenTypes.SLIST).getLastChild()
+ .getPreviousSibling();
+
+ if (last == null
+ || last.getType() != TokenTypes.SEMI
+ || !isValidFail(last.getPreviousSibling())) {
+ log(ast, MSG_KEY);
+ }
+ }
+ }
+
+ /**
+ * Checks if the given method is a test method, defined by the junit annotation Test.
+ * @param method the method AST to examine.
+ * @return {@code true} if the method is a test method.
+ */
+ private boolean isTestMethod(DetailAST method) {
+ return method != null
+ && ((importTest && AnnotationUtility.containsAnnotation(method, "Test"))
+ || AnnotationUtility.containsAnnotation(method, FQ_JUNIT_TEST));
+ }
+
+ /**
+ * Checks if the expression is an junit fail assertion.
+ * @param expression The expression to examine.
+ * @return {@code true} if the expression is a valid junit fail assertion.
+ */
+ private boolean isValidFail(DetailAST expression) {
+ boolean result = false;
+
+ if (expression.getFirstChild().getType() == TokenTypes.METHOD_CALL) {
+ final DetailAST ident = expression.getFirstChild().getFirstChild();
+
+ if (importAssert && ident.getType() == TokenTypes.DOT) {
+ final DetailAST firstChild = ident.getFirstChild();
+
+ result = "Assert".equals(firstChild.getText())
+ && FAIL.equals(firstChild.getNextSibling().getText());
+ }
+ else if (importStaticFail) {
+ result = FAIL.equals(ident.getText());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Retrieves the method definition AST parent from the specified node, as long as it doesn't
+ * contain a lambda.
+ * @param node The node to examine.
+ * @return The parent method definition.
+ */
+ private static DetailAST getMethod(DetailAST node) {
+ DetailAST result = null;
+
+ for (DetailAST token = node.getParent(); token != null; token = token.getParent()) {
+ final int type = token.getType();
+ if (type == TokenTypes.METHOD_DEF) {
+ result = token;
+ }
+ if (type == TokenTypes.METHOD_DEF || type == TokenTypes.LAMBDA) {
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns import text.
+ *
+ * @param ast ast node that represents import
+ * @return String that represents importing class
+ */
+ private static String getImportText(DetailAST ast) {
+ final FullIdent imp;
+ if (ast.getType() == TokenTypes.IMPORT) {
+ imp = FullIdent.createFullIdentBelow(ast);
+ }
+ else {
+ imp = FullIdent.createFullIdent(ast.getFirstChild().getNextSibling());
+ }
+ return imp.getText();
+ }
+
+}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnBooleanFromTernaryCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnBooleanFromTernaryCheck.java
index 7482b0038c..cebaaf547d 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnBooleanFromTernaryCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnBooleanFromTernaryCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,7 @@
*
*
* @author Ivan Sopov
+ * @since 1.8.0
*/
public class ReturnBooleanFromTernaryCheck extends AbstractCheck {
@@ -51,6 +52,16 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST ast) {
final DetailAST secondBranch = ast.getLastChild();
@@ -62,4 +73,5 @@ public void visitToken(DetailAST ast) {
log(ast, MSG_KEY);
}
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnCountExtendedCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnCountExtendedCheck.java
index 20cecc460b..6b9e0fc8b2 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnCountExtendedCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnCountExtendedCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,8 +21,6 @@
import java.util.Collection;
import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Set;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
@@ -49,7 +47,12 @@
* - Methods by name ("ignoreMethodsNames" property). Note, that the "ignoreMethodsNames"
* property type is a RegExp:
* using this property you can list the names of ignored methods separated by comma (but you
- * can also use '|' to separate different method names in usual for RegExp style).
+ * can also use '|' to separate different method names in usual for RegExp style).
+ * If the violation is on a lambda, since it has no method name, you can specify the string
+ * {@code null} to ignore all lambda violations for now. It should be noted, that ignoring lambdas
+ * this way may not always be supported as it is a hack and giving all lambdas the same name. It
+ * could be changed if a better way to single out individual lambdas if found.
+ *
* - Methods which linelength less than given value ("linesLimit" property).
*
- "return" statements which depth is greater or equal to the given value ("returnDepthLimit"
* property). There are few supported
@@ -63,6 +66,7 @@
*
*
* @author Daniil Yaroslavtsev
+ * @since 1.8.0
*/
public class ReturnCountExtendedCheck extends AbstractCheck {
@@ -81,12 +85,19 @@ public class ReturnCountExtendedCheck extends AbstractCheck {
"return.count.extended.ctor";
/**
- * Default maximum allowed "return" literals count per method/ctor.
+ * A key is pointing to the warning message text in "messages.properties"
+ * file.
+ */
+ public static final String MSG_KEY_LAMBDA =
+ "return.count.extended.lambda";
+
+ /**
+ * Default maximum allowed "return" literals count per method/ctor/lambda.
*/
private static final int DEFAULT_MAX_RETURN_COUNT = 1;
/**
- * Default number of lines of which method/ctor body may consist to be
+ * Default number of lines of which method/ctor/lambda body may consist to be
* skipped by check.
*/
private static final int DEFAULT_IGNORE_METHOD_LINES_COUNT = 20;
@@ -99,7 +110,7 @@ public class ReturnCountExtendedCheck extends AbstractCheck {
/**
* Number which defines, how many lines of code on the top of current
- * processed method/ctor will be ignored by check.
+ * processed method/ctor/lambda will be ignored by check.
*/
private static final int DEFAULT_TOP_LINES_TO_IGNORE_COUNT = 5;
@@ -109,12 +120,12 @@ public class ReturnCountExtendedCheck extends AbstractCheck {
private Set ignoreMethodsNames = new HashSet<>();
/**
- * Maximum allowed "return" literals count per method/ctor (1 by default).
+ * Maximum allowed "return" literals count per method/ctor/lambda (1 by default).
*/
private int maxReturnCount = DEFAULT_MAX_RETURN_COUNT;
/**
- * Maximum number of lines of which method/ctor body may consist to be
+ * Maximum number of lines of which method/ctor/lambda body may consist to be
* skipped by check. 20 by default.
*/
private int ignoreMethodLinesCount = DEFAULT_IGNORE_METHOD_LINES_COUNT;
@@ -125,14 +136,14 @@ public class ReturnCountExtendedCheck extends AbstractCheck {
private int minIgnoreReturnDepth = DEFAULT_MIN_IGNORE_RETURN_DEPTH;
/**
- * Option to ignore "empty" return statements in void methods and ctors.
+ * Option to ignore "empty" return statements in void methods and ctors and lambdas.
* "true" by default.
*/
private boolean ignoreEmptyReturns = true;
/**
* Number which defines, how many lines of code on the top of each
- * processed method/ctor will be ignored by check. 5 by default.
+ * processed method/ctor/lambda will be ignored by check. 5 by default.
*/
private int topLinesToIgnoreCount = DEFAULT_TOP_LINES_TO_IGNORE_COUNT;
@@ -159,7 +170,7 @@ public void setIgnoreMethodsNames(String[] ignoreMethodNames) {
}
/**
- * Sets maximum allowed "return" literals count per method/ctor.
+ * Sets maximum allowed "return" literals count per method/ctor/lambda.
* @param maxReturnCount - the new "maxReturnCount" property value.
* @see ReturnCountExtendedCheck#maxReturnCount
*/
@@ -168,7 +179,7 @@ public void setMaxReturnCount(int maxReturnCount) {
}
/**
- * Sets the maximum number of lines of which method/ctor body may consist to
+ * Sets the maximum number of lines of which method/ctor/lambda body may consist to
* be skipped by check.
* @param ignoreMethodLinesCount
* - the new value of "ignoreMethodLinesCount" property.
@@ -189,7 +200,7 @@ public void setMinIgnoreReturnDepth(int minIgnoreReturnDepth) {
}
/**
- * Sets the "ignoring empty return statements in void methods and ctors"
+ * Sets the "ignoring empty return statements in void methods and ctors and lambdas"
* option state.
* @param ignoreEmptyReturns
* the new "allowEmptyReturns" property value.
@@ -212,16 +223,30 @@ public void setTopLinesToIgnoreCount(int topLinesToIgnoreCount) {
@Override
public int[] getDefaultTokens() {
- return new int[] {TokenTypes.METHOD_DEF, TokenTypes.CTOR_DEF, };
+ return new int[] {
+ TokenTypes.METHOD_DEF,
+ TokenTypes.CTOR_DEF,
+ TokenTypes.LAMBDA,
+ };
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
}
@Override
- public void visitToken(final DetailAST methodDefNode) {
- final DetailAST openingBrace = methodDefNode
+ public void visitToken(final DetailAST node) {
+ final DetailAST openingBrace = node
.findFirstToken(TokenTypes.SLIST);
- final String methodName = getMethodName(methodDefNode);
+ final String nodeName = getMethodName(node);
if (openingBrace != null
- && !matches(methodName, ignoreMethodsNames)) {
+ && !matches(nodeName, ignoreMethodsNames)) {
final DetailAST closingBrace = openingBrace.getLastChild();
int curMethodLinesCount = getLinesCount(openingBrace,
@@ -232,34 +257,48 @@ public void visitToken(final DetailAST methodDefNode) {
}
if (curMethodLinesCount >= ignoreMethodLinesCount) {
-
- final int mCurReturnCount = getReturnCount(methodDefNode,
+ final int mCurReturnCount = getReturnCount(node,
openingBrace);
if (mCurReturnCount > maxReturnCount) {
- final String mKey;
-
- if (methodDefNode.getType() == TokenTypes.METHOD_DEF) {
- mKey = MSG_KEY_METHOD;
- }
- else {
- mKey = MSG_KEY_CTOR;
- }
+ logViolation(node, nodeName, mCurReturnCount);
+ }
+ }
+ }
+ }
- final DetailAST methodNameToken = methodDefNode
- .findFirstToken(TokenTypes.IDENT);
+ /**
+ * Reports violation to user based on the parameters given.
+ * @param node The node that the violation is on.
+ * @param nodeName The name given to the node.
+ * @param mCurReturnCount The return count violation amount.
+ */
+ private void logViolation(DetailAST node, String nodeName, int mCurReturnCount) {
+ if (node.getType() == TokenTypes.LAMBDA) {
+ // lambdas have no name
+ log(node, MSG_KEY_LAMBDA, mCurReturnCount, maxReturnCount);
+ }
+ else {
+ final DetailAST nodeNameToken = node
+ .findFirstToken(TokenTypes.IDENT);
+ final String mKey;
- log(methodNameToken, mKey,
- methodName, mCurReturnCount,
- maxReturnCount);
- }
+ if (node.getType() == TokenTypes.METHOD_DEF) {
+ mKey = MSG_KEY_METHOD;
}
+ else {
+ mKey = MSG_KEY_CTOR;
+ }
+
+ log(nodeNameToken, mKey,
+ nodeName, mCurReturnCount,
+ maxReturnCount);
}
}
/**
- * Gets the "return" statements count for given method/ctor and saves the
- * last "return" statement DetailAST node for given method/ctor body. Uses
+ * Gets the "return" statements count for given method/ctor/lambda and saves the
+ * last "return" statement DetailAST node for given method/ctor/lambda body. Uses
* an iterative algorithm.
* @param methodOpeningBrace
* a DetailAST node that points to the current method`s opening
@@ -275,22 +314,15 @@ private int getReturnCount(final DetailAST methodDefNode,
DetailAST curNode = methodOpeningBrace;
- while (curNode != null) {
-
- // before node visiting
- if (curNode.getType() == TokenTypes.RCURLY
- && curNode.getParent() == methodOpeningBrace) {
- // stop at closing brace
- break;
- }
- else {
- if (curNode.getType() == TokenTypes.LITERAL_RETURN
- && getDepth(methodDefNode, curNode) < minIgnoreReturnDepth
- && shouldEmptyReturnStatementBeCounted(curNode)
- && getLinesCount(methodOpeningBrace,
- curNode) > topLinesToIgnoreCount) {
- result++;
- }
+ // stop at closing brace
+ while (curNode.getType() != TokenTypes.RCURLY
+ || curNode.getParent() != methodOpeningBrace) {
+ if (curNode.getType() == TokenTypes.LITERAL_RETURN
+ && getDepth(methodDefNode, curNode) < minIgnoreReturnDepth
+ && shouldEmptyReturnStatementBeCounted(curNode)
+ && getLinesCount(methodOpeningBrace,
+ curNode) > topLinesToIgnoreCount) {
+ result++;
}
// before node leaving
@@ -300,11 +332,13 @@ && getLinesCount(methodOpeningBrace,
// skip nested methods (UI listeners, Runnable.run(), etc.)
if (type == TokenTypes.METHOD_DEF
// skip anonymous classes
- || type == TokenTypes.CLASS_DEF) {
+ || type == TokenTypes.CLASS_DEF
+ // skip lambdas which is like an anonymous class/method
+ || type == TokenTypes.LAMBDA) {
nextNode = curNode.getNextSibling();
}
- while ((curNode != null) && (nextNode == null)) {
+ while (nextNode == null) {
// leave the visited Node
nextNode = curNode.getNextSibling();
if (nextNode == null) {
@@ -371,12 +405,13 @@ private static int getDepth(DetailAST methodDefNode,
*/
private static String getMethodName(DetailAST methodDefNode) {
String result = null;
- for (DetailAST curNode : getChildren(methodDefNode)) {
- if (curNode.getType() == TokenTypes.IDENT) {
- result = curNode.getText();
- break;
- }
+ final DetailAST ident = methodDefNode.findFirstToken(TokenTypes.IDENT);
+
+ // lambdas don't have a name
+ if (ident != null && methodDefNode.getType() != TokenTypes.LAMBDA) {
+ result = ident.getText();
}
+
return result;
}
@@ -393,23 +428,6 @@ private static int getLinesCount(DetailAST beginAst, DetailAST endAST) {
return endAST.getLineNo() - beginAst.getLineNo();
}
- /**
- * Gets all the children which are one level below on the current DetailAST
- * parent node.
- * @param node
- * Current parent node.
- * @return The list of children one level below on the current parent node.
- */
- private static List getChildren(final DetailAST node) {
- final List result = new LinkedList<>();
- DetailAST curNode = node.getFirstChild();
- while (curNode != null) {
- result.add(curNode);
- curNode = curNode.getNextSibling();
- }
- return result;
- }
-
/**
* Matches string to given list of RegExp patterns.
*
@@ -420,10 +438,16 @@ private static List getChildren(final DetailAST node) {
* @return true if given string could be fully matched by one of given patterns, false otherwise
*/
private static boolean matches(String string, Collection patterns) {
+ String match = string;
+
+ if (match == null) {
+ match = "null";
+ }
+
boolean result = false;
if (!patterns.isEmpty()) {
for (String pattern : patterns) {
- if (string.matches(pattern)) {
+ if (match.matches(pattern)) {
result = true;
break;
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnNullInsteadOfBooleanCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnNullInsteadOfBooleanCheck.java
index fff5b20827..4da752a14d 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnNullInsteadOfBooleanCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/ReturnNullInsteadOfBooleanCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -34,6 +34,7 @@
*
*
* @author Ivan Sopov
+ * @since 1.8.0
*/
public class ReturnNullInsteadOfBooleanCheck extends AbstractCheck {
@@ -55,6 +56,11 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public int[] getRequiredTokens() {
return new int[] {
@@ -105,4 +111,5 @@ public void leaveToken(DetailAST ast) {
break;
}
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SimpleAccessorNameNotationCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SimpleAccessorNameNotationCheck.java
index 48cb94016a..8320124928 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SimpleAccessorNameNotationCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SimpleAccessorNameNotationCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -39,7 +39,7 @@
* , for example:
*
*
- * <module name="SimpleAccesorNameNotationCheck"> <
+ * <module name="SimpleAccessorNameNotationCheck"> <
* property name="prefix" value="m_"/>
* </module>
*
@@ -47,8 +47,10 @@
*
* @author Hidoyatov Victor
* @author Ilja Dubinin
+ * @since 1.9.0
*/
public class SimpleAccessorNameNotationCheck extends AbstractCheck {
+
/**
* A key is pointing to the warning message text in "messages.properties"
* file.
@@ -91,24 +93,34 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST methodDef) {
- final String methodName = methodDef.findFirstToken(TokenTypes.IDENT).getText();
if (hasBody(methodDef) && !isMethodAtAnonymousClass(methodDef)) {
+ final String methodName = methodDef.findFirstToken(TokenTypes.IDENT).getText();
if (methodName.startsWith(BOOLEAN_GETTER_PREFIX)) {
if (!isGetterCorrect(methodDef,
methodName.substring(BOOLEAN_GETTER_PREFIX.length()))) {
- log(methodDef.getLineNo(), MSG_KEY_GETTER);
+ log(methodDef, MSG_KEY_GETTER);
}
}
else if (methodName.startsWith(SETTER_PREFIX)) {
if (!isSetterCorrect(methodDef, methodName.substring(SETTER_PREFIX.length()))) {
- log(methodDef.getLineNo(), MSG_KEY_SETTER);
+ log(methodDef, MSG_KEY_SETTER);
}
}
else if (methodName.startsWith(GETTER_PREFIX)) {
if (!isGetterCorrect(methodDef, methodName.substring(GETTER_PREFIX.length()))) {
- log(methodDef.getLineNo(), MSG_KEY_GETTER);
+ log(methodDef, MSG_KEY_GETTER);
}
}
}
@@ -127,17 +139,14 @@ else if (methodName.startsWith(GETTER_PREFIX)) {
private boolean isSetterCorrect(DetailAST methodDef, String methodName) {
final DetailAST methodType = methodDef.findFirstToken(TokenTypes.TYPE);
boolean result = true;
- if (methodType.branchContains(TokenTypes.LITERAL_VOID)) {
-
+ if (methodType.findFirstToken(TokenTypes.LITERAL_VOID) != null) {
DetailAST currentVerifiedTop = methodDef.findFirstToken(TokenTypes.SLIST);
if (containsOnlyExpression(currentVerifiedTop)) {
-
currentVerifiedTop = currentVerifiedTop.getFirstChild();
- final boolean containsOnlyOneAssignment = currentVerifiedTop.getChildCount() == 1
- && currentVerifiedTop.getFirstChild().getType() == TokenTypes.ASSIGN;
+ final boolean containsOnlyOneAssignment = currentVerifiedTop.getFirstChild()
+ .getType() == TokenTypes.ASSIGN;
if (containsOnlyOneAssignment) {
-
currentVerifiedTop = currentVerifiedTop.getFirstChild();
final DetailAST parameters =
methodDef.findFirstToken(TokenTypes.PARAMETERS);
@@ -147,7 +156,6 @@ private boolean isSetterCorrect(DetailAST methodDef, String methodName) {
if (nameOfSettingField != null
&& verifyFieldAndMethodName(nameOfSettingField,
methodName)) {
-
result = false;
}
}
@@ -171,22 +179,18 @@ private boolean isGetterCorrect(DetailAST methodDef, String methodName) {
final DetailAST parameters = methodDef.findFirstToken(TokenTypes.PARAMETERS);
boolean result = true;
if (parameters.getChildCount() == 0) {
-
DetailAST currentVerifiedTop =
methodDef.findFirstToken(TokenTypes.SLIST);
if (containsOnlyReturn(currentVerifiedTop)) {
-
currentVerifiedTop = currentVerifiedTop.getFirstChild();
if (isCorrectReturn(currentVerifiedTop)) {
-
currentVerifiedTop = currentVerifiedTop.getFirstChild();
final String nameOfGettingField = getNameOfGettingField(currentVerifiedTop);
if (nameOfGettingField != null
&& verifyFieldAndMethodName(nameOfGettingField,
methodName)) {
-
result = false;
}
}
@@ -207,8 +211,7 @@ && verifyFieldAndMethodName(nameOfGettingField,
private static boolean containsOnlyExpression(DetailAST objectBlock) {
//three child: EXPR, SEMI and RCURLY
return objectBlock.getChildCount() == EXPRESSION_BLOCK_CHILD_COUNT
- && objectBlock.getFirstChild().getType() == TokenTypes.EXPR
- && objectBlock.findFirstToken(TokenTypes.SEMI) != null;
+ && objectBlock.getFirstChild().getType() == TokenTypes.EXPR;
}
/**
@@ -225,32 +228,23 @@ private static String getNameOfSettingField(DetailAST assign,
DetailAST parameters) {
String nameOfSettingField = null;
- final DetailAST assigningFirstChild = assign.getFirstChild();
-
if (assign.getChildCount() == 2
&& assign.getLastChild().getType() == TokenTypes.IDENT) {
+ final DetailAST assigningFirstChild = assign.getFirstChild();
if (assigningFirstChild.getType() == TokenTypes.IDENT) {
-
nameOfSettingField = assigningFirstChild.getText();
if (checkNameOfParameters(parameters, nameOfSettingField)) {
nameOfSettingField = null;
}
-
}
else {
if (assigningFirstChild.getType() == TokenTypes.DOT) {
-
- if (assigningFirstChild.getChildCount() == 2
- && "this".equals(assigningFirstChild
- .getFirstChild().getText())
- && assigningFirstChild.getLastChild().getType() == TokenTypes.IDENT) {
-
+ if ("this".equals(assigningFirstChild.getFirstChild().getText())) {
nameOfSettingField = assigningFirstChild.getLastChild()
.getText();
}
-
}
}
}
@@ -292,14 +286,13 @@ private static boolean containsOnlyReturn(DetailAST methodBody) {
* Return true when getter has correct arguments of return.
*
* @param literalReturn
- * - DeailAST contains LITERAL_RETURN
+ * - DetailAST contains LITERAL_RETURN
* @return - true when getter has correct return.
*/
private static boolean isCorrectReturn(DetailAST literalReturn) {
//two child: EXPR and SEMI
return literalReturn.getChildCount() == 2
- && literalReturn.getFirstChild().getType() == TokenTypes.EXPR
- && literalReturn.getLastChild().getType() == TokenTypes.SEMI;
+ && literalReturn.getFirstChild().getType() == TokenTypes.EXPR;
}
/**
@@ -317,16 +310,12 @@ private static String getNameOfGettingField(DetailAST expr) {
final DetailAST exprFirstChild = expr.getFirstChild();
if (exprFirstChild.getType() == TokenTypes.IDENT) {
-
nameOfGettingField = exprFirstChild.getText();
-
}
else {
if (exprFirstChild.getType() == TokenTypes.DOT
&& exprFirstChild.getChildCount() == 2
- && exprFirstChild.getFirstChild().getType() == TokenTypes.LITERAL_THIS
- && exprFirstChild.getLastChild().getType() == TokenTypes.IDENT) {
-
+ && exprFirstChild.getFirstChild().getType() == TokenTypes.LITERAL_THIS) {
nameOfGettingField = exprFirstChild.getLastChild().getText();
}
}
@@ -340,26 +329,23 @@ private static String getNameOfGettingField(DetailAST expr) {
* Return true when name of the field is not contained in parameters of the
* setter method.
*
- * @param paramrters
+ * @param parameters
* - DetailAST contains parameters of the setter.
* @param fieldName
* - name of the field.
* @return true when name of the field is not contained in parameters.
*/
- private static boolean checkNameOfParameters(DetailAST paramrters,
+ private static boolean checkNameOfParameters(DetailAST parameters,
String fieldName) {
-
boolean isNameOfParameter = false;
- final int parametersChildCount = paramrters.getChildCount();
+ final int parametersChildCount = parameters.getChildCount();
- final DetailAST parameterDef = paramrters
+ final DetailAST parameterDef = parameters
.findFirstToken(TokenTypes.PARAMETER_DEF);
for (int i = 0; i < parametersChildCount && !isNameOfParameter; i++) {
-
isNameOfParameter = parameterDef.findFirstToken(TokenTypes.IDENT).getText()
.equals(fieldName);
-
}
return isNameOfParameter;
@@ -389,4 +375,5 @@ private static boolean hasBody(DetailAST methodDef) {
final DetailAST body = methodDef.findFirstToken(TokenTypes.SLIST);
return body != null;
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SingleBreakOrContinueCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SingleBreakOrContinueCheck.java
index 005580e175..75946dffc9 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SingleBreakOrContinueCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/SingleBreakOrContinueCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -109,6 +109,7 @@
*
*
* @author Yasser Aziza
+ * @since 1.18.0
*/
public class SingleBreakOrContinueCheck extends AbstractCheck {
@@ -125,10 +126,20 @@ public int[] getDefaultTokens() {
TokenTypes.LITERAL_DO, };
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST ast) {
if (getNumberOfContinueAndBreaks(ast.getFirstChild()) > 1) {
- log(ast.getLineNo(), MSG_KEY);
+ log(ast, MSG_KEY);
}
}
@@ -171,4 +182,5 @@ private static boolean shouldIgnore(DetailAST node) {
|| TokenTypes.LITERAL_WHILE == node.getType()
|| TokenTypes.LITERAL_DO == node.getType();
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/TernaryPerExpressionCountCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/TernaryPerExpressionCountCheck.java
index 13403c5ca7..be2484b771 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/TernaryPerExpressionCountCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/TernaryPerExpressionCountCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -44,9 +44,12 @@
* System.out.println(x);
*
*
- * Output for code above is "D", but more obvious would be "BC".+ * Output for code above is "D", but more obvious would be "BC". + *
+ *+ * Check has following properties: + *
*
* When using ignoreIsolatedTernaryOnLine (value = true), even without
- * ignoreTernaryOperatorsInBraces option Check won't warn on code below:
+ * ignoreTernaryOperatorsInBraces option Check won't warn on code below:
+ *
* int a = (d == 5) ? d : f @@ -83,6 +88,7 @@ ** * @author Aleksey Nesterenko + * @since 1.12.0 */ public class TernaryPerExpressionCountCheck extends AbstractCheck { @@ -93,12 +99,22 @@ public class TernaryPerExpressionCountCheck extends AbstractCheck { */ public static final String MSG_KEY = "ternary.per.expression.count"; + /** Default limit of ternary operators per expression. */ private static final int DEFAULT_MAX_TERNARY_PER_EXPRESSION_COUNT = 1; + /** Limit of ternary operators per expression. */ private int maxTernaryPerExpressionCount = DEFAULT_MAX_TERNARY_PER_EXPRESSION_COUNT; + /** + * If true Check will ignore ternary operators in braces (braces explicitly + * set priority level). + */ private boolean ignoreTernaryOperatorsInBraces = true; + /** + * If true Check will ignore one line ternary operators, if only it is + * places in line alone. + */ private boolean ignoreIsolatedTernaryOnLine = true; @Override @@ -108,6 +124,16 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + /** * Sets the maximum number of ternary operators, default value = 1. * @@ -143,7 +169,6 @@ public void setIgnoreIsolatedTernaryOnLine(boolean ignoreIsolatedTernaryOnLine) @Override public void visitToken(DetailAST expressionNode) { - final List
* The check is not "type aware", that is to say, it can't tell if parentheses * are unnecessary based on the types in an expression. It also doesn't know - * about operator precedence and associatvity; therefore it won't catch + * about operator precedence and associativity; therefore it won't catch * something like *
*@@ -51,8 +50,10 @@ * * @author Eric Roe * @author Antonenko Dmitriy + * @since 1.8.0 */ public class UnnecessaryParenthesesExtendedCheck extends AbstractCheck { + /**Warning message key.*/ public static final String MSG_KEY_ASSIGN = "unnecessary.paren.assign"; /**Warning message key.*/ @@ -153,51 +154,55 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST ast) { final int type = ast.getType(); - final boolean surrounded = isSurrounded(ast); final DetailAST parent = ast.getParent(); - if ((type == TokenTypes.ASSIGN) - && (parent.getType() == TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR)) { - // shouldn't process assign in annotation pairs - return; - } - - // An identifier surrounded by parentheses. - if (surrounded && (type == TokenTypes.IDENT)) { - parentToSkip = ast.getParent(); - log(ast, MSG_KEY_IDENT, ast.getText()); - return; - } + // shouldn't process assign in annotation pairs + if ((type != TokenTypes.ASSIGN) + || (parent.getType() != TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR)) { + final boolean surrounded = isSurrounded(ast); - // A literal (numeric or string) surrounded by parentheses. - if (surrounded && inTokenList(type, LITERALS)) { - parentToSkip = ast.getParent(); - if (type == TokenTypes.STRING_LITERAL) { - log(ast, MSG_KEY_STRING, - chopString(ast.getText())); + // An identifier surrounded by parentheses. + if (surrounded && (type == TokenTypes.IDENT)) { + parentToSkip = ast.getParent(); + log(ast, MSG_KEY_IDENT, ast.getText()); } - else { - log(ast, MSG_KEY_LITERAL, ast.getText()); + // A literal (numeric or string) surrounded by parentheses. + else if (surrounded && inTokenList(type, LITERALS)) { + parentToSkip = ast.getParent(); + if (type == TokenTypes.STRING_LITERAL) { + log(ast, MSG_KEY_STRING, + chopString(ast.getText())); + } + else { + log(ast, MSG_KEY_LITERAL, ast.getText()); + } } - return; - } - - // The rhs of an assignment surrounded by parentheses. - if (inTokenList(type, ASSIGNMENTS)) { - assignDepth++; - final DetailAST last = ast.getLastChild(); - if (last.getType() == TokenTypes.RPAREN) { - final DetailAST subtree = ast.getFirstChild().getNextSibling() - .getNextSibling(); - final int subtreeType = subtree.getType(); - if (!ignoreCalculationOfBooleanVariables || !inTokenList( - subtreeType, EQUALS)) { - log(ast, MSG_KEY_ASSIGN); + // The rhs of an assignment surrounded by parentheses. + else if (inTokenList(type, ASSIGNMENTS)) { + assignDepth++; + final DetailAST last = ast.getLastChild(); + if (last.getType() == TokenTypes.RPAREN) { + final DetailAST subtree = ast.getFirstChild().getNextSibling() + .getNextSibling(); + final int subtreeType = subtree.getType(); + if (!ignoreCalculationOfBooleanVariables || !inTokenList( + subtreeType, EQUALS)) { + log(ast, MSG_KEY_ASSIGN); + } } - } } } @@ -212,39 +217,7 @@ public void leaveToken(DetailAST ast) { || (parent.getType() != TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR)) { // An expression is surrounded by parentheses. if (type == TokenTypes.EXPR) { - - // If 'mParentToSkip' == 'aAST', then we've already logged a - // warning about an immediate child node in visitToken, so we don't - // need to log another one here. - - if ((parentToSkip != ast) && exprSurrounded(ast)) { - if (assignDepth >= 1) { - if (!ignoreCalculationOfBooleanVariables || !inTokenList( - subtreeType(ast), EQUALS)) { - log(ast, MSG_KEY_ASSIGN); - } - } - else if (ast.getParent().getType() - == TokenTypes.LITERAL_RETURN) { - if (!ignoreCalculationOfBooleanVariablesWithReturn - || !inTokenList(subtreeType(ast), EQUALS)) { - log(ast, MSG_KEY_RETURN); - } - } - else if (ast.getParent().getType() - == TokenTypes.LITERAL_ASSERT) { - if (!ignoreCalculationOfBooleanVariablesWithAssert - || !inTokenList(subtreeType(ast), EQUALS)) { - log(ast, MSG_KEY_EXPR); - } - } - else { - if (!ignoreCalculationOfBooleanVariables || !inTokenList( - subtreeType(ast), EQUALS)) { - log(ast, MSG_KEY_EXPR); - } - } - } + leaveTokenExpression(ast); parentToSkip = null; } @@ -256,6 +229,45 @@ else if (inTokenList(type, ASSIGNMENTS)) { } } + /** + * Examines the expression AST for violations. + * @param ast The AST to examine. + */ + private void leaveTokenExpression(DetailAST ast) { + // If 'mParentToSkip' == 'aAST', then we've already logged a + // warning about an immediate child node in visitToken, so we don't + // need to log another one here. + + if ((parentToSkip != ast) && exprSurrounded(ast)) { + if (assignDepth >= 1) { + if (!ignoreCalculationOfBooleanVariables || !inTokenList( + subtreeType(ast), EQUALS)) { + log(ast, MSG_KEY_ASSIGN); + } + } + else if (ast.getParent().getType() + == TokenTypes.LITERAL_RETURN) { + if (!ignoreCalculationOfBooleanVariablesWithReturn + || !inTokenList(subtreeType(ast), EQUALS)) { + log(ast, MSG_KEY_RETURN); + } + } + else if (ast.getParent().getType() + == TokenTypes.LITERAL_ASSERT) { + if (!ignoreCalculationOfBooleanVariablesWithAssert + || !inTokenList(subtreeType(ast), EQUALS)) { + log(ast, MSG_KEY_EXPR); + } + } + else { + if (!ignoreCalculationOfBooleanVariables || !inTokenList( + subtreeType(ast), EQUALS)) { + log(ast, MSG_KEY_EXPR); + } + } + } + } + /** * Tests if the given* * @author Zuy Alexey + * @since 1.13.0 */ public class UselessSingleCatchCheck extends AbstractCheck { + /** * A key is pointing to the warning message text in "messages.properties" * file. @@ -52,6 +54,16 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST tryBlockNode) { final int catchBlocksCount = tryBlockNode.getChildCount(TokenTypes.LITERAL_CATCH); @@ -78,10 +90,10 @@ && isSimpleRethrow(firstStatementNode)) { /** * Determines whether throw node is of form - *DetailAST
is surrounded by parentheses. * In short, doesaAST
have a previous sibling whose type is @@ -271,8 +283,7 @@ private static boolean isSurrounded(DetailAST ast) { final DetailAST next = ast.getNextSibling(); return (prev != null) && (next != null) - && (prev.getType() == TokenTypes.LPAREN) - && (next.getType() == TokenTypes.RPAREN); + && (prev.getType() == TokenTypes.LPAREN); } /** @@ -285,15 +296,7 @@ private static boolean isSurrounded(DetailAST ast) { * equal toTokenTypes.EXPR
. */ private static boolean exprSurrounded(DetailAST ast) { - boolean surrounded = false; - if (ast.getChildCount() >= MIN_CHILDREN_FOR_MATCH) { - final AST n1 = ast.getFirstChild(); - final AST nn = ast.getLastChild(); - - surrounded = (n1.getType() == TokenTypes.LPAREN) - && (nn.getType() == TokenTypes.RPAREN); - } - return surrounded; + return ast.getChildCount() >= MIN_CHILDREN_FOR_MATCH; } /** @@ -324,10 +327,14 @@ private static boolean inTokenList(int type, int[] tokens) { *MAX_QUOTED_LENGTH
; otherwiseaString
. */ private static String chopString(String string) { + final String result; if (string.length() > MAX_QUOTED_LENGTH) { - return string.substring(0, MAX_QUOTED_LENGTH) + "...\""; + result = string.substring(0, MAX_QUOTED_LENGTH) + "...\""; + } + else { + result = string; } - return string; + return result; } /** @@ -381,4 +388,5 @@ public final void setIgnoreCalculationOfBooleanVariablesWithAssert( this.ignoreCalculationOfBooleanVariablesWithAssert = ignoreCalculationOfBooleanVariablesWithAssert; } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSingleCatchCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSingleCatchCheck.java index 15fdca1c05..322f609a56 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSingleCatchCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSingleCatchCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -37,8 +37,10 @@ *
throw exceptionObject;
+ * throw exceptionObject;
.
* @param throwNode
* node of type TokenTypes.LITERAL_THROW
- * @return wheather this throw node is of specified form
+ * @return whether this throw node is of specified form
*/
private static boolean isSimpleRethrow(DetailAST throwNode) {
final DetailAST exprNode = throwNode.findFirstToken(TokenTypes.EXPR);
@@ -91,7 +103,7 @@ private static boolean isSimpleRethrow(DetailAST throwNode) {
}
/**
- * Gets catch parameter name
+ * Gets catch parameter name.
* @param catchNode
* node of type TokenTypes.LITERAL_CATCH
* @return catch parameter name
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSuperCtorCallCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSuperCtorCallCheck.java
index 97071f8372..ba154c052a 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSuperCtorCallCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/UselessSuperCtorCallCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -32,6 +32,7 @@
*
* * Case 1. no-argument "super()" is called from class ctor if class is not derived, for example: + *
*
*
* class Dummy {
@@ -45,6 +46,7 @@
*
* Case 2. no-argument "super()" is called without parameters from class ctor if class is
* derived, for example:
+ *
*
*
* class Derived extends Base {
@@ -67,6 +69,7 @@
* violations when "super()" called inside derived class. This option defaults to "false".
* If for example this option set to "true", then Check will not generate violation for
* cases like following:
+ *
*
*
* class Base {
@@ -87,9 +90,10 @@
* Check will not generate violation when "super()" called inside class ctor when class
* has multiple public ctors(however, setting this option to "true" will not prevent Check
* from logging violation if class does not extend anything). This option defaults to "false".
- * This option may be usefull for cases in which class`s ctors just forward its arguments to
+ * This option may be useful for cases in which class`s ctors just forward its arguments to
* super ctors, thus removing "super()" in this case will make default ctors look not like
* others. For example:
+ *
*
*
* class Base {
@@ -128,6 +132,7 @@
*
* Checkstyle configuration example with options "allowCallToNoArgsSuperCtor" and
* "allowCallToNoArgsSuperCtorIfMultiplePublicCtor" set to true.
+ *
*
* <module name="UselessSuperCtorCallCheck">
* <property name="allowCallToNoArgsSuperCtor" value="true"/>
@@ -136,8 +141,10 @@
*
*
* @author Zuy Alexey
+ * @since 1.13.0
*/
public class UselessSuperCtorCallCheck extends AbstractCheck {
+
/**
* Violation message key.
*/
@@ -188,6 +195,16 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST aSuperCallNode) {
if (getSuperCallArgsCount(aSuperCallNode) == 0) {
@@ -269,7 +286,7 @@ private static int getClassPublicCtorCount(DetailAST aClassDefNode) {
}
/**
- * Checks whether given ctor is public
+ * Checks whether given ctor is public.
* @param aCtorDefNode
* a ctor definition node(TokenTypes.CTOR_DEF)
* @return true, if given ctor is public
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/WhitespaceBeforeArrayInitializerCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/WhitespaceBeforeArrayInitializerCheck.java
index 35a71938cc..91b7b2aa51 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/WhitespaceBeforeArrayInitializerCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/WhitespaceBeforeArrayInitializerCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -36,14 +36,18 @@
* };
*
*
+ *
* This example is valid too:
+ *
*
*
* int[] tab = new int[]
* {0, 1, 2, 3}
*
*
+ *
* But this violates check:
+ *
*
*
* int[] ints = new int[]{0, 1, 2, 3};
@@ -51,6 +55,7 @@
*
*
* @author liscju
+ * @since 1.14.0
*/
public class WhitespaceBeforeArrayInitializerCheck extends AbstractCheck {
@@ -64,11 +69,21 @@ public int[] getDefaultTokens() {
return new int[] {TokenTypes.ARRAY_INIT};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void visitToken(DetailAST ast) {
final DetailAST previousAst = getPreviousAst(ast);
if (!areTokensSeparatedByWhitespace(previousAst, ast) && isNestedArrayInitializer(ast)) {
- log(ast.getLineNo(), ast.getColumnNo(), MSG_KEY);
+ log(ast, MSG_KEY);
}
}
@@ -120,4 +135,5 @@ private static DetailAST getPreviousAst(DetailAST ast) {
}
return previousAst;
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/package-info.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/package-info.java
index 13b3be2f81..4f344ef7d3 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/package-info.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/package-info.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/AvoidConditionInversionCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/AvoidConditionInversionCheck.java
index 8a650787df..1b0c5c9a64 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/AvoidConditionInversionCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/AvoidConditionInversionCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -81,6 +81,7 @@
*
*
* @author Aleksey Nesterenko
+ * @since 1.13.0
*/
public class AvoidConditionInversionCheck extends AbstractCheck {
@@ -118,7 +119,7 @@ public class AvoidConditionInversionCheck extends AbstractCheck {
/**
* If true - Check only puts violation on conditions with
*
- * relational operands
+ * relational operands.
*/
private boolean applyOnlyToRelationalOperands;
@@ -127,7 +128,6 @@ public class AvoidConditionInversionCheck extends AbstractCheck {
* @param applyOnlyToRelationalOperands The new value for the field.
*/
public void setApplyOnlyToRelationalOperands(boolean applyOnlyToRelationalOperands) {
-
this.applyOnlyToRelationalOperands = applyOnlyToRelationalOperands;
}
@@ -143,16 +143,22 @@ public int[] getDefaultTokens() {
}
@Override
- public void visitToken(DetailAST ast) {
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
final DetailAST expressionAst = ast.findFirstToken(TokenTypes.EXPR);
switch (ast.getType()) {
-
case TokenTypes.LITERAL_RETURN:
-
if (!isEmptyReturn(ast)) {
-
final DetailAST inversionAst = getInversion(expressionAst);
if (isAvoidableInversion(inversionAst)) {
@@ -160,29 +166,26 @@ public void visitToken(DetailAST ast) {
}
}
break;
+
case TokenTypes.LITERAL_WHILE:
case TokenTypes.LITERAL_DO:
case TokenTypes.LITERAL_IF:
-
final DetailAST invertedAst = getInversion(expressionAst);
-
if (isAvoidableInversion(invertedAst)) {
-
log(invertedAst);
}
break;
- case TokenTypes.FOR_CONDITION:
+ case TokenTypes.FOR_CONDITION:
if (!isEmptyForCondition(ast)) {
-
final DetailAST inversionAst = getInversion(expressionAst);
if (isAvoidableInversion(inversionAst)) {
-
log(inversionAst);
}
}
break;
+
default:
Utils.reportInvalidToken(ast.getType());
break;
@@ -190,54 +193,50 @@ public void visitToken(DetailAST ast) {
}
/**
- * Checks if return statement is not empty
+ * Checks if return statement is not empty.
* @param returnAst
* Node of type
* {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LITERAL_RETURN}
* @return true if the return is empty.
*/
private static boolean isEmptyReturn(DetailAST returnAst) {
-
return returnAst.findFirstToken(TokenTypes.EXPR) == null;
}
/**
- * Checks if condition in for-loop is not empty
+ * Checks if condition in for-loop is not empty.
* @param forConditionAst
* Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#FOR_CONDITION}
* @return true if the for condition is empty.
*/
private static boolean isEmptyForCondition(DetailAST forConditionAst) {
-
return forConditionAst.getFirstChild() == null;
}
/**
- * Gets inversion node of condition if one exists
+ * Gets inversion node of condition if one exists.
* @param expressionAst
* Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#EXPR}
* @return Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LNOT}
* if exists, else - null
*/
private static DetailAST getInversion(DetailAST expressionAst) {
-
return expressionAst.findFirstToken(TokenTypes.LNOT);
}
/**
- * Checks if current inversion is avoidable according to Check's properties
+ * Checks if current inversion is avoidable according to Check's properties.
* @param inversionAst
* Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LNOT}
* @return true if the inversion is avoidable.
*/
private boolean isAvoidableInversion(DetailAST inversionAst) {
-
return inversionAst != null && !isSkipCondition(inversionAst);
}
/**
* Checks if current inverted condition has to be skipped by Check,
- * it depends from user-defined property "applyOnlyToRelationalOperands"
+ * it depends from user-defined property "applyOnlyToRelationalOperands".
* if it's true - Check will ignore inverted conditions with
* non-relational operands
* @param inversionConditionAst
@@ -245,7 +244,6 @@ private boolean isAvoidableInversion(DetailAST inversionAst) {
* @return true if token can be skipped.
*/
private boolean isSkipCondition(DetailAST inversionConditionAst) {
-
return (applyOnlyToRelationalOperands
&& !containsRelationalOperandsOnly(inversionConditionAst))
|| !containsConditionalOrRelationalOperands(inversionConditionAst);
@@ -254,29 +252,24 @@ private boolean isSkipCondition(DetailAST inversionConditionAst) {
/**
* Checks if current inverted condition contains only
*
- * relational operands
+ * relational operands.
* @param inversionConditionAst
* Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LNOT}
* @return true if the node contains only relation operands.
*/
private static boolean containsRelationalOperandsOnly(DetailAST inversionConditionAst) {
-
boolean result = true;
final DetailAST operatorInInversionAst = inversionConditionAst.getFirstChild()
.getNextSibling();
if (operatorInInversionAst != null) {
-
if (!RELATIONAL_OPERATORS_SET.contains(operatorInInversionAst.getType())) {
-
DetailAST currentNode = operatorInInversionAst.getFirstChild();
while (currentNode != null) {
-
if ((currentNode.getType() == TokenTypes.IDENT)
|| (!isRelationalOperand(currentNode))) {
-
result = false;
}
@@ -291,13 +284,12 @@ private static boolean containsRelationalOperandsOnly(DetailAST inversionConditi
/**
* Checks if current operand is
*
- * relational operand
+ * relational operand.
* @param operandAst
* Child node of {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LNOT} node
* @return true if the operand is relational.
*/
private static boolean isRelationalOperand(DetailAST operandAst) {
-
return operandAst.getFirstChild() == null
|| RELATIONAL_OPERATORS_SET.contains(operandAst.getType());
}
@@ -305,21 +297,18 @@ private static boolean isRelationalOperand(DetailAST operandAst) {
/**
* Checks if current condition contains
*
- * conditional operators
+ * conditional operators.
* @param inversionAst
* Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LNOT}
* @return true if the node contains conditional or relational operands.
*/
private static boolean containsConditionalOrRelationalOperands(DetailAST inversionAst) {
-
boolean result = false;
DetailAST currentNodeAst = inversionAst.getFirstChild();
while (currentNodeAst != null) {
-
if (RELATIONAL_AND_CONDITIONAL_OPERATORS_SET.contains(currentNodeAst.getType())) {
-
result = true;
}
@@ -330,13 +319,12 @@ private static boolean containsConditionalOrRelationalOperands(DetailAST inversi
}
/**
- * Logs message on line where inverted condition is used
+ * Logs message on line where inverted condition is used.
* @param inversionAst
* Node of type {@link com.puppycrawl.tools.checkstyle.api.TokenTypes#LNOT}
*/
private void log(DetailAST inversionAst) {
-
- log(inversionAst.getLineNo(), MSG_KEY);
+ log(inversionAst, MSG_KEY);
}
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/CauseParameterInExceptionCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/CauseParameterInExceptionCheck.java
index dd7794aec7..b69c38ed68 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/CauseParameterInExceptionCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/CauseParameterInExceptionCheck.java
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
+// Copyright (C) 2001-2018 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -46,8 +46,10 @@
* ("allowedCauseTypes" option).
+ * Custom check to ensure Checkstyle tests are designed correctly. + *
+ * + *Rationale: This check was made to ensure tests follow a specific design implementation + * so 3rd party utilities like the regression utility can parse the tests for information + * used in creating regression reports. + * + *
+ * Check have following options: + *
+ *+ * To configure the check to report incorrectly made checkstyle tests: + *
+ * + *+ * <module name="CheckstyleTestMakeup"/> + *+ * + * @author Richard Veach + * @since 1.25.0 + */ +public class CheckstyleTestMakeupCheck extends AbstractCheck { + + /** Violations message. */ + public static final String MSG_KEY_CONFIG_NOT_ASSIGNED = "tester.config.not.assigned"; + /** Violations message. */ + public static final String MSG_KEY_CONFIG_NOT_ASSIGNED_WITH = "tester.config.not.assigned.with"; + /** Violations message. */ + public static final String MSG_KEY_CONFIG_NOT_ASSIGNED_PROPERLY = + "tester.config.not.assigned.properly"; + /** Violations message. */ + public static final String MSG_KEY_UNKNOWN_PROPERTY = "tester.unknown.property"; + /** Violations message. */ + public static final String MSG_KEY_CONFIG_NOT_FOUND = "tester.config.not.found"; + + /** Name of 'getPath' method. */ + private static final String METHOD_GET_PATH = "getPath"; + + /** AST of method that is currently being examined. */ + private DetailAST methodAst; + /** List of variable names that reference a file. */ + private Set
+ * Examples: + * + * JDK Collectors, so usage + * of methods that return wildcard could force user customizations over Collectors use wildcard in + * public methods + *
+ *{@code + * // custom util method, wildcard come from Collectors.toList() + * public+ *Collector singleResult(Function super Iterable , T> collector) { + * return Collectors.collectingAndThen(Collectors.toList(), collected -> collected.get(0)); + * } + * }
If suppressions become too wide spread and annoying it might be reasonable to update Check + * with option to ignore wildcard if used with another type (not alone). *
* @author Baratali Izmailov + * @since 1.9.0 */ public class ForbidWildcardAsReturnTypeCheck extends AbstractCheck { + /** * Key for error message. */ @@ -62,6 +83,19 @@ public class ForbidWildcardAsReturnTypeCheck extends AbstractCheck { */ private static final int WILDCARD_SUPER_IDENT = TokenTypes.TYPE_LOWER_BOUNDS; + + /** {@link Deprecated Deprecated} annotation name. */ + private static final String DEPRECATED = "Deprecated"; + + /** Fully-qualified {@link Deprecated Deprecated} annotation name. */ + private static final String FQ_DEPRECATED = "java.lang." + DEPRECATED; + + /** {@link Override Override} annotation name. */ + private static final String OVERRIDE = "Override"; + + /** Fully-qualified {@link Override Override} annotation name. */ + private static final String FQ_OVERRIDE = "java.lang." + OVERRIDE; + /** * Empty array of DetailAST. */ @@ -184,26 +218,48 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public void visitToken(DetailAST methodDefAst) { final String methodScope = getVisibilityScope(methodDefAst); - if (((checkPublicMethods && "public".equals(methodScope)) - || (checkPrivateMethods && "private".equals(methodScope)) - || (checkProtectedMethods && "protected".equals(methodScope)) - || (checkPackageMethods && "package".equals(methodScope))) + if (isCheckableMethodScope(methodScope) && (checkOverrideMethods - || !hasAnnotation(methodDefAst, "Override")) + || (!AnnotationUtility.containsAnnotation(methodDefAst, OVERRIDE) + && !AnnotationUtility.containsAnnotation(methodDefAst, FQ_OVERRIDE))) && (checkDeprecatedMethods - || !hasAnnotation(methodDefAst, "Deprecated"))) { + || (!AnnotationUtility.containsAnnotation(methodDefAst, DEPRECATED) + && !AnnotationUtility.containsAnnotation(methodDefAst, + FQ_DEPRECATED)))) { final List@@ -40,27 +40,37 @@ * } * * + *
* Nested switch block that checks type
parameter should be converted into separate
* method.
- * To enable this check use following configuration:
- *
- * <module name="NestedSwitchCheck"/>
- *
+ * To enable this check use following configuration:
+ *
+ * <module name="NestedSwitchCheck"/> + ** @author Damian Szczepanik (damianszczepanik@github) + * @since 1.13.0 */ -public class NestedSwitchCheck extends AbstractNestedDepthCheck { +public class NestedSwitchCheck extends AbstractCheck { + /** * A key is pointing to the warning message text in "messages.properties" * file. */ public static final String MSG_KEY = "avoid.nested.switch"; - /** Default allowed nesting depth. */ - private static final int DEFAULT_MAX = 0; + /** Maximum allowed nesting depth. */ + private int max; + /** Current nesting depth. */ + private int depth; - /** The default constructor. */ - public NestedSwitchCheck() { - super(DEFAULT_MAX); + /** + * Setter for maximum allowed nesting depth. + * @param max maximum allowed nesting depth. + */ + public final void setMax(int max) { + this.max = max; } @Override @@ -70,13 +80,32 @@ public int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public final int[] getRequiredTokens() { + return getDefaultTokens(); + } + + @Override + public void beginTree(DetailAST rootAST) { + depth = 0; + } + @Override public void visitToken(DetailAST aAST) { - nestIn(aAST, MSG_KEY); + if (depth > max) { + log(aAST, MSG_KEY, depth, max); + } + ++depth; } @Override public void leaveToken(DetailAST aAST) { - nestOut(); + --depth; } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/NoMainMethodInAbstractClassCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/NoMainMethodInAbstractClassCheck.java index 2cb46fdb62..46294324ae 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/NoMainMethodInAbstractClassCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/NoMainMethodInAbstractClassCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -30,8 +30,10 @@ * Forbids main methods in abstract classes. Existence of 'main' method can * mislead a developer to consider this class as a ready-to-use implementation. * @author Baratali Izmailov email + * @since 1.9.0 */ public class NoMainMethodInAbstractClassCheck extends AbstractCheck { + /** * Key for error message. */ @@ -54,6 +56,16 @@ public final int[] getDefaultTokens() { }; } + @Override + public int[] getAcceptableTokens() { + return getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return getDefaultTokens(); + } + @Override public final void visitToken(final DetailAST ast) { if (ast.getType() == TokenTypes.CLASS_DEF) { @@ -68,7 +80,7 @@ public final void visitToken(final DetailAST ast) { } // type of token is METHOD_DEF else if (isChildOfCurrentObjBlockToken(ast) && isMainMethod(ast)) { - log(ast.getLineNo(), MSG_KEY); + log(ast, MSG_KEY); // remove current objblock objBlockTokensStack.pop(); } @@ -110,13 +122,9 @@ private boolean isChildOfCurrentObjBlockToken(final DetailAST methodDefAST) { * @return true if AST has abstract modifier, false otherwise. */ private static boolean hasAbstractModifier(final DetailAST classDefAST) { - boolean result = false; - if (hasChildToken(classDefAST, TokenTypes.MODIFIERS)) { - final DetailAST modifiers = - classDefAST.findFirstToken(TokenTypes.MODIFIERS); - result = hasChildToken(modifiers, TokenTypes.ABSTRACT); - } - return result; + final DetailAST modifiers = + classDefAST.findFirstToken(TokenTypes.MODIFIERS); + return hasChildToken(modifiers, TokenTypes.ABSTRACT); } /** @@ -148,10 +156,7 @@ && isMainMethodModifiers(methodAST) */ private static String getIdentifier(final DetailAST ast) { final DetailAST ident = ast.findFirstToken(TokenTypes.IDENT); - if (ident != null) { - return ident.getText(); - } - return null; + return ident.getText(); } /** @@ -162,14 +167,10 @@ private static String getIdentifier(final DetailAST ast) { * false otherwise. */ private static boolean isMainMethodModifiers(final DetailAST methodAST) { - boolean result = false; - if (hasChildToken(methodAST, TokenTypes.MODIFIERS)) { - final DetailAST modifiers = - methodAST.findFirstToken(TokenTypes.MODIFIERS); - result = hasChildToken(modifiers, TokenTypes.LITERAL_PUBLIC) - && hasChildToken(modifiers, TokenTypes.LITERAL_STATIC); - } - return result; + final DetailAST modifiers = + methodAST.findFirstToken(TokenTypes.MODIFIERS); + return hasChildToken(modifiers, TokenTypes.LITERAL_PUBLIC) + && hasChildToken(modifiers, TokenTypes.LITERAL_STATIC); } /** @@ -179,13 +180,8 @@ private static boolean isMainMethodModifiers(final DetailAST methodAST) { * @return true if AST's type void, false otherwise. */ private static boolean isVoidType(final DetailAST methodAST) { - boolean result = true; - DetailAST methodTypeAST = null; - if (hasChildToken(methodAST, TokenTypes.TYPE)) { - methodTypeAST = methodAST.findFirstToken(TokenTypes.TYPE); - result = hasChildToken(methodTypeAST, TokenTypes.LITERAL_VOID); - } - return result; + final DetailAST methodTypeAST = methodAST.findFirstToken(TokenTypes.TYPE); + return hasChildToken(methodTypeAST, TokenTypes.LITERAL_VOID); } /** @@ -276,4 +272,5 @@ private static boolean hasOnlyStringEllipsisParameter(final DetailAST parameters private static boolean hasChildToken(DetailAST ast, int tokenType) { return ast.findFirstToken(tokenType) != null; } + } diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/PublicReferenceToPrivateTypeCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/PublicReferenceToPrivateTypeCheck.java index 4992c452ee..0c07caf39d 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/PublicReferenceToPrivateTypeCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/design/PublicReferenceToPrivateTypeCheck.java @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. -// Copyright (C) 2001-2016 the original author or authors. +// Copyright (C) 2001-2018 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,6 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes; /** - *
* This Check warns on propagation of inner private types to outer classes:
* - Externally accessible method if it returns private inner type.
* - Externally accessible field if it's type is a private inner type.
@@ -71,8 +70,10 @@
* dead/useless code
*
* @author Aleksey Nesterenko
+ * @since 1.12.0
*/
public class PublicReferenceToPrivateTypeCheck extends AbstractCheck {
+
/**
* Check message key for private types.
*/
@@ -99,6 +100,16 @@ public int[] getDefaultTokens() {
};
}
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
@Override
public void beginTree(DetailAST rootAST) {
privateTypes.clear();
@@ -141,7 +152,7 @@ public void finishTree(DetailAST rootAst) {
outReturnedType.getText())
&& !isExtendsOrImplementsSmth(privateType
.getParent())) {
- log(outReturnedType.getLineNo(), MSG_KEY,
+ log(outReturnedType, MSG_KEY,
outReturnedType.getText());
}
}
@@ -193,7 +204,6 @@ private void addExternallyAccessibleFieldTypes(DetailAST fieldDefAst) {
*/
private static List
- * Enums are defined to be used as class have some own methods. This condition
- * is used to distinguish between Values Enumeration and Class Enumeration.
- * Values Enumeration looks like the following:
- * enum SimpleErrorEnum
- * {
- * FIRST_SIMPLE, SECOND_SIMPLE, THIRD_SIMPLE;
- * }
- *
- *
- * While Class Enumeration has some methods, for example:
- * enum SimpleErrorEnum
- * {
- * FIRST_SIMPLE, SECOND_SIMPLE, THIRD_SIMPLE;
- *
- * public String toString() {
- * return Integer.toString(ordinal() + 10);
- * }
- * }
- *
*
- * Name format for Class Enumeration values is specified with - * {@link #setObjFormat(String)} , while format for enum constants - with - * {@link #setConstFormat(String)} + * Checks that enumeration value names conform to a format specified + * by the format property. The format is a + * {@link java.util.regex.Pattern regular expression} and defaults to + * ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$. + *
*
- * To avoid assuming enum as static object reference, while using some specific
- * methods, {@link #setExcludes(String[])} can be used. For example to make enum in
- * the previous example a constant set Excludes property to a value
- * toString
+ * An example of how to configure the check is:
+ *
+ * <module name="EnumValueName"/> + **
- * By default toString
is used as an exclusion.
+ * An example of how to configure the check for names that requires all names to be lowercase
+ * with underscores and digits is:
+ *
+ * <module name="EnumValueName"> + * <property name="format" value="^[a-z_0-9]+*$"/> + * </module> + ** * @author Pavel Baranchikov - * - * @see - * Java Coding Style + * @since 1.24.0 */ -public class EnumValueNameCheck extends AbstractCheck { - /** - * A key is pointing to the warning message text in "messages.properties" - * file. - */ - public static final String MSG_CONST = "enum.name.const.invalidPattern"; - /** - * A key is pointing to the warning message text in "messages.properties" - * file. - */ - public static final String MSG_OBJ = "enum.name.obj.invalidPattern"; +public class EnumValueNameCheck extends AbstractNameCheck { /** * Default pattern for Values Enumeration names. */ - public static final String DEFAULT_CONST_PATTERN = + public static final String DEFAULT_PATTERN = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"; /** - * Default pattern for Class Enumeration names. - */ - public static final String DEFAULT_OBJ_PATTERN = "^[A-Z][a-zA-Z0-9]*$"; - - /** - * Default exclusions value. - */ - private static final String[] DEFAULT_EXCLUSION = { - "toString", - }; - - /** - * Regular expression to test Class Enumeration names against. - */ - private Pattern objRegexp; - - /** - * Format for Class Enumeration names to check for. Compiled to - * {@link #objRegexp} - */ - private String objFormat; - - /** - * Regular expression to test Values Enumeration names against. - */ - private Pattern constRegexp; - - /** - * Format for Values Enumeration names to check for. Compiled to - * {@link #constRegexp} - */ - private String constFormat; - - /** - * Method and field names to exclude from check. - */ - private final List
true
if enum is a class enumeration
- */
- private boolean isClassEnumeration(DetailAST ast) {
- return hasMembers(ast, excludes);
+ public int[] getAcceptableTokens() {
+ return new int[] {TokenTypes.ENUM_CONSTANT_DEF};
}
- /**
- * Method determines whether the specified enum is a constant or is an
- * object.
- *
- * @param ast
- * token of a enum value definition
- * @param excludes
- * list of ignored member names
- * @return true
if enum is a class enumeration
- */
- private static boolean
- hasMembers(DetailAST ast, Listtrue
if at least one pattern have been successfully
- * matched.
- */
- private static boolean
- isAnyMatched(CollectionString
value
- * @throws ConversionException
+ * @throws IllegalArgumentException
* unable to parse aFormat
*/
- public final void setIgnorePattern(String format) throws ConversionException {
+ public final void setIgnorePattern(String format) {
try {
ignorePattern = Pattern.compile(format);
}
catch (final PatternSyntaxException ex) {
- throw new ConversionException("unable to parse " + format, ex);
+ throw new IllegalArgumentException("unable to parse " + format, ex);
}
}
+
}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/sizes/package-info.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/sizes/package-info.java
new file mode 100644
index 0000000000..39638f5dda
--- /dev/null
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/sizes/package-info.java
@@ -0,0 +1,24 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2018 the original author or authors.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Contains the Size checks
+ * that are bundled with the main distribution.
+ */
+package com.github.sevntu.checkstyle.checks.sizes;
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/package-info.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/package-info.java
new file mode 100644
index 0000000000..aaf7c26f65
--- /dev/null
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/package-info.java
@@ -0,0 +1,24 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2018 the original author or authors.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Contains the miscellaneous utilities that are bundled with the main distribution.
+ */
+package com.github.sevntu.checkstyle;
+
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/annotation/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/annotation/messages.properties
index 364c1c8aac..0e1fc4b4c7 100644
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/annotation/messages.properties
+++ b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/annotation/messages.properties
@@ -1,16 +1,3 @@
-annotation.missing.deprecated=Must include both @java.lang.Deprecated annotation and @deprecated Javadoc tag with description.
-annotation.missing.override=Must include @java.lang.Override annotation when '{'@inheritDoc'}' Javadoc tag exists.
annotation.missing.required.parameter=The annotation {0} is missing required parameters {1}.
-annotation.not.valid.on=The annotation {0} is not valid at this location.
-annotation.incorrect.style=Annotation style must be ''{0}''.
annotation.incorrect.target=Incorrect target: ''{0}'' for annotation: ''{1}''.
-annotation.trailing.comma.missing=Annotation array values must contain trailing comma.
-annotation.trailing.comma.present=Annotation array values cannot contain trailing comma.
-annotation.parens.missing=Annotation must have closing parenthesis.
-annotation.parens.present=Annotation cannot have closing parenthesis.
-annotation.package.location=Package annotations must be in the package-info.java info.
annotation.forbid.element.value=Forbidden element ''{0}'' in annotation ''{1}''.
-suppressed.warning.not.allowed=The warning ''{0}'' cannot be suppressed at this location.
-javadoc.duplicateTag=Duplicate {0} tag.
-javadoc.missing=Missing a Javadoc comment.
-tag.not.valid.on=The Javadoc {0} tag is not valid at this location.
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties
index 1db1574900..ff1ddb38b9 100644
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties
+++ b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties
@@ -1,14 +1,8 @@
-array.trailing.comma=Array should contain trailing comma.
-assignment.inner.avoid=Inner assignments should be avoided.
-avoid.declare.constants=Constants declaration inside interfaces should be avoided.
avoid.default.serializable.in.inner.classes=Inner class should not implement default Serializable interface.
-avoid.finalizer.method=Usage of finalizer method should be avoided.
-avoid.clone.method=Usage of 'clone' method should be avoided.
avoid.hiding.cause.exception=Cause exception ''{0}'' was lost.
avoid.not.short.circuit.operators.for.boolean=Short-circuit operator should be used instead of ''{0}''.
avoid.modifiers.for.types=''{0}'' instance should not have ''{1}'' modifier.
avoid.constant.as.first.operand.in.condition=Constant have to be second operand of ''{0}''.
-covariant.equals=Covariant equals without overriding equals(java.lang.Object).
confusing.condition.check=Avoid negation within an "if" expression with an "else" clause.
custom.declaration.order.field=Field definition in wrong order. Expected ''{0}'' then ''{1}''.
custom.declaration.order.constructor=Constructor definition in wrong order. Expected ''{0}'' then ''{1}''.
@@ -17,87 +11,43 @@ custom.declaration.order.class=Class definition in wrong order. Expected ''{0}''
custom.declaration.order.interface=Interface definition in wrong order. Expected ''{0}'' then ''{1}''.
custom.declaration.order.enum=Enum definition in wrong order. Expected ''{0}'' then ''{1}''.
custom.declaration.order.invalid.setter=Setter ''{0}'' is in wrong order. Should be right after ''{1}''.
-declaration.order.constructor=Constructor definition in wrong order.
-declaration.order.method=Method definition in wrong order.
-declaration.order.static=Static variable definition in wrong order.
-declaration.order.instance=Instance variable definition in wrong order.
-declaration.order.access=Variable access definition in wrong order.
-default.comes.last=Default should be the last switch label.
diamond.operator.for.variable.definition = Diamond operator expected.
-doublechecked.locking.avoid=The double-checked locking idiom is broken and should be avoided.
-empty.statement=Empty statement.
+either.log.or.throw=Either log or throw exception.
empty.public.ctor=This empty public constructor is useless.
enum.trailing.comma=Enum constant should contain trailing comma.
enum.trailing.comma.semi=Enum constant should contain trailing comma without semi-colon afterwards.
-equals.avoid.null=String literal expressions should be on the left side of an equals comparison.
-equals.noHashCode=Definition of ''equals()'' without corresponding definition of ''hashCode()''.
-either.log.or.throw=Either log or throw exception.
-explicit.init=Variable ''{0}'' explicitly initialized to ''{1}'' (default value for its type).
-fall.through=Fall through from previous branch of the switch statement.
-fall.through.last=Fall through from the last branch of the switch statement.
-final.variable=Variable ''{0}'' should be declared final.
finalize.implementation.missed.try.finally = finalize() method should contain try-finally block with super.finalize() call inside finally block.
finalize.implementation.public = finalize() method should have a "protected" visibility.
finalize.implementation.useless = finalize() method is useless: it does nothing except for calling super.finalize().
finalize.implementation.missed.super.finalize = You have to call super.finalize() right after finally opening brace.
forbid.certain.imports=Import ''{1}'' should not match ''{0}'' pattern, it is forbidden.
+forbid.certain.method=Call to ''{0}'' method (matches pattern ''{1}'') with ''{2}'' arguments (matches pattern ''{3}'') is forbidden.
forbid.c.comments.in.the.method.body=C-style comments (/*...*/) inside method body are not allowed.
forbid.return.in.finally.block=Finally block should not contain return statements.
forbid.throw.anonymous.exception=Avoid throwing anonymous exception.
-hidden.field=''{0}'' hides a field.
illegal.catch=Catching ''{0}'' is not allowed.
-illegal.throw=Throwing ''{0}'' is not allowed.
forbid.instantiation=Instantiation of ''{0}'' is not allowed.
-illegal.token=Usage of ''{0}'' is not allowed.
-illegal.token.text=Token text matches an illegal pattern ''{0}''.
-illegal.type=Declaring variables, return values or parameters of type ''{0}'' is not allowed.
incorrect.getter.name=Unexpected getter name.
incorrect.setter.name=Unexpected setter name.
-inline.conditional.avoid=Inline conditionals should be avoided.
-instantiation.avoid=Instantiation of {0} should be avoided.
-junit.method.name=The method ''{0}'' should be named ''{1}''.
-junit.method.return.type=The method ''{0}'' must be declared with a {1} return type.
-junit.method.parameters=The method ''{0}'' must be declared with no parameters.
-junit.method.public.and.static=The method ''{0}'' must be declared static.
-junit.method.protected.or.public=The method ''{0}'' must be public or protected.
-junit.method.static=The method ''{0}'' shouldn''t be static.
logic.condition.need.optimization=Condition with {0} at line {1} position {2} need optimization. All method calls are advised to move to end of logic expression.
-magic.number=''{0}'' is a magic number.
map.iteration.entrySet=You are using both keys and values for this map. It is better to use entrySet() instead of keySet() + get().
map.iteration.keySet=It is better to use keySet() method to iterate over this map because you aren`t using values.
map.iteration.values=You are using only values of this map. It is better to use values() to iterate this map.
-redundant.return=Redundant return.
-missing.ctor=Class should define a constructor.
-missing.package.declaration=Missing package declaration.
-missing.super.call=Method ''{0}'' should call ''super.{0}''.
-missing.switch.default=switch without \"default\" clause.
-modified.control.variable=Control variable ''{0}'' is modified.
+move.variable.inside=Variable ''{0}'' can be moved inside the block at line ''{1}'' to restrict runtime creation.
multiple.string.literal=The String {0} appears {1} times in the file.
multiple.variable.declarations=Only one variable definition per line allowed.
multiple.variable.declarations.comma=Each variable declaration must be in its own statement.
name.convention.for.test.classes=JUnit test class name should match ''{0}'' pattern.
-nested.if.depth=Nested if-else depth is {0,number,integer} (max allowed is {1,number,integer}).
-nested.try.depth=Nested try depth is {0,number,integer} (max allowed is {1,number,integer}).
no.null.for.collections=Method should return empty collection instead of null.
numeric.literal.need.underscore=Numeric literal should have underscores.
overridable.method=Overridable method ''{0}'' is called in {1} body.
overridable.method.leads=Calling the method ''{0}'' in {1} body leads to the call of the overridable method ''{2}''.
-parameter.assignment=Assignment of parameter ''{0}'' is not allowed.
redundant.return.check=Redundant return.
-redundant.throws.classInfo=Unable to get class information for {0}.
-redundant.throws.duplicate=Redundant throws: ''{0}'' listed more then one time.
-redundant.throws.subclass=Redundant throws: ''{0}'' is subclass of ''{1}''.
-redundant.throws.unchecked=Redundant throws: ''{0}'' is unchecked exception.
-require.this.variable=Reference to instance variable ''{0}'' needs \"this.\".
-require.this.unfound.variable=Unable find where ''{0}'' is declared.
-require.this.method=Method call to ''{0}'' needs \"this.\".
+require.fail=try/catch either requires a fail at the end of the try clause for junit tests or to remove the try/catch completely.
return.count.extended.method=Return count for ''{0}'' method is {1} (max allowed is {2}).
return.count.extended.ctor=Return count for ''{0}'' constructor is {1} (max allowed is {2}).
-return.depth=Return depth is {0,number,integer} (max allowed is {1,number,integer}).
-simplify.boolreturn=Conditional logic can be removed.
-simplify.expression=Expression can be simplified.
+return.count.extended.lambda=Return count for the lambda is {0} (max allowed is {1}).
single.break.or.continue.in.loops=Loops should not contain more than a single "break" or "continue" statement
-string.literal.equality=Literal Strings should be compared using equals(), not ''{0}''.
ternary.per.expression.count=More than {0} ternary operators in expression.
unnecessary.paren.assign=Unnecessary parentheses around assignment right-hand side.
unnecessary.paren.expr=Unnecessary parentheses around expression.
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/design/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/design/messages.properties
index a80d88568c..d5ecc9e63e 100644
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/design/messages.properties
+++ b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/design/messages.properties
@@ -4,14 +4,13 @@ avoid.nested.switch=Nested switch should be avoided, extract nested switch block
avoid.main.method.in.abstract.class=Main method inside abstract class should be avoided.
cause.parameter.in.exception=''{0}'' class should have a constructor with exception cause as parameter.
child.block.length=Block length is {0} lines, but should be lesser or equal to {1} lines.
-design.forExtension=Method ''{0}'' is not designed for extension - needs to be abstract, final or empty.
-final.class=Class {0} should be declared as final.
-interface.type=interfaces should describe a type and hence have methods.
-variable.notPrivate=Variable ''{0}'' must be private and have accessor methods.
-mutable.exception=The field ''{0}'' must be declared final.
-throws.count=Throws count is {0,number,integer} (max allowed is {1,number,integer}).
hide.utility.class=Utility classes should not have a public or default constructor.
forbid.wildcard.as.return.type=Wildcard as return type should be avoided.
public.reference.to.private.type=Reference to the the instance of private type: {0}.
static.method.candidate=Method {0} should be declared as static.
constructor.without.params=Calls to constructors of ''{0}'' should use at least one parameter.
+tester.config.not.assigned=DefaultConfiguration not assigned.
+tester.config.not.assigned.with=DefaultConfiguration was not assigned by an allowed create configuration method.
+tester.config.not.assigned.properly=DefaultConfiguration was not assigned properly.
+tester.unknown.property=Unknown property name/value.
+tester.config.not.found=DefaultConfiguration was not found.
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/naming/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/naming/messages.properties
index d4b7f4b6ed..0edc20059a 100644
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/naming/messages.properties
+++ b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/naming/messages.properties
@@ -1,8 +1,3 @@
name.invalidPattern=Name ''{0}'' must match pattern ''{1}''.
-illegal.abstract.class.name=Name ''{0}'' must match pattern ''{1}''.
-no.abstract.class.modifier=Class ''{0}'' must has abstract modifier.
-method.name.equals.class.name=Method Name ''{0}'' must not equal the enclosing class name.
-enum.name.const.invalidPattern=Name of Values Enumeration ''{0}'' must match pattern ''{1}''.
-enum.name.obj.invalidPattern=Name of Class Enumeration ''{0}'' must match pattern ''{1}''.
enum.name.formats.violated=Name of enumeration value ''{0}'' must match one of patterns: {1}.
enum.name.format.violated=Name of enumeration value ''{0}'' must match pattern {1}.
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/sizes/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/sizes/messages.properties
index f62baa656c..8adbb4e74b 100644
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/sizes/messages.properties
+++ b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/sizes/messages.properties
@@ -1,7 +1 @@
-executableStatementCount=Executable statement count is {0,number,integer} (max allowed is {1,number,integer}).
-maxLen.file=File length is {0,number,integer} lines (max allowed is {1,number,integer}).
-maxLen.method=Method length is {0,number,integer} lines (max allowed is {1,number,integer}).
-maxLen.anonInner=Anonymous inner class length is {0,number,integer} lines (max allowed is {1,number,integer}).
maxLineLen=Line is longer than {0,number,integer} characters. Current line length is {1,number,integer}.
-maxOuterTypes=Outer types defined is {0,number,integer} (max allowed is {1,number,integer}).
-maxParam=More than {0,number,integer} parameters.
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/whitespace/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/whitespace/messages.properties
deleted file mode 100644
index 3ebf816e2f..0000000000
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/whitespace/messages.properties
+++ /dev/null
@@ -1 +0,0 @@
-single.space.separator=Use a single space to separate tokens.
diff --git a/sevntu-checks/src/main/sh/ast.sh b/sevntu-checks/src/main/sh/ast.sh
index 244d4e8e65..ba4db142a7 100755
--- a/sevntu-checks/src/main/sh/ast.sh
+++ b/sevntu-checks/src/main/sh/ast.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#################################################################################
-# This is a useful script which builds Checkstyle AST (abstract synthax tree) #
+# This is a useful script which builds Checkstyle AST (abstract syntax tree) #
# for custom Java file and opens it using simple built-in Checkstyle GUI. #
#################################################################################
@@ -41,7 +41,7 @@ CHECKSTYLE_VERSION=5.7
ARCHIVE_FILE_NAME=checkstyle-${CHECKSTYLE_VERSION}-bin.tar.gz
CHECKSTYLE_OUTPUT_FILE_NAME=checkstyle-${CHECKSTYLE_VERSION}-all.jar
-# checking /tmp for existance
+# checking /tmp for existence
TMPDIR=/tmp
if [ ! -d $TMPDIR ]
then
diff --git a/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/BaseCheckTestSupport.java b/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/BaseCheckTestSupport.java
deleted file mode 100644
index c2600f8004..0000000000
--- a/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/BaseCheckTestSupport.java
+++ /dev/null
@@ -1,185 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2016 the original author or authors.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-////////////////////////////////////////////////////////////////////////////////
-
-package com.github.sevntu.checkstyle;
-
-import static java.text.MessageFormat.format;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.URL;
-import java.util.List;
-import java.util.Locale;
-import java.util.Properties;
-
-import org.junit.Assert;
-
-import com.google.common.collect.Lists;
-import com.puppycrawl.tools.checkstyle.AuditEventUtFormatter;
-import com.puppycrawl.tools.checkstyle.Checker;
-import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
-import com.puppycrawl.tools.checkstyle.DefaultLogger;
-import com.puppycrawl.tools.checkstyle.TreeWalker;
-import com.puppycrawl.tools.checkstyle.api.AuditEvent;
-import com.puppycrawl.tools.checkstyle.api.Configuration;
-
-public abstract class BaseCheckTestSupport extends Assert {
- private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
- private final PrintStream printStream = new PrintStream(baos);
-
- public static DefaultConfiguration createCheckConfig(Class> clazz) {
- return new DefaultConfiguration(clazz.getName());
- }
-
- protected void verify(Configuration config, String fileName, String[] expected)
- throws Exception {
- verify(createChecker(config), fileName, fileName, expected);
- }
-
- protected void verify(Checker checker, String fileName, String[] expected) throws Exception {
- verify(checker, fileName, fileName, expected);
- }
-
- protected void verify(Checker checker, String processedFilename, String messageFileName,
- String[] aExpected) throws Exception {
- verify(checker, new File[] {new File(processedFilename)}, messageFileName, aExpected);
- }
-
- protected void verify(Checker checker, File[] processedFiles, String messageFileName,
- String[] expected) throws Exception {
- printStream.flush();
- final List