diff --git a/.travis.yml b/.travis.yml index a52bb4c806..684b34f79b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -dist: trusty -sudo: false addons: ssh_known_hosts: - web.sourceforge.net @@ -10,20 +8,39 @@ env: global: - secure: KBEuB6U1p5RQXSYe157AwydFr/zpXQPA0IChVCgZV+X1mMyy9ZtrjH1J1AXuviseDDXDbaT25sRnsvpl82rfRw2xOkMGXHy4N95/ylTSr8DjHxTao71BhXsvFycNobFva5y2EGNWqDvpS8I2oSZo7Qk4la3yep3rcJQvcy6RDbbhpDTbL1QMFyadunIBm0WtqbunrMqtjSqaoPsXz8TiQuxHvX4vEXzVbaxV1QQt79Vi+daa6wAV3mRQAugnx+UffsC8JqMxgm06usWeJgCJzxgm8E7clZCLmf53B2TL8dK6bIYbqyvOY3uFxitsTG0d8Z0GOJwXBgZNgbniTRO8ZJSty5eZP8LBybbjVLSL25DNTWtCjADUL/uySnXIEidlMt2N/3QmH7zrGAfAk/tIwKpdRca2GLLydeXf6PSkiahnPEkIY/QupcsOLELhdifpdOjb8QW1OenA+vUbNM9dccLwKnX6Fj9cu4VQG601AcYDr2eyhq8WYkr3wYdw/6KdUa3hmplowTBs+qguppP+eOSgGuEsy38KLtqnvm6WlHy6tcLmcVYKG3DmR1b7TWXsOXC6/VMH8BHBkvsF1QdRg9+Cgx07vX3Hw7roPiYzmaO9Ajs20ATsUfRskMuWCTeTSK5pN8X27veRCZlhFjeKQMDdmfVwzpAfRgKsl3TEn1I= - secure: U1DfAv6acUUWe+dao/ZSDUX64JRadNJY16rITsdrM4ZNAJSuXpEY3p/LWcYjN7D49YmyutbXH9+L3KKQUQGrGXj9QTarfYvd8ZsKt4FK8yv7AFy+RQNIbAjNEHBzHx15p+srMheTaetl7aLwY0qhF+D/RtGapxHKyY4dBHrb0lp8VGyiCiL7Aop8GGskosi1mtirPBp/BStPZ2bEyxG0QzU5SsVWkJWwV9aWLPVAR/n7Xgx/6Gjl6Fed2c/WSrWi4vchm3Ny8pfTweOax3PGYYjBVxIfuX0mqmwuJsY7gNfXCfN3dPiPKGJPFy1pC+LGyGkklO5ReKFLd4O1ME6fU0dlIGfD6n+Q4H6/w9FHXegcKTfWIJm/MFa6vA/tJM5R6zJQuiTQJboHm/UmS/iQj76z0p6sK15Xp5vFId+/dHKqa8xY+Bt6HiXy6z401HOc8QcYBAf7TqhqUt/ZE7HN4be46uR90KmzIrWz6wEoDW7HfwQ9ZMbs55zoOXrvekyE9/gXskypO0p2JT3Y0vlvO27KQvIrSwI480kOVOrlyrYA+LZqlcKaayOuCuZh4lITQUYinUoZZict5joYthH+Cyh2zovoBpxsntDJdMnaZNLtSC7hlhpbMBYaT2y1O6vZH5Yix0mxuDvs/x6ogP5CNBeUYlXhaL+g4GnwKyr0ZA0= - - secure: "ElWjttpoMwqezP2zyHkx7CiPON/mRLUW7SsSlEqdlTUYRIaSaL7sShUORJUzj58U/Nnfi/eY4Rweo0CtVu20sG16s9B4adnmPS44LAitztybPR/co93gN9qb8jiIl41nVcOJq+Rut2Z4nr8AGRhVCG9Drg4+DreCqQ4DE5ZD6J99GN0IFGrREt59HQUlBlT9jD0AndK/1GQ6kWAenuSREE2P5ih59rf6FrrfddQO5iqyFFoaHek3JiOmpaLK+z7i4EvMKsAJEooFNuGhHVuyaJJRRZHAncGiQ+uW/yL7G5rY51G6YSNJczzEtfrRg+YrIUbokUPmifSIbnXO/AIZRAq1dMhA8exRc5n+75RB1X164qm4a+yggdybFBh0L59xu606PJQJAuWy+x10nled7FAVXiotxbB0r2bhlVmWFEN+FWPqXg2rVkHvw6+5PM67rG5g1LCgjKzb9I6JWPiVI+EMn8Pw8gryL2Sdqtl08Da0Ypbl2ZK/afU4CEPEKnrDc9ecXKjacehTYwGS48V213XvArcmoEpsyZDRSMTrvK3/e29GEaxoK/ZzWJylpeOtsICEEFYEBEiDsiIW4C50MIUPT2xHV6MaPQzhkuwrbQ6QFYzHzihBaiQuMmXUQ4DMb3fOPkNZAQHQo8CgJ78IcbCABAoGv9mu/fo2KoLo11U=" + - secure: "gxI7W4V4fUPQLMCvecXXdet1/mCh6m0RIQMtErVVOnwxEEjeDmko/3rHSl+wk6IeFaaQKcmHJJSJEj+e5TgWRH1uuzCnbFHZhuH28ce/H0EqLJ3GTXeDEgFLzhh//T3ySOZChZELgJ67cKxZJNFMhBVOR2/QIGjZjdzvl36ugsu80Ak3XJb8HCm8D2P8Vuezz/OlCkSOGXaiqZXfflV/cuaLWuueGfQGW9x/UyDTNsuBdB7YnEcxOWt8RgB4JrcPGV7/etxLHXTw9IMEeUhQ/RsxLZHKNYt9cx/QOZkpXemhdT9L2pAIi77eO98x+yAfB1qV6T6IeDd/OiABUzfb7asNBwE+bYRuVkCiWLo3x3hs8FcgsPe4L10guxfRMJPxax9E7uYb9TFxtvc42dDWNyp1BVCtEtmjErO4CJeW97ukhgkUkPhzUZgQ2Gj5Tn4VRjQOQyzh/S/YsHyfxoAQrscc/3bq5PBmtdowyGQd5dsvShdpE6glf+HnBZ8TCw5BaxQuTjapQWjsGuJVCVsrNDtwOFy5UTfxK9OeTUsjwfO5JjkoIeqGyLHPnTMWyZ6EYa//nWPOU1KgVE6Hrzfr3zxEzL1nN/TYahzhKOxXE701W9YhTmhCVljMlSYioTUfTaXHgGLpojvSWlhsTbc3r0gj4NglqakIy7MKgQLgES8=" - secure: "otZkFNhApMofp2Jl2baZdpNEPcTa79Xc9wyOw1gl1+ubCLtOGr32FDUSr0HQWKrGXcYZR4bc0A80hx0/ykZ/twJaRAabcNYtjwRMDKKrp3plvp8RTZlB1QW85nsdmk3qmHACzc94wKnmcaDohM5FPxnWspZG5Y4ejYX4HEK6r1fwL4FjMPSLd5QW8yCaAc7dpBSm2UyIXuuDjkekXblJFe8ydbf9aF97WKJMCwqIs9Zo5oJa2pnWCw47ixwjVdkaH5x5727I+YmFqn5rjdEideUFEAlggqMaxuOtfYhuG/8k5W3Q/+WX+G7rEPTcemjmaosbbpoOUE0YUHV3Wi3R5D66NuWIpQwX6kw4rTwL0YIh//0aNb8jv4Z8KwkiTMrYuj0we5tXzARp3yYn56P0JBAm6BihNhfEBv06655Tg5LUsWqUTZCl3KJhwtO1N+OuOkE5qoZm59knq6DeZOsYWAVb3MpzklP06kXGYTjb44PVMUc6ynuuZjgPJDv/0906feA3REHBJVxd3PvJp1c8VvQSeW3ndghEz0akJHY/jxV1rJZAZC1ZeshYUpBNmh0sFDty/UE43IvIB4EInypQHyTtQvMc6LuLjTeu2E5ZMsA3udj66EMrYm4Y2eheJycSfttDqzhsKXIVJ4LmA/xtDR01cp1jsqbbZBhVI67rA40=" - secure: "mmHRnK/8CHfgtwaTN3MgjFD1R8EVQhIb/a0Aag3gPaHWW52Ex6xWG7GsF4kRcdzHdIdrQxHZTiDa2oVMWbnQ16CAu4dZJadwTxhBW4JmE1tsi2C6i+uwMBPvnKBXHwt+QOAqNB0L/ByYwWLkucSLoyRs6qU0i7sJ3ZC/EPCuLI8VfBlFUVegSbp2WmclmFnxOi5MKr15Zwd8BGgyWUsvd1OHxhvO3Xr/ZPO4R+1kIgyojloTMu6oGM/shYgsrUXgmI/WvZRTq+25SRCjUmATJtuDXXgVeJtYabi/+Zju5Z7K06oaKvFYM+BgZWPmGQkVCxKVjSlug0rx6+qgRKIf/B/cPxmQDS0ZZVDmDcbxeibBL9JhRqIDwDb0XS9t1qBXvIJ5E4ZmdX/XuvLCnC4xJptu/vHyKl1wbRM3dcXEBk8J0knJc4JvY2yupF3LS32sfEHftLwzr63U3/0dOQvsCSJRBy5zgI8ieABUZAeZmmaQ6RCGOTEYrGO2G4CCF2uVq4YdrCOsfmrb0DzH8llNMkXKzXlITRvmkuBlTRRKxGnPzS3vf0iicdAkmTiU5u7lArFFc7IKcW4ypO+RKDTUpq74K+UZBI9eBjV7Po368EO8epJ5aIx32a2kyS/hYWkS/dZh7I0fNZa2qBUceZO/KZGRjH4dQFW9t0J9Q7LLXJY=" - secure: "geOU/7VR83KYTOCR5XkgFqnHJEnXeB6hNDE7UFcN4ZsL9uVLhxlDVWV3ujJ87nyBzggG1KfSnUx11UwOQrbBl0K6sEXo/B2q5ytOsWoSLi7+0qm/uhhw/DTBOq57p8TIDKFM7rDhO7uajSn7Y86LeZkh9wIs5265Fh1yhCkiPbczDUMsX4P0GGg2qgkIKSBw4DZf6sPDc4xjJq/4/cLnjXo/K0ZYAIoSLqDfe1gmkzMtQlad+1t8Lwv/gOJ4BNRF4a5aEvGF6kbFovFoeFWCQTKlkn6VJtY+BETGKW2RH9efGeMs7JbBbNm+nnpoNsbJ0gdmGlhSbWT8enIm72/P0ThTBJWVcLJ30tUd0UeYD9C49wbJ3RHSxsoUKP9YhHJ+XKNx+8irkJ8LPCkNMQEFE153gEVvU7tCgah9Uq6laYZv9cQE0dWzNt3//Ymls8BzY38Ha4PbrIIJqEuWwnAX6ZgTgzVtXx1AJjkDFG9KFKPhN7NfNMbh7rn5C84a1h5zrIydm+6RcIBC+xTLDEiN7djiquf3PcNtyGLcO8dNN4Uv8iU0Jw8ch3+w0PJO53v5py+IS1V8pwwYaYF2iVPOoziS0tP8MsgYVGwpTZhvz3v8x0ge8r6KJE4zdvoPtCRNr2Oo3sJGYqkt86Hu6agKFiljP5AgJNx7iQD5GQn6J3w=" - secure: "gqyPF3d75JuwZptnQQQKO6rGUILXGO09y9dZhShdX8qq5Mexa2ISk77Y/b0yyAdhJMgEglls5cWlbHkwCAB0i4yL25RE5CtQUe4er+CIKwBIs0M56ghbcOwWAFB/cXeyyWmXDHBVnVUeKm7IJ34txsEclnMzQSR/DInSzsCFMUQok8HEaWZNssMjyRgo6goKGdG5vNWGfLLY7mKGMe/6PpYJD0G8k+Na08aX06ZWph38He8O3imUAngoQrxiSp0UYmnHDkigbV7S2LdZOsj7kMxkiyigzK/P1eygHVbFAhohLroaqS9B4CBK7QeOyup2vxVKqJVzFwOCylD0786CImvaG2ZYMtvJkapvaEE0mdMlyYpHgdIkmHZu28aMW7hXEhxHyBAxKuPcj5eGCGziO+ztCvfYIA9CGs1uA4KLrED7SahvB0oXnt3KTFdRc857cWcpp2NmRKihLzVdgHlmT8zcYaec3zP1VdMoa2bmLHoaZtAwvMTcAG56FcET1p7f9v+uiU88ZeptEjTJfpAWlq34tpwZXNyIQi5IROocSHM+PKTgLAsAMP5klGascr8E0sEzREl7tg8hqEwXKym/sVKyT+HMptA3UZcrZZhm07/cmQ0pUVvbV9QDb0MzU3O2wF7vT3U7R7Fb1u0LxMjblPyEazTp8ldabVRJREwlsDc=" - - secure: "JIhuqaI0i+zvuqqXiQBHpuKr7AQ8jfk6Gbr8Qgiq4yJtdEWXZGxnAT9BmlbjkgT7ABXvLgxf2CIdUOMo1yYfBlxQL/y5+e89jaVpYF3tvNAzYQ1e12VzQRsd/jDb7qvm7tw3rDHEn3dSEot7Q6KbPcL6WzWJINVMCCmOgvq9gKHgE6Y5q5EgZ5rxiXyuO27ndzcbxaor4PIaiSzHO9+AJQ7p2zDLP+kG4nKVTBX0l9VoKiYFhIpIhpbigi3jyLDMDRiWpwTWZC6P8/RXfZg/lc5ADOuM2DM8oXPpZuqOa/g31LWQOSCuEnQ1G16vbLgipSPpgAc7jYWD5cywhG9dLkiKaZDh5x0meLM2RoAgz6eAnQfTTqJ68OM9o9yXjubEedsNpNRAr9/DXMd+fbh10W2vbvL5HCNB3lic3anehhR9le7PLuEKxg654wXt3KM2PZGVWbotIyBK0CvGzqGkppvwT23QdDDqSdkWuGQIhGQ0xBOdYkwebycxP5wwPUmObG+mymQ1Be2BXvmghttsiJdKlt4CVSYOJUMus6kU32G95hdTgKblsX4J1Of2i1nYsjyMKh3k945tqXwQrIsxOOQug0oIkz24zlLaOaQcorWtJ6Y1HPaZKpVIFUEF0y8Uq/O4oB2bOYC6WDUQfpj7nRG6xbi+BeBS84m1ttCEk4g=" - matrix: - - BUILD=deploy - - BUILD=doc - - BUILD=sonar - - BUILD=coveralls + - secure: "VezxV+VdmbmtrQYT8AZIyg41WBROxuxpumerkcubADF7V4wV6lwx9Rd2G6yAr0VuHCNUUhS4m+gPFIsuiQbAhyupiEkwhzUYqk1tF+LITlLLPegLypjiLmhJMwGUNuDSSsih1Icmg9FzrP4VyzgGn9pBjoG9QYj1civBZeGwg++e/XDYlHMXrpd/UEfMKVB71JwB0tle4fKJZSvblIqP62yvbBaKHx6A4+ZWzJV5Vps0DoIeNtKCNmNNloKZVHfjbsvqSjnMYUJzkOzyPkM822q41N/D+3IAufO16+jH/W0vAZeN0e4GXiN5W+CVkr2Gbh0FwkVQcI3bekaOIn45XLUMLKdf+JsWDPKz9RraHelR9YxL5GoJ7ntwvmucxw0p8EVyJ/xLk/pBCP8iHq0Jb8//js25XHgxzzAWI37MErPAAGgTKZAVdAN0mGXbe63tWmwaBlEbK8h2A8di6abW5x6YHTkTo2BRlHUSTU8dE3VqTnpSkne5n1SlEa4g1Bci3J45M0/pLmHV6yCxCM5BrVXS5ByaB61py/umSbpmdIBFV6TM1MaKK3lAucQrR+8To/vCbm8XqPyujJdOR+ENIuuDgEU/Yh5Hv5SAODekUYaCp4pjfGzFADHQWVNDxIOXrwBN4OfSiAvRc1x6HXndOmNI4QtOxheuCRFFthq8VZI=" matrix: fast_finish: true + include: + - name: "linux - mvn deploy" + os: linux + dist: trusty + sudo: false + env: BUILD=deploy + - name: "linux - build documentation" + os: linux + dist: trusty + sudo: false + env: BUILD=doc + - name: "linux - run sonar" + os: linux + dist: trusty + sudo: false + env: BUILD=sonar + - name: "linux - run coveralls" + os: linux + dist: trusty + sudo: false + env: BUILD=coveralls + - name: "macosx - mvn verify" + os: osx + env: BUILD=deploy before_install: - wget https://github.com/sormuras/bach/raw/master/install-jdk.sh @@ -31,10 +48,11 @@ before_install: - bash .travis/configure-maven.sh - rvm install 2.4.1 - rvm use 2.4.1 -# Install OracleJDK 10 - see https://sormuras.github.io/blog/2018-03-20-jdk-matrix.html +# Install OpenJDK 11 - see https://sormuras.github.io/blog/2018-03-20-jdk-matrix.html install: - - . ./install-jdk.sh -F 10 -L BCL - - bundle install --without=release_notes_preprocessing + - . ./install-jdk.sh -F 11 -L GPL -W $HOME/jdk + - gem install bundler + - bundle install --with=release_notes_preprocessing before_script: true script: source .travis/build-$BUILD.sh after_success: true @@ -72,7 +90,8 @@ cache: directories: - "$HOME/.m2" - vendor/bundle - + - "$HOME/jdk" + - "$HOME/.rvm/" # Secure Keys, that need to be set for snapshot builds # diff --git a/.travis/build-coveralls.sh b/.travis/build-coveralls.sh index 7af296cd85..b58629a5fa 100755 --- a/.travis/build-coveralls.sh +++ b/.travis/build-coveralls.sh @@ -4,7 +4,7 @@ set -e source .travis/logger.sh source .travis/common-functions.sh -VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec | tail -1) +VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec) log_info "Building PMD Coveralls.io report ${VERSION} on branch ${TRAVIS_BRANCH}" if ! travis_isPush; then @@ -12,17 +12,12 @@ if ! travis_isPush; then exit 0 fi -# -# for java9: enable all modules. -# coveralls plugin seems to need java.xml.bind module -echo "MAVEN_OPTS='-Xms1g -Xmx1g --add-modules java.se.ee'" > ${HOME}/.mavenrc - ( # disable fast fail, exit immediately, in this subshell set +e ./mvnw clean install -DskipTests=true -Dmaven.javadoc.skip=true -B -V - ./mvnw test jacoco:report coveralls:report -Pcoveralls -B -V + ./mvnw package jacoco:report coveralls:report -Pcoveralls -B -V if [ $? -ne 0 ]; then log_error "Error creating coveralls report" diff --git a/.travis/build-deploy.sh b/.travis/build-deploy.sh index bad3f4eb92..fac52a56f8 100755 --- a/.travis/build-deploy.sh +++ b/.travis/build-deploy.sh @@ -48,7 +48,12 @@ log_info "Building PMD ${VERSION} on branch ${TRAVIS_BRANCH}" MVN_BUILD_FLAGS="-B -V" -if travis_isPullRequest; then +if travis_isOSX; then + + log_info "The build is running on OSX" + ./mvnw verify $MVN_BUILD_FLAGS + +elif travis_isPullRequest; then log_info "This is a pull-request build" ./mvnw verify $MVN_BUILD_FLAGS @@ -90,13 +95,35 @@ elif travis_isPush; then else log_success "Successfully uploaded pmd-*-${VERSION}.zip to sourceforge" fi - rsync -avh docs/pages/release_notes.md ${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/pmd/${VERSION}/ReadMe.md - if [ $? -ne 0 ]; then + + ) + + ( # UPLOAD RELEASE NOTES TO SOURCEFORGE + + # This handler is called if any command fails + function release_notes_fail() { log_error "Error while uploading release_notes.md as ReadMe.md to sourceforge!" log_error "Please upload manually: https://sourceforge.net/projects/pmd/files/pmd/" - else - log_success "Successfully uploaded release_notes.md as ReadMe.md to sourceforge" - fi + } + + # exit subshell after trap + set -e + trap release_notes_fail ERR + + RELEASE_NOTES_TMP=$(mktemp -t) + + .travis/render_release_notes.rb docs/pages/release_notes.md | tail -n +6 > "$RELEASE_NOTES_TMP" + + rsync -avh "$RELEASE_NOTES_TMP" ${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/pmd/${VERSION}/ReadMe.md + + log_success "Successfully uploaded release_notes.md as ReadMe.md to sourceforge" + + ) + + + ( + # disable fast fail, exit immediately, in this subshell + set +e upload_baseline diff --git a/.travis/build-doc.sh b/.travis/build-doc.sh index f340a42c61..e4ec9c9a9b 100755 --- a/.travis/build-doc.sh +++ b/.travis/build-doc.sh @@ -4,7 +4,7 @@ set -e source .travis/logger.sh source .travis/common-functions.sh -VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec | tail -1) +VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec) log_info "Building PMD Documentation ${VERSION} on branch ${TRAVIS_BRANCH}" if ! travis_isPush; then diff --git a/.travis/build-sonar.sh b/.travis/build-sonar.sh index e880f11d4d..7e51aaf46d 100755 --- a/.travis/build-sonar.sh +++ b/.travis/build-sonar.sh @@ -4,7 +4,7 @@ set -e source .travis/logger.sh source .travis/common-functions.sh -VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec | tail -1) +VERSION=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec) log_info "Building PMD Sonar ${VERSION} on branch ${TRAVIS_BRANCH}" if ! travis_isPush; then @@ -12,17 +12,17 @@ if ! travis_isPush; then exit 0 fi -# -# for java9: enable all modules. -# sonar plugin seems to need java.xml.bind module -echo "MAVEN_OPTS='-Xms1g -Xmx1g --add-modules java.se.ee'" > ${HOME}/.mavenrc - ( + # for sonar, we need to use java10, until sonarjava 5.8.0 is released (Sept. 2018) + JAVA_HOME=$(bash ./install-jdk.sh -F 10 -L GPL -W $HOME/jdk --emit-java-home | tail --lines 1) + export JAVA_HOME + export PATH=${JAVA_HOME}/bin:$PATH + # disable fast fail, exit immediately, in this subshell set +e # Run the build - ./mvnw clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -B -V + ./mvnw clean package sonar:sonar -Dsonar.login=${SONAR_TOKEN} -Psonar -B -V if [ $? -ne 0 ]; then log_error "Error updating sonar..." diff --git a/.travis/common-functions.sh b/.travis/common-functions.sh index 7c4742b5bd..887d15b759 100755 --- a/.travis/common-functions.sh +++ b/.travis/common-functions.sh @@ -10,6 +10,7 @@ echo "TRAVIS_SECURE_ENV_VARS: ${TRAVIS_SECURE_ENV_VARS}" echo "TRAVIS_BRANCH: ${TRAVIS_BRANCH}" echo "TRAVIS_TAG: ${TRAVIS_TAG}" echo "TRAVIS_ALLOW_FAILURE: ${TRAVIS_ALLOW_FAILURE}" +echo "TRAVIS_OS_NAME: ${TRAVIS_OS_NAME}" function travis_isPullRequest() { if [ "${TRAVIS_REPO_SLUG}" != "pmd/pmd" ] || [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then @@ -27,6 +28,14 @@ function travis_isPush() { fi } +function travis_isOSX() { + if [[ $TRAVIS_OS_NAME == 'osx' ]]; then + return 0 + else + return 1 + fi +} + function has_docs_change() { if [[ $(git diff --name-only ${TRAVIS_COMMIT_RANGE}) = *"docs/"* ]]; then log_info "Checking for changes in docs/ (TRAVIS_COMMIT_RANGE=${TRAVIS_COMMIT_RANGE}): changes found" diff --git a/.travis/release.sh b/.travis/release.sh index 883f9721d4..2565125c88 100755 --- a/.travis/release.sh +++ b/.travis/release.sh @@ -28,9 +28,6 @@ if [ "${BUILD}" = "deploy" ]; then true ) -# install the gems required for rendering the release notes -bundle install --with=release_notes_preprocessing - # renders, and skips the first 6 lines - the Jekyll front-matter RENDERED_RELEASE_NOTES=$(bundle exec .travis/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) diff --git a/.travis/render_release_notes.rb b/.travis/render_release_notes.rb index d8acab0e74..dc0eb0877d 100755 --- a/.travis/render_release_notes.rb +++ b/.travis/render_release_notes.rb @@ -13,6 +13,7 @@ require "safe_yaml" # include some custom liquid extensions require_relative "../docs/_plugins/rule_tag" +require_relative "../docs/_plugins/tocmaker_block" require_relative "../docs/_plugins/custom_filters" # explicitly setting safe mode to get rid of the warning diff --git a/.travis/travis-settings.xml b/.travis/travis-settings.xml index 20ca3d60c8..d3c3c6446c 100644 --- a/.travis/travis-settings.xml +++ b/.travis/travis-settings.xml @@ -6,7 +6,9 @@ - + + org.sonarsource.scanner.maven + ossrh diff --git a/BUILDING.md b/BUILDING.md index 78865d329f..b148affeab 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1,7 +1,8 @@ # How to build PMD -PMD uses [Maven](https://maven.apache.org/) and requires [Java 9](http://www.oracle.com/technetwork/java/javase/downloads/index.html) -for building. +PMD uses [Maven](https://maven.apache.org/) and requires at least Java 10 for building. +You can get Java 10 from [Oracle](http://www.oracle.com/technetwork/java/javase/downloads/index.html) +or from the [OpenJDK Project](http://jdk.java.net). PMD uses the [maven wrapper](https://github.com/takari/maven-wrapper), so you can simply build PMD as following: diff --git a/Gemfile b/Gemfile index ed76d93bfe..4894455d47 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,9 @@ source 'https://rubygems.org/' gem 'pmdtester', '~> 1.0.0.pre.beta3' gem 'danger', '~> 5.6', '>= 5.6' -# This group is only needed during release (via .travis/release.sh and do-release.sh) +# This group is only needed for rendering release notes +# this happens during release (.travis/release.sh and do-release.sh) +# but also during regular builds (.travis/build-deploy.sh) group :release_notes_preprocessing do gem 'liquid', '>=4.0.0' gem 'safe_yaml', '>=1.0' diff --git a/do-release.sh b/do-release.sh index 5417ffd455..38aab524e3 100755 --- a/do-release.sh +++ b/do-release.sh @@ -1,7 +1,7 @@ #!/bin/bash # Make sure, everything is English... -export LANG=C.UTF8 +export LANG=C.UTF-8 # verify the current directory if [ ! -f pom.xml -o ! -d ../pmd.github.io ]; then @@ -62,15 +62,19 @@ echo "Press enter to continue..." read -# install bundles needed for rendering release notes -bundle install with=release_notes_preprocessing --path vendor/bundle - - export RELEASE_VERSION export DEVELOPMENT_VERSION export CURRENT_BRANCH + +# install bundles needed for rendering release notes +bundle install --with=release_notes_preprocessing --path vendor/bundle + RELEASE_RULESET="pmd-core/src/main/resources/rulesets/releases/${RELEASE_VERSION//\./}.xml" +export RELEASE_NOTES_POST="_posts/$(date -u +%Y-%m-%d)-PMD-${RELEASE_VERSION}.md" +echo "Generating ../pmd.github.io/${RELEASE_NOTES_POST}..." +NEW_RELEASE_NOTES=$(bundle exec .travis/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) +echo "${NEW_RELEASE_NOTES}" > ../pmd.github.io/${RELEASE_NOTES_POST} echo "* Update date info in **docs/_config.yml**." echo " date: $(date -u +%d-%B-%Y)" @@ -80,8 +84,6 @@ echo " ${RELEASE_RULESET}" echo echo "* Update **../pmd.github.io/_config.yml** to mention the new release" echo -echo "* Add **../pmd.github.io/_posts/$(date -u +%Y-%m-%d)-PMD-${RELEASE_VERSION}.md" -echo echo "Press enter to continue..." read echo "Committing current changes (pmd)" @@ -95,7 +97,7 @@ git commit -a -m "Prepare pmd release ${RELEASE_VERSION}" ( echo "Committing current changes (pmd.github.io)" cd ../pmd.github.io - git add _posts/$(date -u +%Y-%m-%d)-PMD-${RELEASE_VERSION}.md + git add ${RELEASE_NOTES_POST} git commit -a -m "Prepare pmd release ${RELEASE_VERSION}" git push ) @@ -117,7 +119,6 @@ echo echo "Check the milestone on github:" echo "" echo " --> move any open issues to the next milestone, close the current milestone" -echo " --> Maybe there are some milestones on sourceforge, too: ." echo echo echo "Prepare Next development version:" @@ -129,7 +130,6 @@ read # update release_notes_old OLD_RELEASE_NOTES=$(tail -n +8 docs/pages/release_notes_old.md) -NEW_RELEASE_NOTES=$(bundle exec .travis/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) echo "$(head -n 7 docs/pages/release_notes_old.md)" > docs/pages/release_notes_old.md echo "$NEW_RELEASE_NOTES" >> docs/pages/release_notes_old.md echo >> docs/pages/release_notes_old.md @@ -143,18 +143,13 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- -## {{ site.pmd.date }} - {{ site.pmd.version | append_unless: is_release_version, "-SNAPSHOT" }} +## {{ site.pmd.date }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. This is a {{ site.pmd.release_type }} release. -### Table Of Contents - -* [New and noteworthy](#new-and-noteworthy) -* [Fixed Issues](#fixed-issues) -* [API Changes](#api-changes) -* [External Contributions](#external-contributions) +{% tocmaker is_release_notes_processor %} ### New and noteworthy @@ -164,6 +159,8 @@ This is a {{ site.pmd.release_type }} release. ### External Contributions +{% endtocmaker %} + EOF git commit -a -m "Prepare next development version" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index a8204adfd9..8edebbb121 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -13,10 +13,11 @@ GEM execjs coffee-script-source (1.11.1) colorator (1.1.0) - commonmarker (0.17.9) + commonmarker (0.17.11) ruby-enum (~> 0.5) concurrent-ruby (1.0.5) - dnsruby (1.60.2) + dnsruby (1.61.2) + addressable (~> 2.5) em-websocket (0.5.1) eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) @@ -26,29 +27,29 @@ GEM execjs (2.7.0) faraday (0.15.2) multipart-post (>= 1.2, < 3) - ffi (1.9.23) + ffi (1.9.25) forwardable-extended (2.6.0) gemoji (3.0.0) - github-pages (186) + github-pages (191) activesupport (= 4.2.10) github-pages-health-check (= 1.8.1) jekyll (= 3.7.3) - jekyll-avatar (= 0.5.0) + jekyll-avatar (= 0.6.0) jekyll-coffeescript (= 1.1.1) jekyll-commonmark-ghpages (= 0.1.5) jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.9.3) + jekyll-feed (= 0.10.0) jekyll-gist (= 1.5.0) jekyll-github-metadata (= 2.9.4) - jekyll-mentions (= 1.3.0) + jekyll-mentions (= 1.4.1) jekyll-optional-front-matter (= 0.3.0) jekyll-paginate (= 1.1.0) jekyll-readme-index (= 0.2.0) - jekyll-redirect-from (= 0.13.0) + jekyll-redirect-from (= 0.14.0) jekyll-relative-links (= 0.5.3) jekyll-remote-theme (= 0.3.1) jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.4.0) + jekyll-seo-tag (= 2.5.0) jekyll-sitemap (= 1.2.0) jekyll-swiss (= 0.4.0) jekyll-theme-architect (= 0.1.1) @@ -65,12 +66,12 @@ GEM jekyll-theme-tactile (= 0.1.1) jekyll-theme-time-machine (= 0.1.1) jekyll-titles-from-headings (= 0.5.1) - jemoji (= 0.9.0) - kramdown (= 1.16.2) + jemoji (= 0.10.1) + kramdown (= 1.17.0) liquid (= 4.0.0) listen (= 3.1.5) mercenary (~> 0.3) - minima (= 2.4.1) + minima (= 2.5.0) nokogiri (>= 1.8.2, < 2.0) rouge (= 2.2.1) terminal-table (~> 1.4) @@ -80,7 +81,7 @@ GEM octokit (~> 4.0) public_suffix (~> 2.0) typhoeus (~> 1.3) - html-pipeline (2.8.0) + html-pipeline (2.8.4) activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.6.0) @@ -99,7 +100,7 @@ GEM pathutil (~> 0.9) rouge (>= 1.7, < 4) safe_yaml (~> 1.0) - jekyll-avatar (0.5.0) + jekyll-avatar (0.6.0) jekyll (~> 3.0) jekyll-coffeescript (1.1.1) coffee-script (~> 2.2) @@ -113,15 +114,14 @@ GEM rouge (~> 2) jekyll-default-layout (0.1.4) jekyll (~> 3.0) - jekyll-feed (0.9.3) + jekyll-feed (0.10.0) jekyll (~> 3.3) jekyll-gist (1.5.0) octokit (~> 4.2) jekyll-github-metadata (2.9.4) jekyll (~> 3.1) octokit (~> 4.0, != 4.4.0) - jekyll-mentions (1.3.0) - activesupport (~> 4.0) + jekyll-mentions (1.4.1) html-pipeline (~> 2.3) jekyll (~> 3.0) jekyll-optional-front-matter (0.3.0) @@ -129,7 +129,7 @@ GEM jekyll-paginate (1.1.0) jekyll-readme-index (0.2.0) jekyll (~> 3.0) - jekyll-redirect-from (0.13.0) + jekyll-redirect-from (0.14.0) jekyll (~> 3.3) jekyll-relative-links (0.5.3) jekyll (~> 3.3) @@ -138,7 +138,7 @@ GEM rubyzip (>= 1.2.1, < 3.0) jekyll-sass-converter (1.5.2) sass (~> 3.4) - jekyll-seo-tag (2.4.0) + jekyll-seo-tag (2.5.0) jekyll (~> 3.3) jekyll-sitemap (1.2.0) jekyll (~> 3.3) @@ -187,12 +187,11 @@ GEM jekyll (~> 3.3) jekyll-watch (2.0.0) listen (~> 3.0) - jemoji (0.9.0) - activesupport (~> 4.0, >= 4.2.9) + jemoji (0.10.1) gemoji (~> 3.0) html-pipeline (~> 2.2) jekyll (~> 3.0) - kramdown (1.16.2) + kramdown (1.17.0) liquid (4.0.0) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) @@ -200,15 +199,15 @@ GEM ruby_dep (~> 1.2) mercenary (0.3.6) mini_portile2 (2.3.0) - minima (2.4.1) + minima (2.5.0) jekyll (~> 3.5) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.11.3) multipart-post (2.0.0) - nokogiri (1.8.2) + nokogiri (1.8.4) mini_portile2 (~> 2.3.0) - octokit (4.9.0) + octokit (4.11.0) sawyer (~> 0.8.0, >= 0.5.3) pathutil (0.16.1) forwardable-extended (~> 2.6) @@ -220,9 +219,9 @@ GEM ruby-enum (0.7.2) i18n ruby_dep (1.5.0) - rubyzip (1.2.1) + rubyzip (1.2.2) safe_yaml (1.0.4) - sass (3.5.6) + sass (3.5.7) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) @@ -237,7 +236,7 @@ GEM ethon (>= 0.9.0) tzinfo (1.2.5) thread_safe (~> 0.1) - unicode-display_width (1.3.3) + unicode-display_width (1.4.0) PLATFORMS ruby diff --git a/docs/_config.yml b/docs/_config.yml index 86838109bd..aa5028435f 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,8 +1,8 @@ repository: pmd/pmd pmd: - version: 6.7.0 - date: 2018-??-?? + version: 6.8.0 + date: ??-??-2018 release_type: minor output: web diff --git a/docs/_plugins/tocmaker_block.rb b/docs/_plugins/tocmaker_block.rb new file mode 100644 index 0000000000..990d02e7a8 --- /dev/null +++ b/docs/_plugins/tocmaker_block.rb @@ -0,0 +1,60 @@ +# Generates a table of contents based on markdown headers in the body +# +# The block has 2 optional args: +# * A variable name. If provided, the toc will only be generated if the var is true +# * An integer, describing the maximum depth at which headers are added to the toc + +class TocMakerBlock < Liquid::Block + + def initialize(tag_name, arg, tokens) + super + + condition, depth = arg.split + + @max_depth = depth.to_s.empty? ? 100 : depth.to_i + @condition_var = condition.strip unless condition.to_s.empty? + + @body = tokens + end + + def to_internal_link(header) + url = header.downcase.gsub(/\s+/, "-") + + "[#{header}](##{url})" + end + + def render(context) + + contents = @body.render(context) + + if @condition_var && !context[@condition_var] + # If the condition is false, the toc is not generated + return contents + end + + headers = contents.lines.map {|l| + if /^(#+)\s+(\S.*)$/ =~ l + [$1.length, $2] + end + }.compact + + min_indent = headers.map {|t| t[0]}.min + + headers = headers.map {|t| + actual_depth = t[0] - min_indent + if actual_depth < @max_depth then + + indent = " " * actual_depth + + "#{indent}* #{to_internal_link(t[1])}" + end + }.compact + + headers.unshift("### Table Of Contents\n") + + headers.join("\n") + contents + end +end + + +Liquid::Template.register_tag('tocmaker', TocMakerBlock) diff --git a/docs/pages/pmd/devdocs/building.md b/docs/pages/pmd/devdocs/building.md index 90ca2caf60..c76ed1db04 100644 --- a/docs/pages/pmd/devdocs/building.md +++ b/docs/pages/pmd/devdocs/building.md @@ -10,10 +10,9 @@ author: Tom Copeland, Xavier Le Vourch # Compiling PMD -* JDK 9 or higher -* [Apache Maven](http://maven.apache.org) 3 or later. +* JDK 10 or higher -{% include note.html content="While Java 9 is required for building, running PMD only requires Java 7 (or Java 8 for Apex)." %} +{% include note.html content="While Java 10 is required for building, running PMD only requires Java 7 (or Java 8 for Apex and the Designer)." %} You’ll need to either check out the source code or download the latest source release. Assuming you’ve got the latest source release, unzip it to a directory: diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 5800289cac..4800ca41fc 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -145,18 +145,13 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- -## {{ site.pmd.date }} - {{ site.pmd.version | append_unless: is_release_version, "-SNAPSHOT" }} +## {{ site.pmd.date }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. This is a {{ site.pmd.release_type }} release. -### Table Of Contents - -* [New and noteworthy](#new-and-noteworthy) -* [Fixed Issues](#fixed-issues) -* [API Changes](#api-changes) -* [External Contributions](#external-contributions) +{% tocmaker %} ### New and noteworthy @@ -166,6 +161,8 @@ This is a {{ site.pmd.release_type }} release. ### External Contributions +{% endtocmaker %} + ``` {%endraw%} diff --git a/docs/pages/pmd/rules/apex.md b/docs/pages/pmd/rules/apex.md index 3026c4ae17..7d1e5a2bc0 100644 --- a/docs/pages/pmd/rules/apex.md +++ b/docs/pages/pmd/rules/apex.md @@ -24,6 +24,7 @@ folder: pmd/rules * [IfElseStmtsMustUseBraces](pmd_rules_apex_codestyle.html#ifelsestmtsmustusebraces): Avoid using if..else statements without using surrounding braces. If the code formattingor indent... * [IfStmtsMustUseBraces](pmd_rules_apex_codestyle.html#ifstmtsmustusebraces): Avoid using if statements without using braces to surround the code block. If the codeformatting ... * [MethodNamingConventions](pmd_rules_apex_codestyle.html#methodnamingconventions): Method names should always begin with a lower case character, and should not contain underscores. +* [OneDeclarationPerLine](pmd_rules_apex_codestyle.html#onedeclarationperline): Apex allows the use of several variables declaration of the same type on one line. However, itcan... * [VariableNamingConventions](pmd_rules_apex_codestyle.html#variablenamingconventions): A variable naming conventions rule - customize this to your liking. Currently, itchecks for fina... * [WhileLoopsMustUseBraces](pmd_rules_apex_codestyle.html#whileloopsmustusebraces): Avoid using 'while' statements without using braces to surround the code block. If the codeformat... @@ -112,7 +113,7 @@ folder: pmd/rules It contains the following rules: - [ApexBadCrypto](pmd_rules_apex_security.html#apexbadcrypto), [ApexCRUDViolation](pmd_rules_apex_security.html#apexcrudviolation), [ApexCSRF](pmd_rules_apex_security.html#apexcsrf), [ApexDangerousMethods](pmd_rules_apex_security.html#apexdangerousmethods), [ApexInsecureEndpoint](pmd_rules_apex_security.html#apexinsecureendpoint), [ApexOpenRedirect](pmd_rules_apex_security.html#apexopenredirect), [ApexSharingViolations](pmd_rules_apex_security.html#apexsharingviolations), [ApexSOQLInjection](pmd_rules_apex_security.html#apexsoqlinjection), [ApexSuggestUsingNamedCred](pmd_rules_apex_security.html#apexsuggestusingnamedcred), [ApexUnitTestClassShouldHaveAsserts](pmd_rules_apex_bestpractices.html#apexunittestclassshouldhaveasserts), [ApexUnitTestShouldNotUseSeeAllDataTrue](pmd_rules_apex_bestpractices.html#apexunittestshouldnotuseseealldatatrue), [ApexXSSFromEscapeFalse](pmd_rules_apex_security.html#apexxssfromescapefalse), [ApexXSSFromURLParam](pmd_rules_apex_security.html#apexxssfromurlparam), [AvoidDeeplyNestedIfStmts](pmd_rules_apex_design.html#avoiddeeplynestedifstmts), [AvoidDirectAccessTriggerMap](pmd_rules_apex_errorprone.html#avoiddirectaccesstriggermap), [AvoidDmlStatementsInLoops](pmd_rules_apex_performance.html#avoiddmlstatementsinloops), [AvoidGlobalModifier](pmd_rules_apex_bestpractices.html#avoidglobalmodifier), [AvoidHardcodingId](pmd_rules_apex_errorprone.html#avoidhardcodingid), [AvoidLogicInTrigger](pmd_rules_apex_bestpractices.html#avoidlogicintrigger), [AvoidNonExistentAnnotations](pmd_rules_apex_errorprone.html#avoidnonexistentannotations), [AvoidSoqlInLoops](pmd_rules_apex_performance.html#avoidsoqlinloops), [AvoidSoslInLoops](pmd_rules_apex_performance.html#avoidsoslinloops), [ClassNamingConventions](pmd_rules_apex_codestyle.html#classnamingconventions), [CyclomaticComplexity](pmd_rules_apex_design.html#cyclomaticcomplexity), [EmptyCatchBlock](pmd_rules_apex_errorprone.html#emptycatchblock), [EmptyIfStmt](pmd_rules_apex_errorprone.html#emptyifstmt), [EmptyStatementBlock](pmd_rules_apex_errorprone.html#emptystatementblock), [EmptyTryOrFinallyBlock](pmd_rules_apex_errorprone.html#emptytryorfinallyblock), [EmptyWhileStmt](pmd_rules_apex_errorprone.html#emptywhilestmt), [ExcessiveClassLength](pmd_rules_apex_design.html#excessiveclasslength), [ExcessiveParameterList](pmd_rules_apex_design.html#excessiveparameterlist), [ExcessivePublicCount](pmd_rules_apex_design.html#excessivepubliccount), [ForLoopsMustUseBraces](pmd_rules_apex_codestyle.html#forloopsmustusebraces), [IfElseStmtsMustUseBraces](pmd_rules_apex_codestyle.html#ifelsestmtsmustusebraces), [IfStmtsMustUseBraces](pmd_rules_apex_codestyle.html#ifstmtsmustusebraces), [MethodNamingConventions](pmd_rules_apex_codestyle.html#methodnamingconventions), [MethodWithSameNameAsEnclosingClass](pmd_rules_apex_errorprone.html#methodwithsamenameasenclosingclass), [NcssConstructorCount](pmd_rules_apex_design.html#ncssconstructorcount), [NcssMethodCount](pmd_rules_apex_design.html#ncssmethodcount), [NcssTypeCount](pmd_rules_apex_design.html#ncsstypecount), [StdCyclomaticComplexity](pmd_rules_apex_design.html#stdcyclomaticcomplexity), [TooManyFields](pmd_rules_apex_design.html#toomanyfields), [VariableNamingConventions](pmd_rules_apex_codestyle.html#variablenamingconventions), [WhileLoopsMustUseBraces](pmd_rules_apex_codestyle.html#whileloopsmustusebraces) + [ApexBadCrypto](pmd_rules_apex_security.html#apexbadcrypto), [ApexCRUDViolation](pmd_rules_apex_security.html#apexcrudviolation), [ApexCSRF](pmd_rules_apex_security.html#apexcsrf), [ApexDangerousMethods](pmd_rules_apex_security.html#apexdangerousmethods), [ApexInsecureEndpoint](pmd_rules_apex_security.html#apexinsecureendpoint), [ApexOpenRedirect](pmd_rules_apex_security.html#apexopenredirect), [ApexSharingViolations](pmd_rules_apex_security.html#apexsharingviolations), [ApexSOQLInjection](pmd_rules_apex_security.html#apexsoqlinjection), [ApexSuggestUsingNamedCred](pmd_rules_apex_security.html#apexsuggestusingnamedcred), [ApexUnitTestClassShouldHaveAsserts](pmd_rules_apex_bestpractices.html#apexunittestclassshouldhaveasserts), [ApexUnitTestShouldNotUseSeeAllDataTrue](pmd_rules_apex_bestpractices.html#apexunittestshouldnotuseseealldatatrue), [ApexXSSFromEscapeFalse](pmd_rules_apex_security.html#apexxssfromescapefalse), [ApexXSSFromURLParam](pmd_rules_apex_security.html#apexxssfromurlparam), [AvoidDeeplyNestedIfStmts](pmd_rules_apex_design.html#avoiddeeplynestedifstmts), [AvoidDirectAccessTriggerMap](pmd_rules_apex_errorprone.html#avoiddirectaccesstriggermap), [AvoidDmlStatementsInLoops](pmd_rules_apex_performance.html#avoiddmlstatementsinloops), [AvoidGlobalModifier](pmd_rules_apex_bestpractices.html#avoidglobalmodifier), [AvoidHardcodingId](pmd_rules_apex_errorprone.html#avoidhardcodingid), [AvoidLogicInTrigger](pmd_rules_apex_bestpractices.html#avoidlogicintrigger), [AvoidNonExistentAnnotations](pmd_rules_apex_errorprone.html#avoidnonexistentannotations), [AvoidSoqlInLoops](pmd_rules_apex_performance.html#avoidsoqlinloops), [AvoidSoslInLoops](pmd_rules_apex_performance.html#avoidsoslinloops), [ClassNamingConventions](pmd_rules_apex_codestyle.html#classnamingconventions), [CyclomaticComplexity](pmd_rules_apex_design.html#cyclomaticcomplexity), [EmptyCatchBlock](pmd_rules_apex_errorprone.html#emptycatchblock), [EmptyIfStmt](pmd_rules_apex_errorprone.html#emptyifstmt), [EmptyStatementBlock](pmd_rules_apex_errorprone.html#emptystatementblock), [EmptyTryOrFinallyBlock](pmd_rules_apex_errorprone.html#emptytryorfinallyblock), [EmptyWhileStmt](pmd_rules_apex_errorprone.html#emptywhilestmt), [ExcessiveClassLength](pmd_rules_apex_design.html#excessiveclasslength), [ExcessiveParameterList](pmd_rules_apex_design.html#excessiveparameterlist), [ExcessivePublicCount](pmd_rules_apex_design.html#excessivepubliccount), [ForLoopsMustUseBraces](pmd_rules_apex_codestyle.html#forloopsmustusebraces), [IfElseStmtsMustUseBraces](pmd_rules_apex_codestyle.html#ifelsestmtsmustusebraces), [IfStmtsMustUseBraces](pmd_rules_apex_codestyle.html#ifstmtsmustusebraces), [MethodNamingConventions](pmd_rules_apex_codestyle.html#methodnamingconventions), [MethodWithSameNameAsEnclosingClass](pmd_rules_apex_errorprone.html#methodwithsamenameasenclosingclass), [NcssConstructorCount](pmd_rules_apex_design.html#ncssconstructorcount), [NcssMethodCount](pmd_rules_apex_design.html#ncssmethodcount), [NcssTypeCount](pmd_rules_apex_design.html#ncsstypecount), [OneDeclarationPerLine](pmd_rules_apex_codestyle.html#onedeclarationperline), [StdCyclomaticComplexity](pmd_rules_apex_design.html#stdcyclomaticcomplexity), [TooManyFields](pmd_rules_apex_design.html#toomanyfields), [VariableNamingConventions](pmd_rules_apex_codestyle.html#variablenamingconventions), [WhileLoopsMustUseBraces](pmd_rules_apex_codestyle.html#whileloopsmustusebraces) * Empty Code (`rulesets/apex/empty.xml`): diff --git a/docs/pages/pmd/rules/apex/codestyle.md b/docs/pages/pmd/rules/apex/codestyle.md index 1612e82a5c..0e59a82e23 100644 --- a/docs/pages/pmd/rules/apex/codestyle.md +++ b/docs/pages/pmd/rules/apex/codestyle.md @@ -5,7 +5,7 @@ permalink: pmd_rules_apex_codestyle.html folder: pmd/rules/apex sidebaractiveurl: /pmd_rules_apex.html editmepath: ../pmd-apex/src/main/resources/category/apex/codestyle.xml -keywords: Code Style, ClassNamingConventions, IfElseStmtsMustUseBraces, IfStmtsMustUseBraces, ForLoopsMustUseBraces, MethodNamingConventions, VariableNamingConventions, WhileLoopsMustUseBraces +keywords: Code Style, ClassNamingConventions, IfElseStmtsMustUseBraces, IfStmtsMustUseBraces, ForLoopsMustUseBraces, MethodNamingConventions, OneDeclarationPerLine, VariableNamingConventions, WhileLoopsMustUseBraces language: Apex --- ## ClassNamingConventions @@ -192,6 +192,52 @@ public class Foo { ``` +## OneDeclarationPerLine + +**Since:** PMD 6.7.0 + +**Priority:** High (1) + +Apex allows the use of several variables declaration of the same type on one line. However, it +can lead to quite messy code. This rule looks for several declarations on the same line. + +**This rule is defined by the following XPath expression:** +``` xpath +//VariableDeclarationStatements + [count(VariableDeclaration) > 1] + [$strictMode or count(distinct-values(VariableDeclaration/@BeginLine)) != count(VariableDeclaration)] +| +//FieldDeclarationStatements + [count(FieldDeclaration) > 1] + [$strictMode or count(distinct-values(FieldDeclaration/VariableExpression/@BeginLine)) != count(FieldDeclaration/VariableExpression)] +``` + +**Example(s):** + +``` java +Integer a, b; // not recommended + +Integer a, + b; // ok by default, can be flagged setting the strictMode property + +Integer a; // preferred approach +Integer b; +``` + +**This rule has the following properties:** + +|Name|Default Value|Description|Multivalued| +|----|-------------|-----------|-----------| +|cc_categories|Style|Code Climate Categories|yes. Delimiter is '\|'.| +|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|no| +|cc_block_highlighting|false|Code Climate Block Highlighting|no| +|strictMode|false|If true, mark combined declaration even if the declarations are on separate lines.|no| + +**Use this rule by referencing it:** +``` xml + +``` + ## VariableNamingConventions **Since:** PMD 5.5.0 diff --git a/docs/pages/pmd/rules/java.md b/docs/pages/pmd/rules/java.md index 48387179af..e3dbda321f 100644 --- a/docs/pages/pmd/rules/java.md +++ b/docs/pages/pmd/rules/java.md @@ -63,7 +63,7 @@ folder: pmd/rules * [AtLeastOneConstructor](pmd_rules_java_codestyle.html#atleastoneconstructor): Each non-static class should declare at least one constructor.Classes with solely static members ... * [AvoidDollarSigns](pmd_rules_java_codestyle.html#avoiddollarsigns): Avoid using dollar signs in variable/method/class/interface names. * [AvoidFinalLocalVariable](pmd_rules_java_codestyle.html#avoidfinallocalvariable): Avoid using final local variables, turn them into fields. -* [AvoidPrefixingMethodParameters](pmd_rules_java_codestyle.html#avoidprefixingmethodparameters): Prefixing parameters by 'in' or 'out' pollutes the name of the parameters and reduces code readab... +* [AvoidPrefixingMethodParameters](pmd_rules_java_codestyle.html#avoidprefixingmethodparameters): Deprecated Prefixing parameters by 'in' or 'out' pollutes the name of the parameters and reduces code readab... * [AvoidProtectedFieldInFinalClass](pmd_rules_java_codestyle.html#avoidprotectedfieldinfinalclass): Do not use protected fields in final classes since they cannot be subclassed.Clarify your intent ... * [AvoidProtectedMethodInFinalClassNotExtending](pmd_rules_java_codestyle.html#avoidprotectedmethodinfinalclassnotextending): Do not use protected methods in most final classes since they cannot be subclassed. This shouldon... * [AvoidUsingNativeCode](pmd_rules_java_codestyle.html#avoidusingnativecode): Unnecessary reliance on Java Native Interface (JNI) calls directly reduces application portabilit... @@ -96,7 +96,7 @@ folder: pmd/rules * [MDBAndSessionBeanNamingConvention](pmd_rules_java_codestyle.html#mdbandsessionbeannamingconvention): The EJB Specification states that any MessageDrivenBean or SessionBean should be suffixed by 'Bean'. * [MethodArgumentCouldBeFinal](pmd_rules_java_codestyle.html#methodargumentcouldbefinal): A method argument that is never re-assigned within the method can be declared final. * [MethodNamingConventions](pmd_rules_java_codestyle.html#methodnamingconventions): Configurable naming conventions for method declarations. This rule reports method decl... -* [MIsLeadingVariableName](pmd_rules_java_codestyle.html#misleadingvariablename): Detects when a non-field has a name starting with 'm_'. This usually denotes a field and could b... +* [MIsLeadingVariableName](pmd_rules_java_codestyle.html#misleadingvariablename): Deprecated Detects when a non-field has a name starting with 'm_'. This usually denotes a field and could b... * [NoPackage](pmd_rules_java_codestyle.html#nopackage): Detects when a class or interface does not have a package definition. * [OnlyOneReturn](pmd_rules_java_codestyle.html#onlyonereturn): A method should have only one exit point, and that should be the last statement in the method. * [PackageCase](pmd_rules_java_codestyle.html#packagecase): Detects when a package definition contains uppercase characters. @@ -106,7 +106,7 @@ folder: pmd/rules * [ShortClassName](pmd_rules_java_codestyle.html#shortclassname): Short Classnames with fewer than e.g. five characters are not recommended. * [ShortMethodName](pmd_rules_java_codestyle.html#shortmethodname): Method names that are very short are not helpful to the reader. * [ShortVariable](pmd_rules_java_codestyle.html#shortvariable): Fields, local variables, or parameter names that are very short are not helpful to the reader. -* [SuspiciousConstantFieldName](pmd_rules_java_codestyle.html#suspiciousconstantfieldname): Field names using all uppercase characters - Sun's Java naming conventions indicating constants -... +* [SuspiciousConstantFieldName](pmd_rules_java_codestyle.html#suspiciousconstantfieldname): Deprecated Field names using all uppercase characters - Sun's Java naming conventions indicating constants -... * [TooManyStaticImports](pmd_rules_java_codestyle.html#toomanystaticimports): If you overuse the static import feature, it can make your program unreadable and unmaintainable,... * [UnnecessaryAnnotationValueElement](pmd_rules_java_codestyle.html#unnecessaryannotationvalueelement): Avoid the use of value in annotations when it's the only element. * [UnnecessaryConstructor](pmd_rules_java_codestyle.html#unnecessaryconstructor): This rule detects when a constructor is not necessary; i.e., when there is only one constructor a... @@ -116,7 +116,7 @@ folder: pmd/rules * [UnnecessaryReturn](pmd_rules_java_codestyle.html#unnecessaryreturn): Avoid the use of unnecessary return statements. * [UselessParentheses](pmd_rules_java_codestyle.html#uselessparentheses): Useless parentheses should be removed. * [UselessQualifiedThis](pmd_rules_java_codestyle.html#uselessqualifiedthis): Look for qualified this usages in the same class. -* [VariableNamingConventions](pmd_rules_java_codestyle.html#variablenamingconventions): A variable naming conventions rule - customize this to your liking. Currently, itchecks for fina... +* [VariableNamingConventions](pmd_rules_java_codestyle.html#variablenamingconventions): Deprecated A variable naming conventions rule - customize this to your liking. Currently, itchecks for fina... * [WhileLoopsMustUseBraces](pmd_rules_java_codestyle.html#whileloopsmustusebraces): Deprecated Avoid using 'while' statements without using braces to surround the code block. If the code forma... ## Design diff --git a/docs/pages/pmd/rules/java/bestpractices.md b/docs/pages/pmd/rules/java/bestpractices.md index 56759de176..4c46a7a429 100644 --- a/docs/pages/pmd/rules/java/bestpractices.md +++ b/docs/pages/pmd/rules/java/bestpractices.md @@ -250,7 +250,6 @@ public class Foo { |Name|Default Value|Description|Multivalued| |----|-------------|-----------|-----------| |checkAddressTypes|IPv4 \| IPv6 \| IPv4 mapped IPv6|Check for IP address types.|yes. Delimiter is '\|'.| -|pattern|^"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"$|Regular Expression|no| **Use this rule by referencing it:** ``` xml @@ -874,6 +873,10 @@ can lead to quite messy code. This rule looks for several declarations on the sa //LocalVariableDeclaration [count(VariableDeclarator) > 1] [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] +| +//FieldDeclaration + [count(VariableDeclarator) > 1] + [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] ``` **Example(s):** diff --git a/docs/pages/pmd/rules/java/codestyle.md b/docs/pages/pmd/rules/java/codestyle.md index b6f2a4db50..091987c4e1 100644 --- a/docs/pages/pmd/rules/java/codestyle.md +++ b/docs/pages/pmd/rules/java/codestyle.md @@ -141,6 +141,8 @@ public class MyClass { ## AvoidPrefixingMethodParameters +Deprecated + **Since:** PMD 5.0 **Priority:** Medium Low (4) @@ -802,6 +804,7 @@ class Foo { |finalFieldPattern|[a-z][a-zA-Z0-9]*|Regex which applies to final field names|no| |staticFieldPattern|[a-z][a-zA-Z0-9]*|Regex which applies to static field names|no| |defaultFieldPattern|[a-z][a-zA-Z0-9]*|Regex which applies to field names|no| +|exclusions|serialVersionUID|Names of fields to whitelist.|yes. Delimiter is '\|'.| **Use this rule by referencing it:** ``` xml @@ -1138,15 +1141,16 @@ public class LinguisticNaming { |Name|Default Value|Description|Multivalued| |----|-------------|-----------|-----------| -|booleanFieldPrefixes|is \| has \| can \| have \| will \| should|the prefixes of fields and variables that indicate boolean|yes. Delimiter is '\|'.| -|checkVariables|true|Check local variable names and types for inconsistent naming|no| -|checkFields|true|Check field names and types for inconsistent naming|no| -|booleanMethodPrefixes|is \| has \| can \| have \| will \| should|the prefixes of methods that return boolean|yes. Delimiter is '\|'.| -|checkPrefixedTransformMethods|true|Check return type of methods whose names start with 'to'|no| -|checkTransformMethods|false|Check return type of methods which contain 'To' in their name|no| -|checkSetters|true|Check return type of setters|no| -|checkGetters|true|Check return type of getters|no| -|checkBooleanMethod|true|Check method names and types for inconsistent naming|no| +|booleanFieldPrefixes|is \| has \| can \| have \| will \| should|The prefixes of fields and variables that indicate boolean.|yes. Delimiter is '\|'.| +|checkVariables|true|Check local variable names and types for inconsistent naming.|no| +|checkFields|true|Check field names and types for inconsistent naming.|no| +|transformMethodNames|to \| as|The prefixes and infixes that indicate a transform method.|yes. Delimiter is '\|'.| +|booleanMethodPrefixes|is \| has \| can \| have \| will \| should|The prefixes of methods that return boolean.|yes. Delimiter is '\|'.| +|checkPrefixedTransformMethods|true|Check return type of methods whose names start with the configured prefix (see transformMethodNames property).|no| +|checkTransformMethods|false|Check return type of methods which contain the configured infix in their name (see transformMethodNames property).|no| +|checkSetters|true|Check return type of setters.|no| +|checkGetters|true|Check return type of getters.|no| +|checkBooleanMethod|true|Check method names and types for inconsistent naming.|no| **Use this rule by referencing it:** ``` xml @@ -1444,6 +1448,8 @@ public class Foo { ## MIsLeadingVariableName +Deprecated + **Since:** PMD 3.4 **Priority:** Medium (3) @@ -1781,6 +1787,8 @@ public class Something { ## SuspiciousConstantFieldName +Deprecated + **Since:** PMD 2.0 **Priority:** Medium (3) @@ -2194,6 +2202,8 @@ public class Foo { ## VariableNamingConventions +Deprecated + **Since:** PMD 1.2 **Priority:** High (1) diff --git a/docs/pages/pmd/userdocs/installation.md b/docs/pages/pmd/userdocs/installation.md index 11e01f02aa..fc9d31ab32 100644 --- a/docs/pages/pmd/userdocs/installation.md +++ b/docs/pages/pmd/userdocs/installation.md @@ -17,6 +17,9 @@ sidebar: pmd_sidebar * For Windows: [Winzip](http://winzip.com) or the free [7-zip](http://www.7-zip.org/) * For Linux / Unix: [InfoZip](http://www.info-zip.org/pub/infozip/) +{% include note.html content="For executing the Designer (./run.sh designer) using [OpenJDK](http://jdk.java.net) or Java 11, you need additionally [OpenJFX](http://jdk.java.net). Download it, extract it and set the environment variable JAVAFX_HOME." %} + + ### Installation PMD is distributed as a zip archive, which includes both [PMD](#running-pmd-via-command-line) and [CPD](/pmd_userdocs_cpd.html). diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a324c2ee28..a374402d01 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -4,76 +4,76 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- -## {{ site.pmd.date }} - {{ site.pmd.version | append_unless: is_release_version, "-SNAPSHOT" }} +## {{ site.pmd.date }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. This is a {{ site.pmd.release_type }} release. -### Table Of Contents - -* [New and noteworthy](#new-and-noteworthy) - * [New Rules](#new-rules) -* [Fixed Issues](#fixed-issues) -* [API Changes](#api-changes) -* [External Contributions](#external-contributions) +{% tocmaker %} ### New and noteworthy -#### New Rules +#### Drawing a line between private and public API -* The new Java rule {% rule java/codestyle/LinguisticNaming %} (`java-codestyle`) - detects cases, when a method name indicates it returns a boolean (such as `isSmall()`) but it doesn't. - Besides method names, the rule also checks field and variable names. It also checks, that getters return - something but setters won't. The rule has several properties with which it can be customized. +Until now, all released public members and types were implicitly considered part +of PMD's public API, including inheritance-specific members (protected members, abstract methods). +We have maintained those APIs with the goal to preserve full binary compatibility between minor releases, +only breaking those APIs infrequently, for major releases. -* The new PL/SQL rule {% rule plsql/codestyle/ForLoopNaming %} (`plsql-codestyle`) - enforces a naming convention for "for loops". Both "cursor for loops" and "index for loops" are covered. - The rule can be customized via patterns. By default, short variable names are reported. -* The new Java rule {% rule java/codestyle/FieldNamingConventions %} (`java-codestyle`) - detects field names that don't comply to a given convention. It defaults to standard Java convention of using camelCase, - but can be configured with ease for e.g. constants or static fields. +In order to allow PMD to move forward at a faster pace, this implicit contract will +be invalidated with PMD 7.0.0. We now introduce more fine-grained distinctions between +the type of compatibility support we guarantee for our libraries, and ways to make +them explicit to clients of PMD. + +##### `.internal` packages and `@InternalApi` annotation + +*Internal API* is meant for use *only* by the main PMD codebase. Internal types and methods +may be modified in any way, or even removed, at any time. + +Any API in a package that contains an `.internal` segment is considered internal. +The `@InternalApi` annotation will be used for APIs that have to live outside of +these packages, e.g. methods of a public type that shouldn't be used outside of PMD (again, +these can be removed anytime). + +##### `@ReservedSubclassing` + +Types marked with the `@ReservedSubclassing` annotation are only meant to be subclassed +by classes within PMD. As such, we may add new abstract methods, or remove protected methods, +at any time. All published public members remain supported. The annotation is *not* inherited, which +means a reserved interface doesn't prevent its implementors to be subclassed. + +##### `@Experimental` + + +APIs marked with the `@Experimental` annotation at the class or method level are subject to change. +They can be modified in any way, or even removed, at any time. You should not use or rely + on them in any production code. They are purely to allow broad testing and feedback. + +##### `@Deprecated` + +APIs marked with the `@Deprecated` annotation at the class or method level will remain supported +until the next major release but it is recommended to stop using them. + + +##### The transition + +*All currently supported APIs will remain so until 7.0.0*. All APIs that are to be moved to +`.internal` packages or hidden will be tagged `@InternalApi` before that major release, and +the breaking API changes will be performed in 7.0.0. ### Fixed Issues -* core - * [#1191](https://github.com/pmd/pmd/issues/1191): \[core] Test Framework: Sort violations by line/column - * [#1283](https://github.com/pmd/pmd/issues/1283): \[core] Deprecate ReportTree - * [#1288](https://github.com/pmd/pmd/issues/1288): \[core] No supported build listeners found with Gradle - * [#1300](https://github.com/pmd/pmd/issues/1300): \[core] PMD stops processing file completely, if one rule in a rule chain fails -* java-bestpractices - * [#940](https://github.com/pmd/pmd/issues/940): \[java] JUnit 4 false positives for JUnit 5 tests - * [#1267](https://github.com/pmd/pmd/pull/1267): \[java] MissingOverrideRule: Avoid NoClassDefFoundError with incomplete classpath * java-codestyle - * [#1255](https://github.com/pmd/pmd/issues/1255): \[java] UnnecessaryFullyQualifiedName false positive: static method on shadowed implicitly imported class - * [#1258](https://github.com/pmd/pmd/issues/1285): \[java] False positive "UselessParentheses" for parentheses that contain assignment -* java-errorprone - * [#1078](https://github.com/pmd/pmd/issues/1078): \[java] MissingSerialVersionUID rule does not seem to catch inherited classes + * [#1329](https://github.com/pmd/pmd/issues/1329): \[java] FieldNamingConventions: false positive in serializable class with serialVersionUID + * [#1334](https://github.com/pmd/pmd/issues/1334): \[java] LinguisticNaming should support AtomicBooleans * java-performance - * [#1298](https://github.com/pmd/pmd/issues/1298): \[java] RedundantFieldInitializer - NumberFormatException with Long -* jsp - * [#1274](https://github.com/pmd/pmd/issues/1274): \[jsp] Support EL in tag attributes - * [#1276](https://github.com/pmd/pmd/issues/1276): \[jsp] add support for jspf and tag extensions -* plsql - * [#681](https://github.com/pmd/pmd/issues/681): \[plsql] Parse error with Cursor For Loop + * [#1325](https://github.com/pmd/pmd/issues/1325): \[java] False positive in ConsecutiveLiteralAppends ### API Changes -* All classes in the package `net.sourceforge.pmd.lang.dfa.report` have been deprecated and will be removed - with PMD 7.0.0. This includes the class `net.sourceforge.pmd.lang.dfa.report.ReportTree`. The reason is, - that this class is very specific to Java and not suitable for other languages. It has only been used for - `YAHTMLRenderer`, which has been rewritten to work without these classes. - ### External Contributions -* [#109](https://github.com/pmd/pmd/pull/109): \[java] Add two linguistics rules under naming - [Arda Aslan](https://github.com/ardaasln) -* [#1254](https://github.com/pmd/pmd/pull/1254): \[ci] \[GSoC] Integrating the danger and pmdtester to travis CI - [BBG](https://github.com/djydewang) -* [#1258](https://github.com/pmd/pmd/pull/1258): \[java] Use typeof in MissingSerialVersionUID - [krichter722](https://github.com/krichter722) -* [#1264](https://github.com/pmd/pmd/pull/1264): \[cpp] Fix NullPointerException in CPPTokenizer:99 - [Rafael Cortês](https://github.com/mrfyda) -* [#1277](https://github.com/pmd/pmd/pull/1277): \[jsp] #1276 add support for jspf and tag extensions - [Jordi Llach](https://github.com/jordillachmrf) -* [#1275](https://github.com/pmd/pmd/pull/1275): \[jsp] Issue #1274 - Support EL in tag attributes - [Jordi Llach](https://github.com/jordillachmrf) -* [#1278](https://github.com/pmd/pmd/pull/1278): \[ci] \[GSoC] Use pmdtester 1.0.0.pre.beta3 - [BBG](https://github.com/djydewang) -* [#1289](https://github.com/pmd/pmd/pull/1289): \[java] UselessParentheses: Fix false positive with assignments - [cobratbq](https://github.com/cobratbq) -* [#1290](https://github.com/pmd/pmd/pull/1290): \[docs] \[GSoC] Create the documentation about pmdtester - [BBG](https://github.com/djydewang) -* [#1256](https://github.com/pmd/pmd/pull/1256): \[java] #940 Avoid JUnit 4 false positives for JUnit 5 tests - [Alex Shesterov](https://github.com/vovkss) +{% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 3c3cd9e857..de6639ce49 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -6,6 +6,110 @@ permalink: pmd_release_notes_old.html Previous versions of PMD can be downloaded here: http://sourceforge.net/projects/pmd/files/pmd/ +## 02-September-2018 - 6.7.0 + +The PMD team is pleased to announce PMD 6.7.0. + +This is a minor release. + +### Table Of Contents + +* [New and noteworthy](#new-and-noteworthy) + * [Modified Rules](#modified-rules) + * [New Rules](#new-rules) + * [Deprecated Rules](#deprecated-rules) +* [Fixed Issues](#fixed-issues) +* [API Changes](#api-changes) +* [External Contributions](#external-contributions) + +### New and noteworthy + +#### Modified Rules + +* The Java rule {% rule java/bestpractices/OneDeclarationPerLine %} (`java-bestpractices`) has been revamped to + consider not only local variable declarations, but field declarations too. + +#### New Rules + +* The new Java rule {% rule java/codestyle/LinguisticNaming %} (`java-codestyle`) + detects cases, when a method name indicates it returns a boolean (such as `isSmall()`) but it doesn't. + Besides method names, the rule also checks field and variable names. It also checks, that getters return + something but setters won't. The rule has several properties with which it can be customized. + +* The new PL/SQL rule {% rule plsql/codestyle/ForLoopNaming %} (`plsql-codestyle`) + enforces a naming convention for "for loops". Both "cursor for loops" and "index for loops" are covered. + The rule can be customized via patterns. By default, short variable names are reported. + +* The new Java rule {% rule java/codestyle/FieldNamingConventions %} (`java-codestyle`) + detects field names that don't comply to a given convention. It defaults to standard Java convention of using camelCase, + but can be configured with ease for e.g. constants or static fields. + +* The new Apex rule {% rule apex/codestyle/OneDeclarationPerLine %} (`apex-codestyle`) enforces declaring a + single field / variable per line; or per statement if the `strictMode` property is set. + It's an Apex equivalent of the already existing Java rule of the same name. + +#### Deprecated Rules + +* The Java rules {% rule java/codestyle/VariableNamingConventions %}, {% rule java/codestyle/MIsLeadingVariableName %}, + {% rule java/codestyle/SuspiciousConstantFieldName %}, and {% rule java/codestyle/AvoidPrefixingMethodParameters %} are + now deprecated, and will be removed with version 7.0.0. They are replaced by the more general + {% rule java/codestyle/FieldNamingConventions %}, {% rule java/codestyle/FormalParameterNamingConventions %}, and + {% rule java/codestyle/LocalVariableNamingConventions %}. + +### Fixed Issues + +* core + * [#1191](https://github.com/pmd/pmd/issues/1191): \[core] Test Framework: Sort violations by line/column + * [#1283](https://github.com/pmd/pmd/issues/1283): \[core] Deprecate ReportTree + * [#1288](https://github.com/pmd/pmd/issues/1288): \[core] No supported build listeners found with Gradle + * [#1300](https://github.com/pmd/pmd/issues/1300): \[core] PMD stops processing file completely, if one rule in a rule chain fails + * [#1317](https://github.com/pmd/pmd/issues/1317): \[ci] Coveralls hasn't built the project since June 25th +* java-bestpractices + * [#940](https://github.com/pmd/pmd/issues/940): \[java] JUnit 4 false positives for JUnit 5 tests + * [#1267](https://github.com/pmd/pmd/pull/1267): \[java] MissingOverrideRule: Avoid NoClassDefFoundError with incomplete classpath + * [#1323](https://github.com/pmd/pmd/issues/1323): \[java] AvoidUsingHardCodedIP ignores match pattern + * [#1327](https://github.com/pmd/pmd/pull/1327): \[java] AvoidUsingHardCodedIP false positive for ":bee" +* java-codestyle + * [#1255](https://github.com/pmd/pmd/issues/1255): \[java] UnnecessaryFullyQualifiedName false positive: static method on shadowed implicitly imported class + * [#1258](https://github.com/pmd/pmd/issues/1285): \[java] False positive "UselessParentheses" for parentheses that contain assignment +* java-errorprone + * [#1078](https://github.com/pmd/pmd/issues/1078): \[java] MissingSerialVersionUID rule does not seem to catch inherited classes +* java-performance + * [#1291](https://github.com/pmd/pmd/issues/1291): \[java] InvalidSlf4jMessageFormat false positive: too many arguments with string concatenation operator + * [#1298](https://github.com/pmd/pmd/issues/1298): \[java] RedundantFieldInitializer - NumberFormatException with Long +* jsp + * [#1274](https://github.com/pmd/pmd/issues/1274): \[jsp] Support EL in tag attributes + * [#1276](https://github.com/pmd/pmd/issues/1276): \[jsp] add support for jspf and tag extensions +* plsql + * [#681](https://github.com/pmd/pmd/issues/681): \[plsql] Parse error with Cursor For Loop + +### API Changes + +* All classes in the package `net.sourceforge.pmd.lang.dfa.report` have been deprecated and will be removed + with PMD 7.0.0. This includes the class `net.sourceforge.pmd.lang.dfa.report.ReportTree`. The reason is, + that this class is very specific to Java and not suitable for other languages. It has only been used for + `YAHTMLRenderer`, which has been rewritten to work without these classes. + +* The nodes RUNSIGNEDSHIFT and RSIGNEDSHIFT are deprecated and will be removed from the AST with PMD 7.0.0. + These represented the operator of ShiftExpression in two cases out of three, but they're not needed and + make ShiftExpression inconsistent. The operator of a ShiftExpression is now accessible through + ShiftExpression#getOperator. + +### External Contributions + +* [#109](https://github.com/pmd/pmd/pull/109): \[java] Add two linguistics rules under naming - [Arda Aslan](https://github.com/ardaasln) +* [#1254](https://github.com/pmd/pmd/pull/1254): \[ci] \[GSoC] Integrating the danger and pmdtester to travis CI - [BBG](https://github.com/djydewang) +* [#1258](https://github.com/pmd/pmd/pull/1258): \[java] Use typeof in MissingSerialVersionUID - [krichter722](https://github.com/krichter722) +* [#1264](https://github.com/pmd/pmd/pull/1264): \[cpp] Fix NullPointerException in CPPTokenizer:99 - [Rafael Cortês](https://github.com/mrfyda) +* [#1277](https://github.com/pmd/pmd/pull/1277): \[jsp] #1276 add support for jspf and tag extensions - [Jordi Llach](https://github.com/jordillachmrf) +* [#1275](https://github.com/pmd/pmd/pull/1275): \[jsp] Issue #1274 - Support EL in tag attributes - [Jordi Llach](https://github.com/jordillachmrf) +* [#1278](https://github.com/pmd/pmd/pull/1278): \[ci] \[GSoC] Use pmdtester 1.0.0.pre.beta3 - [BBG](https://github.com/djydewang) +* [#1289](https://github.com/pmd/pmd/pull/1289): \[java] UselessParentheses: Fix false positive with assignments - [cobratbq](https://github.com/cobratbq) +* [#1290](https://github.com/pmd/pmd/pull/1290): \[docs] \[GSoC] Create the documentation about pmdtester - [BBG](https://github.com/djydewang) +* [#1256](https://github.com/pmd/pmd/pull/1256): \[java] #940 Avoid JUnit 4 false positives for JUnit 5 tests - [Alex Shesterov](https://github.com/vovkss) +* [#1315](https://github.com/pmd/pmd/pull/1315): \[apex] Add OneDeclarationPerStatement rule - [Jeff Hube](https://github.com/jeffhube) + + ## 29-July-2018 - 6.6.0 The PMD team is pleased to announce PMD 6.6.0. diff --git a/pmd-apex-jorje/pom.xml b/pmd-apex-jorje/pom.xml index f53d989da7..a6897a5657 100644 --- a/pmd-apex-jorje/pom.xml +++ b/pmd-apex-jorje/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 1fc38e5979..b9154e5ad6 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-apex/src/main/resources/category/apex/codestyle.xml b/pmd-apex/src/main/resources/category/apex/codestyle.xml index 6254e17d13..0387f32b61 100644 --- a/pmd-apex/src/main/resources/category/apex/codestyle.xml +++ b/pmd-apex/src/main/resources/category/apex/codestyle.xml @@ -149,6 +149,47 @@ public class Foo { + + +Apex allows the use of several variables declaration of the same type on one line. However, it +can lead to quite messy code. This rule looks for several declarations on the same line. + + 1 + + + + 1] + [$strictMode or count(distinct-values(VariableDeclaration/@BeginLine)) != count(VariableDeclaration)] +| +//FieldDeclarationStatements + [count(FieldDeclaration) > 1] + [$strictMode or count(distinct-values(FieldDeclaration/VariableExpression/@BeginLine)) != count(FieldDeclaration/VariableExpression)] +]]> + + + + + + + + + + + + + + 3 + + + + + + + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/CodeStyleRulesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/CodeStyleRulesTest.java index 5d484265d8..7393757536 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/CodeStyleRulesTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/CodeStyleRulesTest.java @@ -17,6 +17,7 @@ public class CodeStyleRulesTest extends SimpleAggregatorTst { addRule(RULESET, "IfElseStmtsMustUseBraces"); addRule(RULESET, "IfStmtsMustUseBraces"); addRule(RULESET, "MethodNamingConventions"); + addRule(RULESET, "OneDeclarationPerLine"); addRule(RULESET, "VariableNamingConventions"); addRule(RULESET, "WhileLoopsMustUseBraces"); } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/OneDeclarationPerLine.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/OneDeclarationPerLine.xml new file mode 100644 index 0000000000..7a1a36a987 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/OneDeclarationPerLine.xml @@ -0,0 +1,95 @@ + + + + + + one field declaration per statement + 1 + + + + + one variable declaration per statement + 1 + + + + + + all is well + 0 + + + + + one variable declaration per line, ok by default + 0 + + + + + one field declaration per line, ok by default + 0 + + + + + one variable declaration per line, not ok when strictMode + true + 1 + + + + + one field declaration per line, not ok when strictMode + true + 1 + + + diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 5147f55afa..d7838f8113 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java new file mode 100644 index 0000000000..82a838e616 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java @@ -0,0 +1,18 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.annotation; + +import java.lang.annotation.Documented; + + +/** + * Indicates the feature is in experimental state: its existence, signature or behavior + * might change without warning from one release to the next. + * + * @since 6.7.0 + */ +@Documented +public @interface Experimental { +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java new file mode 100644 index 0000000000..fbcef90350 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java @@ -0,0 +1,25 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.annotation; + +import java.lang.annotation.Documented; + + +/** + * Tags API members that are not publicly supported API. + * Such members may be removed, renamed, moved, or otherwise + * broken at any time and should not be relied upon outside + * of the main PMD codebase. + * + *

Members and types tagged with this annotation will remain + * supported until 7.0.0, after which some will be moved to internal + * packages, or will see their visibility reduced. + * + * @since 6.7.0 + */ +// NOTE: use @Deprecated with this annotation to raise a compiler warning until 7.0.0 +@Documented +public @interface InternalApi { +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/ReservedSubclassing.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/ReservedSubclassing.java new file mode 100644 index 0000000000..47f10de80c --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/ReservedSubclassing.java @@ -0,0 +1,37 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + + +/** + * Indicates that subclassing this type is not publicly + * supported API. Abstract methods may be added or removed + * at any time, which could break binary compatibility with + * existing implementors. Protected methods are also part of + * the private API of this type. + * + *

The API that is not inheritance-specific (unless {@linkplain InternalApi noted otherwise}, + * all public members), is still public API and will remain binary- + * compatible between major releases. + * + *

Types tagged with this annotation will remain supported + * until 7.0.0, at which point no guarantees will be maintained + * about the stability of the inheritance hierarchy for external + * clients. + * + *

This should be used for example for base rule classes that + * are meant to be used in PMD only, or for AST-related interfaces + * and abstract classes. + * + * @since 6.7.0 + */ +@Target(ElementType.TYPE) +@Documented +public @interface ReservedSubclassing { +} diff --git a/pmd-core/src/main/resources/rulesets/releases/670.xml b/pmd-core/src/main/resources/rulesets/releases/670.xml index b250a1cabf..0209a7c72b 100644 --- a/pmd-core/src/main/resources/rulesets/releases/670.xml +++ b/pmd-core/src/main/resources/rulesets/releases/670.xml @@ -11,6 +11,7 @@ This ruleset contains links to rules that are new in PMD v6.7.0 + diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 52db8345e4..954141a087 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 72e8afcc7c..15e7b227bf 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index c09618a706..4f93d6128e 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-dist/src/main/scripts/designer.bat b/pmd-dist/src/main/scripts/designer.bat index c19b4532f1..60a4fecc63 100644 --- a/pmd-dist/src/main/scripts/designer.bat +++ b/pmd-dist/src/main/scripts/designer.bat @@ -5,14 +5,47 @@ set MAIN_CLASS=net.sourceforge.pmd.util.fxdesigner.DesignerStarter :: sets the jver variable to the java version, eg 901 for 9.0.1+x or 180 for 1.8.0_171-b11 -for /f tokens^=2-4^ delims^=.-_+^" %%j in ('java -fullversion 2^>^&1') do set /A jver="%%j%%k%%l" +:: sets the jvendor variable to either java (oracle) or openjdk +for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| find "version"') do ( + set jvendor=%%j + if %%l EQU ea ( + set /A "jver=%%k00" + ) else ( + set /A jver=%%k%%l%%m + ) +) -if "%jver%" GEQ "900" ( - :: enable reflection - Set jreopts=--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED +Set "jreopts=" +:: oracle java 9 and 10 has javafx included as a module +if /I "%jvendor%" EQU "java" ( + if %jver% GEQ 900 ( + if %jver% LSS 1100 ( + :: enable reflection + Set jreopts=--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED + ) + ) +) + +set "_needjfxlib=0" +if /I "%jvendor%" EQU "openjdk" set _needjfxlib=1 +if /I "%jvendor%" EQU "java" ( + if %jver% GEQ 1100 set _needjfxlib=1 +) +if %_needjfxlib% EQU 1 ( + if %jver% LSS 1000 ( + echo For openjfx at least java 10 is required. + pause + exit + ) + if [%JAVAFX_HOME%] EQU [] ( + echo The environment variable JAVAFX_HOME is missing. + pause + exit + ) + set "classpath=%TOPDIR%\lib\*;%JAVAFX_HOME%\lib\*" ) else ( - Set jreopts= + set "classpath=%TOPDIR%\lib\*" ) -java %jreopts% -classpath "%TOPDIR%\lib\*" %OPTS% %MAIN_CLASS% %* +java %jreopts% -classpath "%classpath%" %OPTS% %MAIN_CLASS% %* diff --git a/pmd-dist/src/main/scripts/run.sh b/pmd-dist/src/main/scripts/run.sh index 5cd03fb76a..9a5ce0d3e0 100755 --- a/pmd-dist/src/main/scripts/run.sh +++ b/pmd-dist/src/main/scripts/run.sh @@ -29,6 +29,7 @@ cygwin_paths() { # For Cygwin, switch paths to Windows format before running java if ${cygwin} ; then [ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --windows "${JAVA_HOME}") + [ -n "${JAVAFX_HOME}" ] && JAVAFX_HOME=$(cygpath --windows "${JAVAFX_HOME}") [ -n "${DIRECTORY}" ] && DIRECTORY=$(cygpath --windows "${DIRECTORY}") classpath=$(cygpath --path --windows "${classpath}") fi @@ -38,6 +39,7 @@ convert_cygwin_vars() { # If cygwin, convert to Unix form before manipulating if ${cygwin} ; then [ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --unix "${JAVA_HOME}") + [ -n "${JAVAFX_HOME}" ] && JAVAFX_HOME=$(cygpath --unix "${JAVAFX_HOME}") [ -n "${CLASSPATH}" ] && CLASSPATH=$(cygpath --path --unix "${CLASSPATH}") fi } @@ -74,32 +76,89 @@ check_lib_dir() { fi } +function script_exit() { + echo $1 >&2 + exit 1 +} + +determine_java_version() { + local full_ver=$(java -version 2>&1) + # java_ver is eg "18" for java 1.8, "90" for java 9.0, "100" for java 10.0.x + readonly java_ver=$(echo $full_ver | sed -n '{ + # replace early access versions, e.g. 11-ea with 11.0.0 + s/-ea/.0.0/ + # replace versions such as 10 with 10.0.0 + s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/ + # extract the major and minor parts of the version + s/^.* version "\(.*\)\.\(.*\)\..*".*$/\1\2/p + }') + # java_vendor is either java (oracle) or openjdk + readonly java_vendor=$(echo $full_ver | sed -n -e 's/^\(.*\) version .*$/\1/p') +} + jre_specific_vm_options() { - full_ver=$(java -version 2>&1) - # java_ver is eg "18" for java 1.8, "90" for java 9.0, "100" for java 10.0.x - java_ver=$(echo $full_ver | sed -n '{ - # replace early access versions, e.g. 11-ea with 11.0.0 - s/-ea/.0.0/ - # replace versions such as 10 with 10.0.0 - s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/ - # extract the major and minor parts of the version - s/^.* version "\(.*\)\.\(.*\)\..*".*$/\1\2/p - }') - options="" + if [ "${APPNAME}" = "designer" ] + then + options="" - if [ "$java_ver" -ge 90 ] && [ "${APPNAME}" = "designer" ] - then # open internal module of javafx to reflection (for our TreeViewWrapper) - options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" - # The rest here is for RichtextFX - options+=" --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" - options+=" --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" - options+=" --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" - options+=" --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" - # Warn of remaining illegal accesses - options+=" --illegal-access=warn" + if [ "$java_ver" -ge 80 ] && [ "$java_ver" -lt 90 ] + then + # no options needed for java8. + options="" + elif [ "$java_ver" -ge 90 ] && [ "$java_ver" -lt 110 ] && [ "$java_vendor" = "java" ] + then + # java9 and java10 from oracle contain javafx as a module + # open internal module of javafx to reflection (for our TreeViewWrapper) + options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" + # The rest here is for RichtextFX + options+=" --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" + options+=" --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" + options+=" --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" + options+=" --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" + # Warn of remaining illegal accesses + options+=" --illegal-access=warn" + elif [ "$java_vendor" = "openjdk" ] || ( [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] ) + then + # openjdk and java11 from oracle onwards do not contain javafx directly + # there are no extra options either - javafx will be added to the classpath without modules + options="" + fi + + echo $options + else + echo "" fi +} - echo $options +function add_pmd_classpath() { + if [ -n "$classpath" ]; then + classpath="$classpath:${LIB_DIR}/*" + else + classpath="${LIB_DIR}/*" + fi +} + +function add_openjfx_classpath() { + if [ "${APPNAME}" = "designer" ] + then + if [ "$java_vendor" = "openjdk" ] && [ "$java_ver" -lt 100 ] + then + script_exit "For openjfx at least java 10 is required" + elif [ "$java_vendor" = "openjdk" ] || ( [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] ) + then + # openjfx is required for openjdk builds and oracle java 11 or later + if [ -z "${JAVAFX_HOME}" ] + then + script_exit "The environment variable JAVAFX_HOME is missing." + else + if [ -n "$classpath" ]; then + classpath="$classpath:${JAVAFX_HOME}/lib/*" + else + classpath="${JAVAFX_HOME}/lib/*" + fi + fi + fi + fi } readonly APPNAME="${1}" @@ -142,19 +201,12 @@ convert_cygwin_vars classpath=$CLASSPATH -cd "${CWD}" - -for jarfile in "${LIB_DIR}"/*.jar; do - if [ -n "$classpath" ]; then - classpath=$classpath:$jarfile - else - classpath=$jarfile - fi -done +add_pmd_classpath +determine_java_version +add_openjfx_classpath cygwin_paths java_heapsize_settings java ${HEAPSIZE} $(jre_specific_vm_options) -cp "${classpath}" "${CLASSNAME}" "$@" - diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 7c9ddc5239..08a9c356a8 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index d62194c4f9..c068abea1b 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 13635af528..79d409113d 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index d7f804400a..30c9b97c70 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index ed713afee8..991335622f 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -2097,8 +2097,8 @@ void ShiftExpression() #ShiftExpression(>1): AdditiveExpression() ( LOOKAHEAD(2) ( "<<" { jjtThis.setImage("<<");} - | RSIGNEDSHIFT() - | RUNSIGNEDSHIFT() + | RSIGNEDSHIFT() { jjtThis.setImage(">>"); } + | RUNSIGNEDSHIFT() { jjtThis.setImage(">>>"); } ) AdditiveExpression() )* } @@ -2585,7 +2585,7 @@ void AssertStatement() : * type declaration syntax with generics clean */ -void RUNSIGNEDSHIFT(): +void RUNSIGNEDSHIFT(): // TODO 7.0.0 make #void {} { ( LOOKAHEAD({ getToken(1).kind == GT && @@ -2594,7 +2594,7 @@ void RUNSIGNEDSHIFT(): ) } -void RSIGNEDSHIFT(): +void RSIGNEDSHIFT(): // TODO 7.0.0 make #void {} { ( LOOKAHEAD({ getToken(1).kind == GT && diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index d43dbd7a6a..329c8036a7 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRSIGNEDSHIFT.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRSIGNEDSHIFT.java index a48e0ae171..4e287e8fad 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRSIGNEDSHIFT.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRSIGNEDSHIFT.java @@ -5,6 +5,10 @@ package net.sourceforge.pmd.lang.java.ast; +/** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ +@Deprecated public class ASTRSIGNEDSHIFT extends AbstractJavaNode { public ASTRSIGNEDSHIFT(int id) { super(id); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRUNSIGNEDSHIFT.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRUNSIGNEDSHIFT.java index 15753e797d..9e2568014d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRUNSIGNEDSHIFT.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRUNSIGNEDSHIFT.java @@ -5,6 +5,10 @@ package net.sourceforge.pmd.lang.java.ast; +/** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ +@Deprecated public class ASTRUNSIGNEDSHIFT extends AbstractJavaNode { public ASTRUNSIGNEDSHIFT(int id) { super(id); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTShiftExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTShiftExpression.java index 2e664764d9..bff4995393 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTShiftExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTShiftExpression.java @@ -39,12 +39,7 @@ public class ASTShiftExpression extends AbstractJavaTypeNode { * Returns the image of the operator, i.e. "<<", ">>", or ">>>". */ public String getOperator() { - if (getImage() != null) { - return getImage(); // << - } - - ASTRSIGNEDSHIFT rsshift = (ASTRSIGNEDSHIFT) jjtGetChild(1); - return rsshift != null ? ">>" : ">>>"; + return getImage(); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java index 9e4cb65496..5a549e5977 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java @@ -133,6 +133,14 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim } + /** + * Returns the name of the variable. + */ + public String getVariableName() { + return getImage(); + } + + /** * Returns true if the variable declared by this node is declared final. * Doesn't account for the "effectively-final" nuance. Resource diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserDecoratedVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserDecoratedVisitor.java index e6bd5306e2..0e55523479 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserDecoratedVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserDecoratedVisitor.java @@ -252,14 +252,22 @@ public class JavaParserDecoratedVisitor implements JavaParserVisitor { } + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRUNSIGNEDSHIFT node, Object data) { visitor.visit(node, data); return visit((JavaNode) node, data); } + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRSIGNEDSHIFT node, Object data) { visitor.visit(node, data); return visit((JavaNode) node, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java index b62e67f9bb..210b09c0b4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorAdapter.java @@ -156,12 +156,22 @@ public class JavaParserVisitorAdapter implements JavaParserVisitor { return visit((JavaNode) node, data); } + + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRUNSIGNEDSHIFT node, Object data) { return visit((JavaNode) node, data); } + + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRSIGNEDSHIFT node, Object data) { return visit((JavaNode) node, data); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorDecorator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorDecorator.java index 028c65e96d..7451c09a30 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorDecorator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaParserVisitorDecorator.java @@ -199,13 +199,21 @@ public class JavaParserVisitorDecorator implements JavaParserControllessVisitor } + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRUNSIGNEDSHIFT node, Object data) { return visitor.visit(node, data); } + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRSIGNEDSHIFT node, Object data) { return visitor.visit(node, data); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJavaRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJavaRule.java index 73a65444ac..0e17201d7a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJavaRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/AbstractJavaRule.java @@ -230,12 +230,22 @@ public abstract class AbstractJavaRule extends AbstractRule implements JavaParse return visit((JavaNode) node, data); } + + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRUNSIGNEDSHIFT node, Object data) { return visit((JavaNode) node, data); } + + /** + * @deprecated Will be removed in 7.0.0. Use {@link ASTShiftExpression#getOperator()} + */ @Override + @Deprecated public Object visit(ASTRSIGNEDSHIFT node, Object data) { return visit((JavaNode) node, data); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java index 9b5b134de4..a70cf3ce0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java @@ -11,6 +11,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; + import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; @@ -135,8 +137,9 @@ public class AvoidUsingHardCodedIPRule extends AbstractJavaRule { // Quick check before using Regular Expression // 1) At least 3 characters // 2) 1st must be a Hex number or a : (colon) - // 3) Must contain at least 1 : (colon) - if (s.length() < 3 || !(isHexCharacter(firstChar) || firstChar == ':') || s.indexOf(':') < 0) { + // 3) Must contain at least 2 colons (:) + if (s.length() < 3 || !(isHexCharacter(firstChar) || firstChar == ':') + || StringUtils.countMatches(s, ':') < 2) { return false; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java index f68dcb2556..0cfc4f2e5a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java @@ -11,6 +11,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.RegexProperty; +import net.sourceforge.pmd.properties.StringMultiProperty; /** @@ -20,6 +21,14 @@ import net.sourceforge.pmd.properties.RegexProperty; * @since 6.7.0 */ public class FieldNamingConventionsRule extends AbstractNamingConventionRule { + // TODO we need a more powerful scheme to match some fields, e.g. include modifiers/type + // We could define a new property, but specifying property values as a single string doesn't scale + private static final StringMultiProperty EXCLUDED_NAMES = StringMultiProperty.named("exclusions") + .desc("Names of fields to whitelist.") + .defaultValues("serialVersionUID") + .build(); + + private final RegexProperty publicConstantFieldRegex = defaultProp("public constant").defaultValue("[A-Z][A-Z_0-9]*").build(); private final RegexProperty constantFieldRegex = defaultProp("constant").desc("Regex which applies to non-public static final field names").defaultValue("[A-Z][A-Z_0-9]*").build(); private final RegexProperty enumConstantRegex = defaultProp("enum constant").defaultValue("[A-Z][A-Z_0-9]*").build(); @@ -35,6 +44,7 @@ public class FieldNamingConventionsRule extends AbstractNamingConventionRule prefixes = getProperty(TRANSFORM_METHOD_NAMES_PROPERTY); + String[] splitMethodName = StringUtils.splitByCharacterTypeCamelCase(nameOfMethod); + if (resultType.isVoid() && splitMethodName.length > 0 + && prefixes.contains(splitMethodName[0].toLowerCase(Locale.ROOT))) { + // "To" or any other configured prefix found addViolationWithMessage(data, node, "Linguistics Antipattern - The transform method ''{0}'' should not return void linguistically", new Object[] { nameOfMethod }); } @@ -93,10 +107,15 @@ public class LinguisticNamingRule extends AbstractJavaRule { private void checkTransformMethods(ASTMethodDeclaration node, Object data, String nameOfMethod) { ASTResultType resultType = node.getResultType(); - if (resultType.isVoid() && containsWord(nameOfMethod, "To")) { - // To in the middle somewhere - addViolationWithMessage(data, node, "Linguistics Antipattern - The transform method ''{0}'' should not return void linguistically", - new Object[] { nameOfMethod }); + List infixes = getProperty(TRANSFORM_METHOD_NAMES_PROPERTY); + for (String infix : infixes) { + if (resultType.isVoid() && containsWord(nameOfMethod, StringUtils.capitalize(infix))) { + // "To" or any other configured infix in the middle somewhere + addViolationWithMessage(data, node, "Linguistics Antipattern - The transform method ''{0}'' should not return void linguistically", + new Object[] { nameOfMethod }); + // the first violation is sufficient - it is still the same method we are analyzing here + break; + } } } @@ -116,12 +135,16 @@ public class LinguisticNamingRule extends AbstractJavaRule { } } + private boolean isBooleanType(ASTType node) { + return "boolean".equalsIgnoreCase(node.getTypeImage()) || TypeHelper.isA(node, "java.util.concurrent.atomic.AtomicBoolean"); + } + private void checkBooleanMethods(ASTMethodDeclaration node, Object data, String nameOfMethod) { ASTResultType resultType = node.getResultType(); ASTType t = node.getResultType().getFirstChildOfType(ASTType.class); if (!resultType.isVoid() && t != null) { for (String prefix : getProperty(BOOLEAN_METHOD_PREFIXES_PROPERTY)) { - if (hasPrefix(nameOfMethod, prefix) && !"boolean".equalsIgnoreCase(t.getTypeImage())) { + if (hasPrefix(nameOfMethod, prefix) && !isBooleanType(t)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The method ''{0}'' indicates linguistically it returns a boolean, but it returns ''{1}''", new Object[] { nameOfMethod, t.getTypeImage() }); } @@ -129,20 +152,20 @@ public class LinguisticNamingRule extends AbstractJavaRule { } } - private void checkField(String typeImage, ASTVariableDeclarator node, Object data) { + private void checkField(ASTType typeNode, ASTVariableDeclarator node, Object data) { for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) { - if (hasPrefix(node.getName(), prefix) && !"boolean".equalsIgnoreCase(typeImage)) { + if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The field ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''", - new Object[] { node.getName(), typeImage }); + new Object[] { node.getName(), typeNode.getTypeImage() }); } } } - private void checkVariable(String typeImage, ASTVariableDeclarator node, Object data) { + private void checkVariable(ASTType typeNode, ASTVariableDeclarator node, Object data) { for (String prefix : getProperty(BOOLEAN_FIELD_PREFIXES_PROPERTY)) { - if (hasPrefix(node.getName(), prefix) && !"boolean".equalsIgnoreCase(typeImage)) { + if (hasPrefix(node.getName(), prefix) && !isBooleanType(typeNode)) { addViolationWithMessage(data, node, "Linguistics Antipattern - The variable ''{0}'' indicates linguistically it is a boolean, but it is ''{1}''", - new Object[] { node.getName(), typeImage }); + new Object[] { node.getName(), typeNode.getTypeImage() }); } } } @@ -153,7 +176,7 @@ public class LinguisticNamingRule extends AbstractJavaRule { if (type != null && getProperty(CHECK_FIELDS)) { List fields = node.findChildrenOfType(ASTVariableDeclarator.class); for (ASTVariableDeclarator field : fields) { - checkField(type.getTypeImage(), field, data); + checkField(type, field, data); } } return data; @@ -165,7 +188,7 @@ public class LinguisticNamingRule extends AbstractJavaRule { if (type != null && getProperty(CHECK_VARIABLES)) { List variables = node.findChildrenOfType(ASTVariableDeclarator.class); for (ASTVariableDeclarator variable : variables) { - checkVariable(type.getTypeImage(), variable, data); + checkVariable(type, variable, data); } } return data; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableNamingConventionsRule.java index 093cff17f6..3e79516e91 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableNamingConventionsRule.java @@ -23,6 +23,7 @@ import net.sourceforge.pmd.properties.BooleanProperty; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.StringMultiProperty; +@Deprecated public class VariableNamingConventionsRule extends AbstractJavaRule { private boolean checkMembers; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidSlf4jMessageFormatRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidSlf4jMessageFormatRule.java index 86ab80b76c..55d90ff474 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidSlf4jMessageFormatRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidSlf4jMessageFormatRule.java @@ -10,9 +10,13 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; +import org.jaxen.JaxenException; +import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType; @@ -26,13 +30,14 @@ import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; -import net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode; +import net.sourceforge.pmd.lang.java.ast.ASTVariableInitializer; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration; import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper; import net.sourceforge.pmd.lang.symboltable.NameDeclaration; public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { + private static final Logger LOG = Logger.getLogger(InvalidSlf4jMessageFormatRule.class.getName()); private static final Set LOGGER_LEVELS; private static final String LOGGER_CLASS = "org.slf4j.Logger"; @@ -42,18 +47,22 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { .unmodifiableSet(new HashSet(Arrays.asList("trace", "debug", "info", "warn", "error"))); } + public InvalidSlf4jMessageFormatRule() { + addRuleChainVisit(ASTName.class); + } + @Override public Object visit(final ASTName node, final Object data) { final NameDeclaration nameDeclaration = node.getNameDeclaration(); // ignore imports or methods if (!(nameDeclaration instanceof VariableNameDeclaration)) { - return super.visit(node, data); + return data; } // ignore non slf4j logger Class type = ((VariableNameDeclaration) nameDeclaration).getType(); if (type == null || !type.getName().equals(LOGGER_CLASS)) { - return super.visit(node, data); + return data; } // get the node that contains the logger @@ -65,7 +74,7 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { // ignore if not a log level if (!LOGGER_LEVELS.contains(method)) { - return super.visit(node, data); + return data; } // find the arguments @@ -73,13 +82,13 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { .getFirstDescendantOfType(ASTArgumentList.class).findChildrenOfType(ASTExpression.class); // remove the message parameter - final ASTPrimaryExpression messageParam = argumentList.remove(0).getFirstDescendantOfType(ASTPrimaryExpression.class); + final ASTExpression messageParam = argumentList.remove(0); final int expectedArguments = expectedArguments(messageParam); if (expectedArguments == 0) { // ignore if we are not expecting arguments to format the message // or if we couldn't analyze the message parameter - return super.visit(node, data); + return data; } // Remove throwable param, since it is shown separately. @@ -89,12 +98,14 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { } if (argumentList.size() < expectedArguments) { - addViolationWithMessage(data, node, "Missing arguments," + getExpectedMessage(argumentList, expectedArguments)); + addViolationWithMessage(data, node, + "Missing arguments," + getExpectedMessage(argumentList, expectedArguments)); } else if (argumentList.size() > expectedArguments) { - addViolationWithMessage(data, node, "Too many arguments," + getExpectedMessage(argumentList, expectedArguments)); + addViolationWithMessage(data, node, + "Too many arguments," + getExpectedMessage(argumentList, expectedArguments)); } - return super.visit(node, data); + return data; } private boolean isNewThrowable(ASTPrimaryExpression last) { @@ -145,7 +156,7 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { + params.size(); } - private int expectedArguments(final ASTPrimaryExpression node) { + private int expectedArguments(final ASTExpression node) { int count = 0; // look if the logger have a literal message if (node.getFirstDescendantOfType(ASTLiteral.class) != null) { @@ -153,7 +164,8 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { } else if (node.getFirstDescendantOfType(ASTName.class) != null) { final String variableName = node.getFirstDescendantOfType(ASTName.class).getImage(); // look if the message is defined locally - final List localVariables = node.getFirstParentOfType(ASTMethodOrConstructorDeclaration.class) + final List localVariables = node + .getFirstParentOfType(ASTMethodOrConstructorDeclaration.class) .findDescendantsOfType(ASTVariableDeclarator.class); count = getAmountOfExpectedArguments(variableName, localVariables); @@ -176,17 +188,36 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule { for (final ASTVariableDeclarator astVariableDeclarator : variables) { if (astVariableDeclarator.getFirstChildOfType(ASTVariableDeclaratorId.class).getImage() .equals(variableName)) { - return countPlaceholders(astVariableDeclarator); + ASTVariableInitializer variableInitializer = astVariableDeclarator + .getFirstDescendantOfType(ASTVariableInitializer.class); + ASTExpression expression = null; + if (variableInitializer != null) { + expression = variableInitializer.getFirstChildOfType(ASTExpression.class); + } + if (expression != null) { + return countPlaceholders(expression); + } } } return 0; } - private int countPlaceholders(final AbstractJavaTypeNode node) { - int result = 0; // zero means, no placeholders, or we could not analyze the message parameter - ASTLiteral stringLiteral = node.getFirstDescendantOfType(ASTLiteral.class); - if (stringLiteral != null) { - result = StringUtils.countMatches(stringLiteral.getImage(), "{}"); + private int countPlaceholders(final ASTExpression node) { + // zero means, no placeholders, or we could not analyze the message parameter + int result = 0; + + try { + List literals = node + .findChildNodesWithXPath( + "AdditiveExpression/PrimaryExpression/PrimaryPrefix/Literal[@StringLiteral='true']" + + "|PrimaryExpression/PrimaryPrefix/Literal[@StringLiteral='true']"); + // if there are multiple literals, we just assume, they are concatenated + // together... + for (Node stringLiteral : literals) { + result += StringUtils.countMatches(stringLiteral.getImage(), "{}"); + } + } catch (JaxenException e) { + LOG.log(Level.FINE, "Could not determine literals", e); } return result; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java index fe05d8a9b7..f4f328e616 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.java.rule.performance; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -85,7 +86,7 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule { @Override public Object visit(ASTVariableDeclaratorId node, Object data) { - if (!isStringBuffer(node)) { + if (!isStringBuilderOrBuffer(node)) { return data; } threshold = getProperty(THRESHOLD_DESCRIPTOR); @@ -96,33 +97,22 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule { } Node lastBlock = getFirstParentBlock(node); Node currentBlock = lastBlock; - Map> decls = node.getScope() - .getDeclarations(VariableNameDeclaration.class); Node rootNode = null; // only want the constructor flagged if it's really containing strings if (concurrentCount >= 1) { rootNode = node; } - for (List decl : decls.values()) { - for (NameOccurrence no : decl) { - JavaNameOccurrence jno = (JavaNameOccurrence) no; - Node n = jno.getLocation(); - // skip the declarations/usages, that deal with a different - // variable - if (!node.getImage().equals(jno.getImage())) { - continue; - } + List usages = determineUsages(node); - currentBlock = getFirstParentBlock(n); + for (NameOccurrence no : usages) { + JavaNameOccurrence jno = (JavaNameOccurrence) no; + Node n = jno.getLocation(); - if (!InefficientStringBufferingRule.isInStringBufferOperation(n, 3, "append")) { - if (!jno.isPartOfQualifiedName()) { - checkForViolation(rootNode, data, concurrentCount); - concurrentCount = 0; - } - continue; - } + currentBlock = getFirstParentBlock(n); + + if (InefficientStringBufferingRule.isInStringBufferOperation(n, 3, "append")) { + // append method call detected ASTPrimaryExpression s = n.getFirstParentOfType(ASTPrimaryExpression.class); int numChildren = s.jjtGetNumChildren(); for (int jx = 0; jx < numChildren; jx++) { @@ -156,12 +146,32 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule { } lastBlock = currentBlock; } + } else if (n.getImage().endsWith(".toString") || n.getImage().endsWith(".length")) { + // ignore toString and length, they do not change affect the content of the sb + } else { + // usage of the stringbuilder variable for any other purpose, including + // calling e.g. delete + checkForViolation(rootNode, data, concurrentCount); + concurrentCount = 0; } } checkForViolation(rootNode, data, concurrentCount); return data; } + private List determineUsages(ASTVariableDeclaratorId node) { + Map> decls = node.getScope() + .getDeclarations(VariableNameDeclaration.class); + for (Map.Entry> entry : decls.entrySet()) { + // find the first variable that matches + if (node.hasImageEqualTo(entry.getKey().getName())) { + return entry.getValue(); + } + } + + return Collections.emptyList(); + } + /** * Determine if the constructor contains (or ends with) a String Literal * @@ -376,10 +386,8 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule { return n instanceof ASTLiteral; } - private static boolean isStringBuffer(ASTVariableDeclaratorId node) { - + private static boolean isStringBuilderOrBuffer(ASTVariableDeclaratorId node) { if (node.getType() != null) { - // return node.getType().equals(StringBuffer.class); return TypeHelper.isEither(node, StringBuffer.class, StringBuilder.class); } Node nn = node.getTypeNameNode(); diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 4e7d4fa7eb..0b875ad295 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -226,9 +226,6 @@ Application with hard-coded IP addresses can become impossible to deploy in some Externalizing IP adresses is preferable. 3 - - - 1] [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] +| +//FieldDeclaration + [count(VariableDeclarator) > 1] + [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] ]]> diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index f80f81051b..9a9138a4f0 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -126,6 +126,7 @@ public class MyClass { @@ -980,7 +981,8 @@ if (foo) { // preferred approach since="6.7.0" message="Linguistics Antipattern - Method name and return type is inconsistent linguistically" class="net.sourceforge.pmd.lang.java.rule.codestyle.LinguisticNamingRule" - externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#linguisticnaming"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#linguisticnaming" + typeResolution="true"> This rule finds Linguistic Naming Antipatterns. It checks for fields, that are named, as if they should be boolean but have a different type. It also checks for methods, that according to their name, should @@ -1294,6 +1296,7 @@ public class Foo { @@ -1616,6 +1619,7 @@ public class Something { @@ -1992,6 +1996,7 @@ public class Foo { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java index e2fb35e5ed..840fdefd5d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java @@ -35,6 +35,7 @@ public class CodeStyleRulesTest extends SimpleAggregatorTst { addRule(RULESET, "EmptyMethodInAbstractClassShouldBeAbstract"); addRule(RULESET, "ExtendsObject"); addRule(RULESET, "FieldDeclarationsShouldBeAtStartOfClass"); + addRule(RULESET, "FieldNamingConventions"); addRule(RULESET, "ForLoopsMustUseBraces"); addRule(RULESET, "ForLoopShouldBeWhileLoop"); addRule(RULESET, "FormalParameterNamingConventions"); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml index 703082a119..bd8457e1d0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml @@ -23,6 +23,7 @@ public class Foo { "0", "0000000000000", "2001:0db8:0000:0000:0000:0000:1428:57ab:0000", + ":bee", // IPv4 "0.0.0.0", @@ -43,7 +44,8 @@ public class Foo { "::ffff:0c22:384e", "0:0:0:0:0:ffff:0c22:384e", "ff00::", - + "::bee", + // IPv4 mapped IPv6 "2001:0db8:0000:0000:0000:0000:12.34.56.78", "::ffff:12.34.56.78", @@ -120,7 +122,7 @@ public class Foo { - 20 + 21 @@ -144,7 +146,7 @@ Comprehensive, check for IPv4 Comprehensive, check for IPv6 ]]> IPv6 - 10 + 11 @@ -160,7 +162,7 @@ Comprehensive, check for IPv4 mapped IPv6 Comprehensive, check for IPv6 and IPv4 mapped IPv6 ]]> IPv6|IPv4 mapped IPv6 - 14 + 15 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml index 72b07d6c97..39768c6233 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml @@ -62,6 +62,30 @@ public class Foo { String name, lastname; } +} + ]]> + + + + Check for field declarations without strictMode + false + 0 + + + + + Check for field declarations with strictMode + true + 1 + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/FieldNamingConventions.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/FieldNamingConventions.xml index 33e5c0c50f..a6d343bcb6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/FieldNamingConventions.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/FieldNamingConventions.xml @@ -128,10 +128,13 @@ Test public constant property cons_[A-Z][A-Z0-9]+ - 2 + 5 + The field name 'Foo' doesn't match '[a-z][a-zA-Z0-9]*' + The final field name 'Hoo' doesn't match '[a-z][a-zA-Z0-9]*' + The static field name 'Bar' doesn't match '[a-z][a-zA-Z0-9]*' + The constant name 'cons_BOLG_FIELD' doesn't match '[A-Z][A-Z_0-9]*' The public constant name 'DDD' doesn't match 'cons_[A-Z][A-Z0-9]+' - The constant name 'cons_BOLG_FIELD' doesn't match '[A-Z][A-Z0-9]+' - Interface fields should be treated like constants + Interface fields should be treated like public constants 3 - The constant name 'Foo' doesn't match '[A-Z][A-Z_0-9]*' - The constant name 'Hoo' doesn't match '[A-Z][A-Z_0-9]*' - The constant name 'Bar' doesn't match '[A-Z][A-Z_0-9]*' + The public constant name 'Foo' doesn't match '[A-Z][A-Z_0-9]*' + The public constant name 'Hoo' doesn't match '[A-Z][A-Z_0-9]*' + The public constant name 'Bar' doesn't match '[A-Z][A-Z_0-9]*' + + + + Exclude serialVersionUID by default + 0 + + + + + More exclusions can be configured + m$mangled + 0 + + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml index 68a35fabcf..006b005d35 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml @@ -221,6 +221,31 @@ public class MethodTypeAndNameIsInconsistentWithPrefixTo { ]]> + + Method Prefix as: Transform Method with property configuration + as + 1 + 6 + + Linguistics Antipattern - The transform method 'asDataType' should not return void linguistically + + + + Method Contains To: Transformation methods true @@ -245,6 +270,31 @@ public class MethodTypeAndNameIsInconsistentWithPrefixTo { ]]> + + Method Contains As: Transformation methods with configured infix + true + as + 1 + 2 + + Linguistics Antipattern - The transform method 'grapeAsWine' should not return void linguistically + + + + Field/Variable Prefix is 2 @@ -411,6 +461,94 @@ public class BooleanFieldsMethodFP { public void myMethod() { Boolean hasLegs; } +} + ]]> + + + + #1334 [java] LinguisticNaming should support AtomicBooleans + 0 + + + + + #1334 [java] LinguisticNaming should support AtomicBooleans false negative + 18 + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidSlf4jMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidSlf4jMessageFormat.xml index 4163fdb66c..0cbc4296a5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidSlf4jMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidSlf4jMessageFormat.xml @@ -240,5 +240,33 @@ public class Foo ]]> - + + #1291 [java] InvalidSlf4jMessageFormat false positive: too many arguments with string concatenation operator + 0 + + \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml index c29969df76..9e3d41b59f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml @@ -1344,6 +1344,77 @@ public class Foo { s.append('h'); s.append("ello"); } +} + ]]> + + + + #1325 [java] False positive in ConsecutiveLiteralAppends + 0 + builder + .append(k) + .append(" = ") + .append(valueToStringFunction.apply(v)) + .append(", ")); + int length = builder.length(); + if (length > 1) { + builder.delete(length - 2, length); + } + builder.append(']'); + return builder.toString(); + } +} + ]]> + + + + FN append inside if statement + 2 + 12,13 + + + + + FP with constructor, append in while + 0 + diff --git a/pmd-java8/pom.xml b/pmd-java8/pom.xml index 2fa4054c77..b9fda3ebcc 100644 --- a/pmd-java8/pom.xml +++ b/pmd-java8/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index e6c8d5a17a..bacddc1155 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 614119b8e5..897bbcd3cc 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index c08b83faa1..08d1f1abf8 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 049e8bc890..868abfc638 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 70f6d334e7..527f8ba177 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 83b4e422a5..843498aacd 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 1936e058cc..dbfdcef557 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index a88254c11c..d9d74f909b 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 99fb66a08e..f67a53fcb3 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-scala/pom.xml b/pmd-scala/pom.xml index b8837419a4..eceaa262b0 100644 --- a/pmd-scala/pom.xml +++ b/pmd-scala/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index e3dfbd9d6e..371576e5aa 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index f525c34b05..873e8a371b 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-ui/pom.xml b/pmd-ui/pom.xml index d572e7050e..4ff9460aa4 100644 --- a/pmd-ui/pom.xml +++ b/pmd-ui/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT @@ -15,6 +15,8 @@ 1.${java.version} 1.${java.version} + + 11-ea+19 @@ -29,15 +31,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - ${java.version} - ${java.version} - - - @@ -76,13 +69,51 @@ net.sourceforge.pmd pmd-core - ${project.version} net.sourceforge.pmd pmd-java ${project.version} + + + + org.openjfx + javafx-base + ${openjfx.version} + provided + + + org.openjfx + javafx-controls + ${openjfx.version} + provided + + + org.openjfx + javafx-fxml + ${openjfx.version} + provided + + + org.openjfx + javafx-graphics + ${openjfx.version} + provided + + + org.openjfx + javafx-media + ${openjfx.version} + provided + + + org.openjfx + javafx-web + ${openjfx.version} + provided + + org.fxmisc.richtext richtextfx diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 402ba937cf..6bd353e38c 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-vm/pom.xml b/pmd-vm/pom.xml index 9b004b42ee..04d669d5b9 100644 --- a/pmd-vm/pom.xml +++ b/pmd-vm/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 5c879bb41b..e1cd6a0fb7 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 16c89019e2..57df22d03d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 6.7.0-SNAPSHOT + 6.8.0-SNAPSHOT pom PMD @@ -445,12 +445,12 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code net.sourceforge.pmd pmd-core - 6.5.0 + 6.6.0 net.sourceforge.pmd pmd-java - 6.5.0 + 6.6.0 @@ -473,7 +473,7 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code org.jacoco jacoco-maven-plugin - 0.8.1 + 0.8.2 @@ -519,7 +519,7 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code - [9,) + [10,) @@ -965,6 +965,49 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code org.eluder.coveralls coveralls-maven-plugin 4.3.0 + + + + javax.xml.bind + jaxb-api + 2.3.0 + + + + + + + + + sonar + + https://sonarcloud.io + + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.4.1.1168 + + + + + + org.jacoco + jacoco-maven-plugin + + + default-prepare-agent + + prepare-agent + + +