From 115a93d6c5059148009c2d2cc819431841e6ec2b Mon Sep 17 00:00:00 2001 From: "Travis CI (pmd-bot)" Date: Sun, 16 Feb 2020 11:29:34 +0000 Subject: [PATCH] Update documentation TRAVIS_JOB_NUMBER=4815.2 TRAVIS_COMMIT_RANGE=de622bcbaec9...7fb09deb3d0f --- 404.html | 18 +- css/pmd-customstyles.css | 32 + feed.xml | 4 +- .../userdocs/designer-overview-with-nums.png | Bin 0 -> 132019 bytes images/userdocs/designer-overview.png | Bin 0 -> 103341 bytes index.html | 133 +- js/mydoc_scroll.html | 18 +- license.html | 18 +- news.html | 18 +- news_archive.html | 18 +- pmd_about_help.html | 18 +- pmd_apex_metrics_index.html | 18 +- pmd_devdocs_building.html | 18 +- pmd_devdocs_development.html | 18 +- pmd_devdocs_experimental_ast_dump.html | 28 +- pmd_devdocs_how_pmd_works.html | 18 +- ...devdocs_major_adding_new_cpd_language.html | 30 +- pmd_devdocs_major_adding_new_language.html | 18 +- ...cs_major_adding_new_metrics_framework.html | 93 +- pmd_devdocs_pmdtester.html | 18 +- pmd_devdocs_roadmap.html | 18 +- pmd_devdocs_rule_deprecation_policy.html | 18 +- pmd_devdocs_writing_documentation.html | 42 +- pmd_java_metrics_index.html | 34 +- pmd_languages_jsp.html | 18 +- pmd_next_major_development.html | 390 ++-- ...docs_committers_merging_pull_requests.html | 18 +- pmd_projectdocs_committers_releasing.html | 18 +- pmd_projectdocs_credits.html | 18 +- pmd_projectdocs_faq.html | 18 +- pmd_projectdocs_trivia_meaning.html | 18 +- pmd_projectdocs_trivia_news.html | 18 +- pmd_projectdocs_trivia_products.html | 18 +- pmd_projectdocs_trivia_similarprojects.html | 18 +- pmd_release_notes.html | 109 +- pmd_release_notes_old.html | 46 +- pmd_rules_apex.html | 18 +- pmd_rules_apex_bestpractices.html | 50 +- pmd_rules_apex_codestyle.html | 48 +- pmd_rules_apex_design.html | 40 +- pmd_rules_apex_documentation.html | 20 +- pmd_rules_apex_errorprone.html | 36 +- pmd_rules_apex_performance.html | 34 +- pmd_rules_apex_security.html | 58 +- pmd_rules_ecmascript.html | 18 +- pmd_rules_ecmascript_bestpractices.html | 30 +- pmd_rules_ecmascript_codestyle.html | 20 +- pmd_rules_ecmascript_errorprone.html | 18 +- pmd_rules_java.html | 18 +- pmd_rules_java_bestpractices.html | 202 ++- pmd_rules_java_codestyle.html | 166 +- pmd_rules_java_design.html | 124 +- pmd_rules_java_documentation.html | 18 +- pmd_rules_java_errorprone.html | 312 ++-- pmd_rules_java_multithreading.html | 62 +- pmd_rules_java_performance.html | 146 +- pmd_rules_java_security.html | 24 +- pmd_rules_jsp.html | 18 +- pmd_rules_jsp_bestpractices.html | 64 +- pmd_rules_jsp_codestyle.html | 22 +- pmd_rules_jsp_design.html | 64 +- pmd_rules_jsp_errorprone.html | 26 +- pmd_rules_jsp_security.html | 44 +- pmd_rules_modelica.html | 18 +- pmd_rules_modelica_bestpractices.html | 18 +- pmd_rules_plsql.html | 18 +- pmd_rules_plsql_bestpractices.html | 18 +- pmd_rules_plsql_codestyle.html | 20 +- pmd_rules_plsql_design.html | 28 +- pmd_rules_plsql_errorprone.html | 32 +- pmd_rules_pom.html | 18 +- pmd_rules_pom_errorprone.html | 18 +- pmd_rules_scala.html | 18 +- pmd_rules_vf.html | 18 +- pmd_rules_vf_security.html | 18 +- pmd_rules_vm.html | 18 +- pmd_rules_vm_bestpractices.html | 18 +- pmd_rules_vm_design.html | 18 +- pmd_rules_vm_errorprone.html | 18 +- pmd_rules_xml.html | 18 +- pmd_rules_xml_errorprone.html | 18 +- pmd_rules_xsl.html | 18 +- pmd_rules_xsl_codestyle.html | 18 +- pmd_rules_xsl_performance.html | 18 +- pmd_userdocs_best_practices.html | 18 +- pmd_userdocs_cli_reference.html | 18 +- pmd_userdocs_configuring_rules.html | 18 +- pmd_userdocs_cpd.html | 24 +- ...serdocs_extending_defining_properties.html | 253 ++- ...userdocs_extending_designer_reference.html | 18 +- pmd_userdocs_extending_metrics_howto.html | 88 +- pmd_userdocs_extending_rule_guidelines.html | 62 +- pmd_userdocs_extending_testing.html | 22 +- ...userdocs_extending_writing_java_rules.html | 1571 +++++++++++++++++ pmd_userdocs_extending_writing_pmd_rules.html | 347 +--- ...serdocs_extending_writing_rules_intro.html | 1547 ++++++++++++++++ ...serdocs_extending_writing_xpath_rules.html | 523 ++++-- pmd_userdocs_extending_your_first_rule.html | 1542 ++++++++++++++++ pmd_userdocs_incremental_analysis.html | 18 +- pmd_userdocs_installation.html | 18 +- pmd_userdocs_making_rulesets.html | 18 +- pmd_userdocs_suppressing_warnings.html | 40 +- pmd_userdocs_tools.html | 18 +- pmd_userdocs_tools_ant.html | 18 +- pmd_userdocs_tools_ci.html | 18 +- pmd_userdocs_tools_gradle.html | 18 +- pmd_userdocs_tools_java_api.html | 126 +- pmd_userdocs_tools_maven.html | 18 +- search.json | 54 +- sitemap.xml | 18 + tag_devdocs.html | 38 +- tag_extending.html | 62 +- tag_getting_started.html | 44 +- tag_languages.html | 38 +- tag_metrics.html | 38 +- tag_release_notes.html | 38 +- tag_rule_references.html | 38 +- tag_tools.html | 38 +- tag_troubleshooting.html | 38 +- tag_userdocs.html | 62 +- titlepage/index.html | 20 +- tocpage/index.html | 18 +- 122 files changed, 8343 insertions(+), 2021 deletions(-) create mode 100644 images/userdocs/designer-overview-with-nums.png create mode 100644 images/userdocs/designer-overview.png create mode 100644 pmd_userdocs_extending_writing_java_rules.html create mode 100644 pmd_userdocs_extending_writing_rules_intro.html create mode 100644 pmd_userdocs_extending_your_first_rule.html diff --git a/404.html b/404.html index ebb6228da9..221ce3777c 100644 --- a/404.html +++ b/404.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1373,7 +1385,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/css/pmd-customstyles.css b/css/pmd-customstyles.css index 2738de8db1..7683ae54d8 100644 --- a/css/pmd-customstyles.css +++ b/css/pmd-customstyles.css @@ -52,3 +52,35 @@ details[open] summary { background-color: #347DBE; color: white; } + + +.hiddenRow { + padding: 0 !important; +} + +.xpath-fun-doc .fun-name { + font-weight: bold; +} + +.xpath-fun-doc .fun-details-header { + font-family: monospace; + font-size: larger; +} + +.xpath-fun-doc .fun-ns { + color: darkgray; +} + +.xpath-fun-doc span.param-name { + font-weight: normal; + +} + +.xpath-fun-doc span.param-type { + font-weight: lighter; + font-style: italic; + color: darkgray; +} +.xpath-fun-doc .code-examples dt { + font-weight: normal; +} diff --git a/feed.xml b/feed.xml index 855a98cc03..20e3be1e08 100644 --- a/feed.xml +++ b/feed.xml @@ -5,8 +5,8 @@ Intended as a documentation theme based on Jekyll for technical writers documenting software and other technical products, this theme has all the elements you would need to handle multiple products with both multi-level sidebar navigation, tags, and other documentation features. https://pmd.github.io/pmd/ - Sat, 15 Feb 2020 18:15:42 +0000 - Sat, 15 Feb 2020 18:15:42 +0000 + Sun, 16 Feb 2020 11:28:58 +0000 + Sun, 16 Feb 2020 11:28:58 +0000 Jekyll v3.8.5 diff --git a/images/userdocs/designer-overview-with-nums.png b/images/userdocs/designer-overview-with-nums.png new file mode 100644 index 0000000000000000000000000000000000000000..2851fd8ae667028af3e55aefbb9e6f821ac53aac GIT binary patch literal 132019 zcmcG#W0Yjw(gs*Ycd5JVt}ffQyKLK5mu;)dwr$(CnPuCq$-eKs_nU9lteHPED_5S( zqrLZu*b)1Qc;bZ0N{hmO!TJIM0s=4gOGq9B1i}^s1Z)8Y3V5X08Lb2O1Ent^Dg^TR z_mkaG6bC#4Yx_&h9t7ko^4~8gNNPF;@F287?bnba}Dr zxUt}P{>2aFtFVw;3?APv0W2i>UzaK4lEw#{0DRwR0VRTy!+S2CXhY*k?!$5JeXoOc z`-J&;6sZL!^)<^Qc&N7ug(d6p%~TBD1nE zGjerhl@bzJu)RRh{QL#&S~S_TaEql$Qwzn;VgGw)I(S%a_8fU~1PK*A+R3T8nVDJ7 zj>+J(xy2A|w;wYdhK73^gw=ogfgzX#mzukBVdBa};LxNg=kFoo)3Er;(b2=_!wl25 zLDPf%-XOvyPW2YLAaHiE>R24VZ(%L&}r zV7LB9Tz9tLyZ`pre|;A!>3Jf&nf8J3h)Dm&c5{|6d_Og@HKz7CT5V}S4J zYhpc4G=HVQ69X4utUbk8#nt;HE4-Qjl>T*w$U>cBr#F6T;Wtd&@XhIzh@tZXJ~i?% zX;BBwx2e*fV~>}8GuD?6%z0IpQVpPRs zWlC=uFe>J*`wfd_kNy~i@6&Lhk4C#LZ8auym-9U=w9|l;-kc8x+`BEo%3F=UgNs)X z_*iU|Cb-=xjP7XKP_))vyDCplFQ8kNP4u7PQ??wqTvtbNyk%kO+@}UXaG0~_78;F~ z+dV@cWF~3Au^7^b3u1g;=`?%(!r(_^t6m8E(3?O3&CFZy%0gdViG4REmddLUcrSol6RF6#&OMu(-yVL73APHXu3 zV&u`N%T0W~3VX|Z(NomoX$nCA+UY`ReMapVk9wiI;Md~OngcfET3S{|F@-5l*;K86 zNR(?Jq1M?_8VqFvBFHdjjVty8!D&3TC#Vi#69Y!F<&PM$NDT9j&?i~waJ*0W&k6gi zJw`XbxuWZ%-6p#6)<|z@_ppJA;HWBHX`HDlFXqVbxt~`>k)wW69v_=+9;tI4J1Bfo`3Gnz6+iT(8f`cJx%`}eGHhV4kh<~Tcr1>7N zgmE1{`G{xA$4v0L$5;i(c=E@$krB_844tRCvSDOM8<5)C+C52Rfsm~41HViyx#W6+ zgXC~UBxv0bPlPY;Vj@DkW8FX6kg+)gdIjjovXAnTUB-yVT|MZTp{tVMJxT1x$RrNm z$2)qD3;cgKFrFV(zM9`*ybFfNd?nyH2P2VI@4JoW8B#&Lu)bZOXJq|Tx)<7wlI()}5=cmCP1K^TzP;_I8PB&0fDp@n@Mo z$?lSOmu~YBY3|YK5%)RPbqVl%8gJT;;6+vY>EiVo4RiO%Jv#1bJ%57g(RqzFOB<%& zi;CHv)bzX#{XGx~C>o!-P4L4R($D_R*zfZ4v45p0`FSK58~0l44B)|g-Oci9MCGs> zZO~+M0z;3==*}mf+k^WnRHlTm7DNW?w**bEK71EfE9%l6skekUOydh2W5HfOM1;mK z2jdngscyD5XaiX>OIl)nIk%-Mhxp>O29IVk$xft*?X3a1PFG>ge_rv^f5rdicupNo zXyO@MTbU>h3ye4=Wt;{{9=eGhkWjt7=UmUog+|FO?C8DOmr(sUQT!>B*f=@bU4nRZ z5^S&9YRGfT>k<`AO1fK>?xmGc&s8L;L-50jLgwSt6OBf@zxKKAX>Wp;fmjve_KqF&igSeF|d!sN}R-qPLdQFB*(*7=#1L!xQC(k5!tBCxK4@B*^ z2?&N?;=N@89r!^iMBX zh>*>iKK+xtor%@#e3RSZTwc{-qb2l)|L~|fX81;a^g+jbUkm@?O{fipPqj_1>9L0Y zysH!gJ?4P5zc@hmdv*X$3~tDrDVsI9TAg`SJ$fYRyEq`9&%tFmPQypb!f5P8i;Wqw z3)KG?3y4ch>lSJs`n3ZMLUkIJ&xtPI|2 zkmuCT9@k2E)+ps>$9Fs!7lvfuf@sqxFTC7jB`ebjBjX`ffS<7(?^Srs2p*FWK(R)h1lZUG`si&4ISjRhx zE&9!cmWti={#^6+=8~$KvqwvO_SY6iaT^cYYWGD0$&MZIN;fmgjf?KwhU&d3h336c zotw88W5ofX)nWn&N)uJIhV`H@+~ZdxPS={If3p@jCi0p+tJcwbNqas1NBWS6B&waeG*|kN_^2~ za|~a^F#9VEku0=SQCw9eS-5!chVR&MVPk3AuFLLj1qd!%dWKH!VzV#m+J*jdh-od9 z=v9t8jM_K1`5^f6Wn*3%Q+-(29#K%b?-=W@a|zC-KM9MtC4cjAeqOe~r%!YaN1fZ; z4g+x49XEvYhoE=M8mEuG{OHdWwX!N~Xxr!hlD?QqGZESc`{cH}OUNAz1cY|d;B1#2 zk2HTlfr@Vi`|Bj<+ruMbdK?%Io2=995-kqrcDk~u^@TKhSpd?G ziLjsoH`^K(8SUo43vm{MyDPmDNCu`iFRm$WeFICi&&%A%5PP zV0miX1c-{7>~#@8ynY3ANK}qV&d!s%?ngQJ1x06Pd4Xe3nbX(D%_?19?Ug!ngdb!L z^nJclB2!b`Lqck$+2Ffgur4rfEp~H~#p`mPDWSdz`d!QMS(viD4ciVt=OJc0ZaIio z{fz?B=Rl%LOHfeIu7{Dm&sJ{_K7#RgTe^7t3(a`j!qyYw#(e5OHaZ&_Nku1_fWApg zz9jh_q^Z5-6+*^|VfU~MMEcAL@q%0D`gyWsJ%}Azt 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 z³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 a rule +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1530,6 +1542,23 @@ you may also use the search bar in the top right, or the sidebar on the left.

    Introduction to writing PMD rules + + + + + + + + + + + + + + + + @@ -2235,6 +2264,16 @@ you may also use the search bar in the top right, or the sidebar on the left.

    Writing a custom rule +
  • Introduction to writing PMD rules
  • + + + + + + +
  • Your first rule XPath
  • @@ -2852,6 +2903,13 @@ you may also use the search bar in the top right, or the sidebar on the left.

    Writing a custom rule + + + + + +
  • The rule designer
  • @@ -3386,6 +3444,13 @@ you may also use the search bar in the top right, or the sidebar on the left.

    Writing a custom rule @@ -3535,6 +3600,16 @@ you may also use the search bar in the top right, or the sidebar on the left.

    diff --git a/js/mydoc_scroll.html b/js/mydoc_scroll.html index e844200e2f..2f606e5b1f 100644 --- a/js/mydoc_scroll.html +++ b/js/mydoc_scroll.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1607,7 +1619,7 @@ $('#small-box-links').localScroll({
    diff --git a/license.html b/license.html index dfdc2af544..3a98257f0c 100644 --- a/license.html +++ b/license.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1617,7 +1629,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    diff --git a/news.html b/news.html index 46e241caa8..a747f42732 100644 --- a/news.html +++ b/news.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1368,7 +1380,7 @@
    diff --git a/news_archive.html b/news_archive.html index 760c3bf8ac..064427db4a 100644 --- a/news_archive.html +++ b/news_archive.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1369,7 +1381,7 @@
    diff --git a/pmd_about_help.html b/pmd_about_help.html index 47d779c4bd..61123895b9 100644 --- a/pmd_about_help.html +++ b/pmd_about_help.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1393,7 +1405,7 @@ through the archives (archive1 diff --git a/pmd_apex_metrics_index.html b/pmd_apex_metrics_index.html index 3a0b419b20..2a18313e57 100644 --- a/pmd_apex_metrics_index.html +++ b/pmd_apex_metrics_index.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1447,7 +1459,7 @@ flow statement.
    diff --git a/pmd_devdocs_building.html b/pmd_devdocs_building.html index 274eba9524..cef356b7d5 100644 --- a/pmd_devdocs_building.html +++ b/pmd_devdocs_building.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1463,7 +1475,7 @@ please post here an
    diff --git a/pmd_devdocs_development.html b/pmd_devdocs_development.html index c97c434c73..89d23b9768 100644 --- a/pmd_devdocs_development.html +++ b/pmd_devdocs_development.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1411,7 +1423,7 @@ every push. Each pull request is built as well.

    diff --git a/pmd_devdocs_experimental_ast_dump.html b/pmd_devdocs_experimental_ast_dump.html index 0b1121f11f..c0ca296eba 100644 --- a/pmd_devdocs_experimental_ast_dump.html +++ b/pmd_devdocs_experimental_ast_dump.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1446,12 +1458,12 @@ with the name “a”.

    import net.sourceforge.pmd.util.treeexport.XmlTreeRenderer; public class TreeExport { - public static void main(String[] args) throws IOException { - LanguageVersionHandler java = LanguageRegistry.getLanguage("Java").getDefaultVersion().getLanguageVersionHandler(); - Parser parser = java.getParser(java.getDefaultParserOptions()); - Node root = parser.parse("foo", new StringReader("class Foo {}")); + public static void main(String[] args) throws IOException { + LanguageVersionHandler java = LanguageRegistry.getLanguage("Java").getDefaultVersion().getLanguageVersionHandler(); + Parser parser = java.getParser(java.getDefaultParserOptions()); + Node root = parser.parse("foo", new StringReader("class Foo {}")); - new XmlTreeRenderer().renderSubtree(root, System.out); + new XmlTreeRenderer().renderSubtree(root, System.out); } } @@ -1481,7 +1493,7 @@ with the name “a”.

    diff --git a/pmd_devdocs_how_pmd_works.html b/pmd_devdocs_how_pmd_works.html index 8fc56aedd1..b6b5712433 100644 --- a/pmd_devdocs_how_pmd_works.html +++ b/pmd_devdocs_how_pmd_works.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1427,7 +1439,7 @@ type resolution information and DFA nodes.
    diff --git a/pmd_devdocs_major_adding_new_cpd_language.html b/pmd_devdocs_major_adding_new_cpd_language.html index b9f13964fc..c21d6961d8 100644 --- a/pmd_devdocs_major_adding_new_cpd_language.html +++ b/pmd_devdocs_major_adding_new_cpd_language.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1373,11 +1385,11 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
  • For Antlr grammars you can take the grammar from here and extend AntlrTokenizer taking Go as an example
  • -
       public class GoTokenizer extends AntlrTokenizer {    
    +    
       public class GoTokenizer extends AntlrTokenizer {    
             
    -       @Override protected AntlrTokenManager getLexerForSource(SourceCode sourceCode) {   
    -           CharStream charStream = AntlrTokenizer.getCharStreamFromSourceCode(sourceCode);   
    -           return new AntlrTokenManager(new GolangLexer(charStream), sourceCode.getFileName());   
    +       @Override protected AntlrTokenManager getLexerForSource(SourceCode sourceCode) {   
    +           CharStream charStream = AntlrTokenizer.getCharStreamFromSourceCode(sourceCode);   
    +           return new AntlrTokenManager(new GolangLexer(charStream), sourceCode.getFileName());   
            }
        }
     
    @@ -1390,10 +1402,10 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
  • Create your Language class

    -
     public class GoLanguage extends AbstractLanguage {    
    +    
     public class GoLanguage extends AbstractLanguage {    
             
          public GoLanguage() {   
    -         super("Go", "go", new GoTokenizer(), ".go");   
    +         super("Go", "go", new GoTokenizer(), ".go");   
          }  
      } 
     
    @@ -1457,7 +1469,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_devdocs_major_adding_new_language.html b/pmd_devdocs_major_adding_new_language.html index f1f9d1c060..9de95fafee 100644 --- a/pmd_devdocs_major_adding_new_language.html +++ b/pmd_devdocs_major_adding_new_language.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1523,7 +1535,7 @@ This can be achieved with Rule Designer:

    diff --git a/pmd_devdocs_major_adding_new_metrics_framework.html b/pmd_devdocs_major_adding_new_metrics_framework.html index 6b15a1be14..e92255c55f 100644 --- a/pmd_devdocs_major_adding_new_metrics_framework.html +++ b/pmd_devdocs_major_adding_new_metrics_framework.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1358,29 +1370,8 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

    Internal architecture of the metrics framework

    -

    Overview of the Java framework

    - -

    The framework has several subsystems, the two most easily identifiable being:

    -
      -
    • -

      A project memoizer (ProjectMemoizer). When a metric is computed, it’s stored back in this structure and can be -reused later. This - reduces the overhead on the calculation of e.g. aggregate results (ResultOption calculations). The contents of - this data structure are indexed with fully qualified names (JavaQualifiedName), which must identify unambiguously - classes and methods.

      -
    • -
    • -

      The façade. The static end-user façade (JavaMetrics) is backed by an instance of a JavaMetricsFaçade. This -allows us to abstract the functionality of the façade into pmd-core for other frameworks to use. The façade -instance contains a project memoizer for the analysed project, and a metrics computer -(JavaMetricsComputer). It’s this last object which really computes the metric and stores back its result in the -project mirror, while the façade only handles parameters.

      -
    • -
    - -

    Metrics (Metric<N>) plug in to this static system and only provide behaviour that’s executed by the metrics computer. -Internally, metric keys (MetricKey<N>) are parameterized with their version (MetricVersion) to index memoisation -maps (see ParameterizedMetricKey<N>). This allows us to memoise several versions of the same metric without conflict.

    +

    The framework is pretty simple. On a high level, a Metric<N> describes some numeric computation on a node of type N. +You should wrap it into a MetricKey<N>, so that it can be cached on nodes (implemented by MetricsUtil).

    At the very least, a metrics framework has those two components and is just a convenient way to compute and memoize metrics on a single file. The expressive power of metrics can be improved by implementing signature matching capabilities, @@ -1388,55 +1379,13 @@ which allows a metric to count signatures matching a specific pattern (a mask) o designed to work across files, given a working usage resolution. However, making that work with incremental analysis is harder than it looks, and has been rescheduled to another project.

    -

    Abstraction layer

    - -

    As you may have seen, most of the functionality of the first two components are abstracted into pmd-core. This -allows us to implement new metrics frameworks quite quickly. These abstract components are parameterized by the -node types of the class and operation AST nodes. Moreover, it makes the external behaviour of the framework very -stable across languages, yet each component can easily be customized by adding methods or overriding existing ones.

    - -

    The signature matching aspect is framed by generic interfaces, but it can’t really be abstracted more -than that. The info given in the signatures is usually very language specific, as it includes info about e.g. -visibility modifiers. So more work is required to implement that, but it can already be used to implement -sophisticated metrics, that already give access to detection strategies.

    -

    Implementation of a new framework

    -

    1. Groundwork

    -
      -
    • Create a class implementing QualifiedName. This implementation must be tailored to the target language so -that it can indentify unambiguously any class and operation in the analysed project. You -must implement equals, hashCode and toString. -Example
    • -
    • Determine the AST nodes that correspond to class and method declaration in your language. These types are -referred hereafter as T and O, respectively. Both these types must implement the interface QualifiableNode, -which means they must expose a getQualifiedName method to give access to their qualified name.
    • -
    - -

    2. Implement the façade

    -
      -
    • Create a class extending AbstractMetricsComputer<T, O>. This object will be responsible for calculating metrics -given a memoizer, a node and info about the metric. Typically, this object is stateless so you might as well make it -a singleton.
    • -
    • Create a class extending BasicProjectMemoizer<T, O>. There’s no abstract functionality to implement. -Example -Example
    • -
    • Create a class extending AbstractMetricsFacade<T, O>. This class needs a reference to your ProjectMemoizer and -your MetricsComputer. It backs the real end user façade, and handles user provided parameters before delegating to -your MetricsComputer. -Example
    • -
    • Create the static façade of your framework. This one has an instance of your MetricsFaçade object and delegates -static methods to that instance. -Example
    • -
    • Create classes AbstractOperationMetric and AbstractClassMetric. These must implement Metric<T> and -Metric<O>, respectively. They typically provide defaults for the supports method of each metric. -Example
    • -
    • Create enums ClassMetricKey and OperationMetricKey. These must implement MetricKey<T> and MetricKey<O>. The -enums list all available metric keys for your language. -Example
    • -
    • Create metrics by extending your base classes, reference them in your enums, and you can start using them with your -façade!
    • +
    • Implement metrics (typically in an internal package)
    • +
    • Create some public enums/ utility classes to expose metric keys
    • +
    • Implement a LanguageMetricsProvider, to expose your metrics to the designer
    • +
    • Use your metric keys in rules with MetricsUtil

    Optional: Signature matching

    @@ -1489,7 +1438,7 @@ build a Signature<N> from a
    diff --git a/pmd_devdocs_pmdtester.html b/pmd_devdocs_pmdtester.html index fe36e6a41d..9b4d1f8f20 100644 --- a/pmd_devdocs_pmdtester.html +++ b/pmd_devdocs_pmdtester.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1395,7 +1407,7 @@ Regression difference reports are commented back to the PR for the reviewer’s
    diff --git a/pmd_devdocs_roadmap.html b/pmd_devdocs_roadmap.html index f53e78ebe3..cf9e950090 100644 --- a/pmd_devdocs_roadmap.html +++ b/pmd_devdocs_roadmap.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1516,7 +1528,7 @@ This should be configurable on per Rule basis similar to TR and SymbolTable.

    diff --git a/pmd_devdocs_rule_deprecation_policy.html b/pmd_devdocs_rule_deprecation_policy.html index 2665c03b26..c2403f295f 100644 --- a/pmd_devdocs_rule_deprecation_policy.html +++ b/pmd_devdocs_rule_deprecation_policy.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1485,7 +1497,7 @@ major release of PMD.

    diff --git a/pmd_devdocs_writing_documentation.html b/pmd_devdocs_writing_documentation.html index f216a6c983..8bbf1554f9 100644 --- a/pmd_devdocs_writing_documentation.html +++ b/pmd_devdocs_writing_documentation.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1428,47 +1440,47 @@ all formatting inside the delimiters, and allow to write code samples without {% jdoc core::Rule %} - Rule + Rule {% jdoc !q!core::Rule %} - net.sourceforge.pmd.Rule + net.sourceforge.pmd.Rule {% jdoc core::Rule#setName(java.lang.String) %} - setName + setName {% jdoc !c!core::Rule#setName(java.lang.String) %} - Rule#setName + Rule#setName {% jdoc !a!core::Rule#setName(java.lang.String) %} - setName(String) + setName(String) {% jdoc !ac!core::Rule#setName(java.lang.String) %} - Rule#setName(String) + Rule#setName(String) {% jdoc core::properties.PropertyDescriptor %} - PropertyDescriptor + PropertyDescriptor {% jdoc_nspace :jast java::lang.java.ast %}{% jdoc jast::ASTAnyTypeDeclaration %} - ASTAnyTypeDeclaration + ASTAnyTypeDeclaration {% jdoc_nspace :jast java::lang.java.ast %}{% jdoc_package :jast %} - net.sourceforge.pmd.lang.java.ast + net.sourceforge.pmd.lang.java.ast {% jdoc_nspace :PrD core::properties.PropertyDescriptor %}{% jdoc !ac!:PrD#uiOrder() %} - PropertyDescriptor#uiOrder() + PropertyDescriptor#uiOrder() {% jdoc_old core::Rule %} - Rule + Rule @@ -1600,7 +1612,7 @@ public class Foo {

    This looks as follows:

    public class Foo {
    -    public void bar() { System.out.println("x"); }
    +    public void bar() { System.out.println("x"); }
     }
     
    @@ -1632,7 +1644,7 @@ by specifying -Dpmd.doc.checkExternalLinks=true<
    diff --git a/pmd_java_metrics_index.html b/pmd_java_metrics_index.html index d3f1f2da4a..0666145f7f 100644 --- a/pmd_java_metrics_index.html +++ b/pmd_java_metrics_index.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1388,15 +1400,15 @@ Also primitives are not included into the count.

    import java.io.IOException; public class Foo { // total 8 - public Set set = new HashSet(); // +2 - public Map map = new HashMap(); // +2 - public String string = ""; // from java.lang -> does not count by default - public Double number = 0.0; // from java.lang -> does not count by default + public Set set = new HashSet(); // +2 + public Map map = new HashMap(); // +2 + public String string = ""; // from java.lang -> does not count by default + public Double number = 0.0; // from java.lang -> does not count by default public int[] intArray = new int[3]; // primitive -> does not count @Deprecated // from java.lang -> does not count by default @Override // from java.lang -> does not count by default - public void foo(List list) throws Exception { // +1 (Exception is from java.lang) + public void foo(List list) throws Exception { // +1 (Exception is from java.lang) throw new IOException(); // +1 } @@ -1528,7 +1540,7 @@ like that behaviour, use the COUNT_IMPORTSclass Foo { // +1, total Ncss = 12 public void bigMethod() // +1 - throws IOException { + throws IOException { int x = 0, y = 2; // +1 boolean a = false, b = true; // +1 @@ -1538,8 +1550,8 @@ like that behaviour, use the COUNT_IMPORTSx += 2; // +1 } while (x < 12); - System.exit(0); // +1 - } catch (IOException ioe) { // +1 + System.exit(0); // +1 + } catch (IOException ioe) { // +1 throw new PatheticFailException(ioe); // +1 } } else { @@ -1726,7 +1738,7 @@ In Proceedings ACM Symposium on Software Reusability, 1995.

    diff --git a/pmd_languages_jsp.html b/pmd_languages_jsp.html index 55de02f83e..9d1bebab51 100644 --- a/pmd_languages_jsp.html +++ b/pmd_languages_jsp.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1426,7 +1438,7 @@ contains only “.java” files, JSP files obviously will not be checked.

    diff --git a/pmd_next_major_development.html b/pmd_next_major_development.html index 2de7b5e76e..5c0245c902 100644 --- a/pmd_next_major_development.html +++ b/pmd_next_major_development.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1431,36 +1443,36 @@ we may decide to remove some APIs that were not tagged as deprecated, though we You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

    @@ -1469,44 +1481,44 @@ by just that superclass.

    6.14.0

    @@ -1707,7 +1719,7 @@ or enable preview language features (e.g. PMD_JA @@ -2158,7 +2170,7 @@ will be removed with PMD 7.0.0. The rule is replaced by the more general
    diff --git a/pmd_projectdocs_committers_merging_pull_requests.html b/pmd_projectdocs_committers_merging_pull_requests.html index 5d518c89c3..937dce73eb 100644 --- a/pmd_projectdocs_committers_merging_pull_requests.html +++ b/pmd_projectdocs_committers_merging_pull_requests.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1544,7 +1556,7 @@ integrated (e.g. gitk and github show the branches, from which the specific comm
    diff --git a/pmd_projectdocs_committers_releasing.html b/pmd_projectdocs_committers_releasing.html index a417e0c09f..5b96e09b0b 100644 --- a/pmd_projectdocs_committers_releasing.html +++ b/pmd_projectdocs_committers_releasing.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1582,7 +1594,7 @@ and mvn versions:set -DnewVersion=5.7.0-SNAPSHOT
    diff --git a/pmd_projectdocs_credits.html b/pmd_projectdocs_credits.html index d563ca12b8..ba4706b5ab 100644 --- a/pmd_projectdocs_credits.html +++ b/pmd_projectdocs_credits.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1887,7 +1899,7 @@ PMD scoreboard formulas, pmd-dcpd optimizations
    diff --git a/pmd_projectdocs_faq.html b/pmd_projectdocs_faq.html index 3df90f259e..4cd4ab5e1a 100644 --- a/pmd_projectdocs_faq.html +++ b/pmd_projectdocs_faq.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1420,7 +1432,7 @@ You must take this into account for certain rules.

    diff --git a/pmd_projectdocs_trivia_meaning.html b/pmd_projectdocs_trivia_meaning.html index 1eb36f147f..aad37a507c 100644 --- a/pmd_projectdocs_trivia_meaning.html +++ b/pmd_projectdocs_trivia_meaning.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1389,7 +1401,7 @@ really know. We just think the letters sound good together.

    diff --git a/pmd_projectdocs_trivia_news.html b/pmd_projectdocs_trivia_news.html index 75b9417c16..4208f4f8c4 100644 --- a/pmd_projectdocs_trivia_news.html +++ b/pmd_projectdocs_trivia_news.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1508,7 +1520,7 @@ interview with Ole-Martin and Tom

    diff --git a/pmd_projectdocs_trivia_products.html b/pmd_projectdocs_trivia_products.html index 6fdf18001e..1d2f128037 100644 --- a/pmd_projectdocs_trivia_products.html +++ b/pmd_projectdocs_trivia_products.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1437,7 +1449,7 @@ to catch web app security problems. Thanks to Joseph Hemler for the props!

    diff --git a/pmd_projectdocs_trivia_similarprojects.html b/pmd_projectdocs_trivia_similarprojects.html index c3bca0976c..475d495a60 100644 --- a/pmd_projectdocs_trivia_similarprojects.html +++ b/pmd_projectdocs_trivia_similarprojects.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1444,7 +1456,7 @@ only for maven project.
    diff --git a/pmd_release_notes.html b/pmd_release_notes.html index ceeb9dbee8..aba4bc4182 100644 --- a/pmd_release_notes.html +++ b/pmd_release_notes.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1398,6 +1410,7 @@ the suppressions with a NOPMD comment. Se
  • java-errorprone
    • #2250: [java] InvalidLogMessageFormat flags logging calls using a slf4j-Marker
    • +
    • #2255: [java] InvalidLogMessageFormat false-positive for a lambda argument
  • java-performance @@ -1411,9 +1424,95 @@ the suppressions with a NOPMD comment. Se

    Deprecated API

    +

    Deprecated APIs

    + +
    Internal API
    + +

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. +You can identify them with the @InternalApi annotation. You’ll also get a deprecation warning.

    + + +
    For removal
    + +

    External Contributions

    @@ -1443,7 +1542,7 @@ the suppressions with a NOPMD comment. Se
    diff --git a/pmd_release_notes_old.html b/pmd_release_notes_old.html index 3256c0399a..ac3b5a2b60 100644 --- a/pmd_release_notes_old.html +++ b/pmd_release_notes_old.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -3560,11 +3572,11 @@ are discontinued for lack of a use-case, and have no planned replacement in 7.0.

    Here’s an example:

    // Before 7.0.0, these are equivalent:
    -IntegerProperty myProperty = new IntegerProperty("score", "Top score value", 1, 100, 40, 3.0f);
    -IntegerProperty myProperty = IntegerProperty.named("score").desc("Top score value").range(1, 100).defaultValue(40).uiOrder(3.0f);
    +IntegerProperty myProperty = new IntegerProperty("score", "Top score value", 1, 100, 40, 3.0f);
    +IntegerProperty myProperty = IntegerProperty.named("score").desc("Top score value").range(1, 100).defaultValue(40).uiOrder(3.0f);
     
     // They both map to the following in 7.0.0
    -PropertyDescriptor<Integer> myProperty = PropertyFactory.intProperty("score").desc("Top score value").require(inRange(1, 100)).defaultValue(40);
    +PropertyDescriptor<Integer> myProperty = PropertyFactory.intProperty("score").desc("Top score value").require(inRange(1, 100)).defaultValue(40);
     

    You’re highly encouraged to migrate to using this new API as soon as possible, to ease your migration to 7.0.0.

    @@ -4689,22 +4701,22 @@ and has since been the preferred way to suppress CPD warnings.

    class BaseHandler(object):
         def __init__(self):
    -        # some unignored code
    -
    -        # tell cpd to start ignoring code - CPD-OFF
    -
    -        # mission critical code, manually loop unroll
    -        GoDoSomethingAwesome(x + x / 2);
    +        # some unignored code
    +
    +        # tell cpd to start ignoring code - CPD-OFF
    +
    +        # mission critical code, manually loop unroll
    +        GoDoSomethingAwesome(x + x / 2);
             GoDoSomethingAwesome(x + x / 2);
             GoDoSomethingAwesome(x + x / 2);
             GoDoSomethingAwesome(x + x / 2);
             GoDoSomethingAwesome(x + x / 2);
             GoDoSomethingAwesome(x + x / 2);
     
    -        # resume CPD analysis - CPD-ON
    -
    -        # further code will *not* be ignored
    -
    + # resume CPD analysis - CPD-ON + + # further code will *not* be ignored +

    Other languages are equivalent.

    @@ -6666,7 +6678,7 @@ See PR #250.

    For example:

    -
        public Object someMethod(int x) throws Exception {
    +
        public Object someMethod(int x) throws Exception {
             // some unignored code
     
             // tell cpd to start ignoring code - CPD-OFF
    @@ -11273,7 +11285,7 @@ Added new HTML report format
                 
    diff --git a/pmd_rules_apex.html b/pmd_rules_apex.html index b629c7f45a..0838646217 100644 --- a/pmd_rules_apex.html +++ b/pmd_rules_apex.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1581,7 +1593,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_apex_bestpractices.html b/pmd_rules_apex_bestpractices.html index ed8dc59477..72dce4a531 100644 --- a/pmd_rules_apex_bestpractices.html +++ b/pmd_rules_apex_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1375,10 +1387,10 @@ improves the readability of test output.

    public class Foo { @isTest static void methodATest() { - System.assertNotEquals('123', o.StageName); // not good - System.assertEquals('123', o.StageName, 'Opportunity stageName is wrong.'); // good - System.assert(o.isClosed); // not good - System.assert(o.isClosed, 'Opportunity is not closed.'); // good + System.assertNotEquals('123', o.StageName); // not good + System.assertEquals('123', o.StageName, 'Opportunity stageName is wrong.'); // good + System.assert(o.isClosed); // not good + System.assert(o.isClosed, 'Opportunity is not closed.'); // good } }
    @@ -1436,7 +1448,7 @@ with messages provide the developer a clearer idea of what the test does.

    @isTest
     public class Foo {
        public static testMethod void testSomething() {
    -      Account a = null;
    +      Account a = null;
        // This is better than having a NullPointerException
        // System.assertNotEquals(a, null, 'account not found');
        a.toString();
    @@ -1502,10 +1514,10 @@ As testMethod keyword is deprecated, Salesforce advices to use @isTest annotatio
         static void methodBTest() {
         }
         @isTest static void methodCTest() {
    -        System.assert(1==2);
    +        System.assert(1==2);
         }
         @isTest static void methodCTest() {
    -        System.debug('I am a debug statement');
    +        System.debug('I am a debug statement');
         }
         private void fetchData() {
         }
    @@ -1564,7 +1576,7 @@ As testMethod keyword is deprecated, Salesforce advices to use @isTest annotatio
     
    @isTest(seeAllData = true)
     public class Foo {
        public static testMethod void testSomething() {
    -      Account a = null;
    +      Account a = null;
        // This is better than having a NullPointerException
        // System.assertNotEquals(a, null, 'account not found');
        a.toString();
    @@ -1623,7 +1635,7 @@ Many interfaces (e.g. Batch) required global modifiers in the past but don’t r
     

    Example(s):

    global class Unchangeable {
    -    global UndeletableType unchangable(UndeletableType param) {
    +    global UndeletableType unchangable(UndeletableType param) {
             // ...
         }
     }
    @@ -1681,15 +1693,15 @@ Therefore delegate the triggers work to a regular class (often called Trigger ha
     
     

    Example(s):

    -
    trigger Accounts on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    -    for(Account acc : Trigger.new) {
    -        if(Trigger.isInsert) {
    +
    trigger Accounts on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    +    for(Account acc : Trigger.new) {
    +        if(Trigger.isInsert) {
                 // ...
             }
     
             // ...
     
    -        if(Trigger.isDelete) {
    +        if(Trigger.isDelete) {
                 // ...
             }
         }
    @@ -1754,9 +1766,9 @@ Therefore delegate the triggers work to a regular class (often called Trigger ha
     public class Foo {
         @isTest
         static void bar() {
    -        System.debug('Hey this code executed.'); // not good
    -        System.debug(LoggingLevel.WARN, 'Hey, something might be wrong.'); // good
    -        System.debug(LoggingLevel.DEBUG, 'Hey, something happened.'); // not good when on strict mode
    +        System.debug('Hey this code executed.'); // not good
    +        System.debug(LoggingLevel.WARN, 'Hey, something might be wrong.'); // good
    +        System.debug(LoggingLevel.DEBUG, 'Hey, something happened.'); // not good when on strict mode
         }
     }
     
    @@ -1828,7 +1840,7 @@ Therefore delegate the triggers work to a regular class (often called Trigger ha
    diff --git a/pmd_rules_apex_codestyle.html b/pmd_rules_apex_codestyle.html index fc61fa0d61..5176f14283 100644 --- a/pmd_rules_apex_codestyle.html +++ b/pmd_rules_apex_codestyle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1475,9 +1487,9 @@ static field, final field. Each regex can be configured through properties.

    Example(s):

    public class Foo {
    -    Integer instanceField; // This is in camel case, so it's ok
    +    Integer instanceField; // This is in camel case, so it's ok
     
    -    Integer INSTANCE_FIELD; // This will be reported unless you change the regex
    +    Integer INSTANCE_FIELD; // This will be reported unless you change the regex
     }
     
    @@ -1641,9 +1653,9 @@ configured through properties.

    Example(s):

    public class Foo {
    -    public bar(Integer methodParameter) { } // This is in camel case, so it's ok
    +    public bar(Integer methodParameter) { } // This is in camel case, so it's ok
     
    -    public baz(Integer METHOD_PARAMETER) { } // This will be reported unless you change the regex
    +    public baz(Integer METHOD_PARAMETER) { } // This will be reported unless you change the regex
     }
     
    @@ -1850,9 +1862,9 @@ properties.

    public class Foo {
         public Foo() {
    -        Integer localVariable; // This is in camel case, so it's ok
    +        Integer localVariable; // This is in camel case, so it's ok
     
    -        Integer LOCAL_VARIABLE; // This will be reported unless you change the regex
    +        Integer LOCAL_VARIABLE; // This will be reported unless you change the regex
         }
     }
     
    @@ -2030,13 +2042,13 @@ can lead to quite messy code. This rule looks for several declarations on the sa

    Example(s):

    -
    Integer a, b;   // not recommended
    +
    Integer a, b;   // not recommended
     
    -Integer a,
    +Integer a,
             b;      // ok by default, can be flagged setting the strictMode property
     
    -Integer a;      // preferred approach
    -Integer b;
    +Integer a;      // preferred approach
    +Integer b;
     

    This rule has the following properties:

    @@ -2108,9 +2120,9 @@ configured through properties.

    Example(s):

    public class Foo {
    -    public Integer instanceProperty { get; set; } // This is in camel case, so it's ok
    +    public Integer instanceProperty { get; set; } // This is in camel case, so it's ok
     
    -    public Integer INSTANCE_PROPERTY { get; set; } // This will be reported unless you change the regex
    +    public Integer INSTANCE_PROPERTY { get; set; } // This will be reported unless you change the regex
     }
     
    @@ -2195,9 +2207,9 @@ by the more general rules Example(s):

    public class Foo {
    -    public static final Integer MY_NUM = 0;
    -    public String myTest = '';
    -    DataModule dmTest = new DataModule();
    +    public static final Integer MY_NUM = 0;
    +    public String myTest = '';
    +    DataModule dmTest = new DataModule();
     }
     
    @@ -2399,7 +2411,7 @@ controlled from the rest.

    diff --git a/pmd_rules_apex_design.html b/pmd_rules_apex_design.html index 6083bfe665..a98ece5ad9 100644 --- a/pmd_rules_apex_design.html +++ b/pmd_rules_apex_design.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1370,7 +1382,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

    Example(s):

    public class Foo {
    -    public void bar(Integer x, Integer y, Integer z) {
    +    public void bar(Integer x, Integer y, Integer z) {
             if (x>y) {
                 if (y>z) {
                     if (z==x) {
    @@ -1652,7 +1664,7 @@ same datatype. These situations usually denote the need for new objects to wrap
         // ...
     }
     // preferred approach
    -public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
    +public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
         // ...
     }
     
    @@ -1736,9 +1748,9 @@ developed easily.

    Example(s):

    public class Foo {
    -    public String value;
    -    public Bar something;
    -    public Variable var;
    +    public String value;
    +    public Bar something;
    +    public Variable var;
         // [... more more public attributes ...]
     
         public void doWork() {}
    @@ -1825,7 +1837,7 @@ lines of code that are split are counted as one.

    Example(s):

    -
    public class Foo extends Bar {
    +
    public class Foo extends Bar {
         //this constructor only has 1 NCSS lines
         public Foo() {
             super();
    @@ -1915,9 +1927,9 @@ lines of code that are split are counted as one.

    Example(s):

    -
    public class Foo extends Bar {
    +
    public class Foo extends Bar {
         //this method only has 1 NCSS lines
    -    public Integer methd() {
    +    public Integer methd() {
             super.methd();
     
     
    @@ -2005,7 +2017,7 @@ lines of code that are split are counted as one.

    Example(s):

    //this class only has 6 NCSS lines
    -public class Foo extends Bar {
    +public class Foo extends Bar {
         public Foo() {
             super();
     
    @@ -2224,8 +2236,8 @@ city/state/zip fields could park them within a single Address field.

    public class Person { // this is more manageable - Date birthDate; - BodyMeasurements measurements; + Date birthDate; + BodyMeasurements measurements; }
    @@ -2296,7 +2308,7 @@ city/state/zip fields could park them within a single Address field.

    diff --git a/pmd_rules_apex_documentation.html b/pmd_rules_apex_documentation.html index 4145424128..61d44e971d 100644 --- a/pmd_rules_apex_documentation.html +++ b/pmd_rules_apex_documentation.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1389,7 +1401,7 @@ order as the method signature. * @description Bar * @return Bar */ - public Object bar() { return null; } + public Object bar() { return null; } }
    @@ -1446,7 +1458,7 @@ order as the method signature.
    diff --git a/pmd_rules_apex_errorprone.html b/pmd_rules_apex_errorprone.html index 4665386e12..48aae5d0a7 100644 --- a/pmd_rules_apex_errorprone.html +++ b/pmd_rules_apex_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1447,10 +1459,10 @@ using DML in constructors is not a security problem, but crashes the application

    Example(s):

    -
    trigger AccountTrigger on Account (before insert, before update) {
    -   Account a = Trigger.new[0]; //Bad: Accessing the trigger array directly is not recommended.
    +
    trigger AccountTrigger on Account (before insert, before update) {
    +   Account a = Trigger.new[0]; //Bad: Accessing the trigger array directly is not recommended.
     
    -   foreach ( Account a : Trigger.new ){
    +   foreach ( Account a : Trigger.new ){
             //Good: Iterate through the trigger.new array instead.
        }
     }
    @@ -1510,9 +1522,9 @@ the logic can dynamically identify the proper data to operate against and not fa
     
    public without sharing class Foo {
         void foo() {
             //Error - hardcoded the record type id
    -        if(a.RecordTypeId == '012500000009WAr'){
    +        if(a.RecordTypeId == '012500000009WAr'){
                 //do some logic here.....
    -        } else if(a.RecordTypeId == '0123000000095Km'){
    +        } else if(a.RecordTypeId == '0123000000095Km'){
                 //do some logic here for a different record type...
             }
         }
    @@ -1635,7 +1647,7 @@ or reported.

    ... try { insert accounts; - } catch (DmlException dmle) { + } catch (DmlException dmle) { // not good } } @@ -1694,7 +1706,7 @@ or reported.

    Example(s):

    public class Foo {
    -  public void bar(Integer x) {
    +  public void bar(Integer x) {
         if (x == 0) {
           // empty!
         }
    @@ -1820,7 +1832,7 @@ or reported.

    public void bar() { try { // empty ! - } catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -1890,7 +1902,7 @@ a while loop that does a lot in the exit expression, rewrite it to make it clear

    Example(s):

    -
    public void bar(Integer a, Integer b) {
    +
    public void bar(Integer a, Integer b) {
       while (a == b) {
         // empty!
       }
    @@ -2007,7 +2019,7 @@ a while loop that does a lot in the exit expression, rewrite it to make it clear
                 
    diff --git a/pmd_rules_apex_performance.html b/pmd_rules_apex_performance.html index 646d4a737e..616041d5db 100644 --- a/pmd_rules_apex_performance.html +++ b/pmd_rules_apex_performance.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1371,8 +1383,8 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    public class Something {
         public void foo() {
    -        for (Integer i = 0; i < 151; i++) {
    -            Account account;
    +        for (Integer i = 0; i < 151; i++) {
    +            Account account;
                 // ...
                 insert account;
             }
    @@ -1430,9 +1442,9 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
     

    Example(s):

    public class Something {
    -    public static void main( String as[] ) {
    -        for (Integer i = 0; i < 10; i++) {
    -            List<Account> accounts = [SELECT Id FROM Account];
    +    public static void main( String as[] ) {
    +        for (Integer i = 0; i < 10; i++) {
    +            List<Account> accounts = [SELECT Id FROM Account];
             }
         }
     }
    @@ -1488,9 +1500,9 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
     

    Example(s):

    public class Something {
    -    public static void main( String as[] ) {
    -        for (Integer i = 0; i < 10; i++) {
    -            List<List<SObject>> searchList = [FIND 'map*' IN ALL FIELDS RETURNING Account (Id, Name), Contact, Opportunity, Lead];
    +    public static void main( String as[] ) {
    +        for (Integer i = 0; i < 10; i++) {
    +            List<List<SObject>> searchList = [FIND 'map*' IN ALL FIELDS RETURNING Account (Id, Name), Contact, Opportunity, Lead];
             }
         }
     }
    @@ -1549,7 +1561,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
                 
    diff --git a/pmd_rules_apex_security.html b/pmd_rules_apex_security.html index af1e02076e..f2b48f6e77 100644 --- a/pmd_rules_apex_security.html +++ b/pmd_rules_apex_security.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1371,10 +1383,10 @@ Hard-wiring these values greatly compromises the security of encrypted data.

    Example(s):

    public without sharing class Foo {
    -    Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123');
    -    Blob hardCodedKey = Blob.valueOf('0000000000000000');
    -    Blob data = Blob.valueOf('Data to be encrypted');
    -    Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data);
    +    Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123');
    +    Blob hardCodedKey = Blob.valueOf('0000000000000000');
    +    Blob data = Blob.valueOf('Data to be encrypted');
    +    Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data);
     }
     
    @@ -1430,11 +1442,11 @@ privilege and may produce runtime errors. This check forces you to handle such s

    Example(s):

    public class Foo {
    -    public Contact foo(String status, String ID) {
    -        Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID];
    +    public Contact foo(String status, String ID) {
    +        Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID];
     
             // Make sure we can update the database before even trying
    -        if (!Schema.sObjectType.Contact.fields.Name.isUpdateable()) {
    +        if (!Schema.sObjectType.Contact.fields.Name.isUpdateable()) {
                 return null;
             }
     
    @@ -1587,7 +1599,7 @@ of private data.
     
     
    public class Foo {
         public Foo() {
    -        Configuration.disableTriggerCRUDSecurity();
    +        Configuration.disableTriggerCRUDSecurity();
         }
     }
     
    @@ -1644,7 +1656,7 @@ of private data.
    public without sharing class Foo {
         void foo() {
    -        HttpRequest req = new HttpRequest();
    +        HttpRequest req = new HttpRequest();
             req.setEndpoint('http://localhost:com');
         }
     }
    @@ -1701,8 +1713,8 @@ redirecting users to phishing sites.

    Example(s):

    public without sharing class Foo {
    -    String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param');
    -    PageReference page() {
    +    String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param');
    +    PageReference page() {
            return new PageReference(unsafeLocation);
         }
     }
    @@ -1813,8 +1825,8 @@ forces the developer to take access restrictions into account before modifying o
     

    Example(s):

    public class Foo {
    -    public void test1(String t1) {
    -        Database.query('SELECT Id FROM Account' + t1);
    +    public void test1(String t1) {
    +        Database.query('SELECT Id FROM Account' + t1);
         }
     }
     
    @@ -1883,10 +1895,10 @@ forces the developer to take access restrictions into account before modifying o

    Example(s):

    public class Foo {
    -    public void foo(String username, String password) {
    -        Blob headerValue = Blob.valueOf(username + ':' + password);
    -        String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
    -        req.setHeader('Authorization', authorizationHeader);
    +    public void foo(String username, String password) {
    +        Blob headerValue = Blob.valueOf(username + ':' + password);
    +        String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
    +        req.setHeader('Authorization', authorizationHeader);
         }
     }
     
    @@ -1943,7 +1955,7 @@ attacks if unescaped.

    Example(s):

    public without sharing class Foo {
    -    Trigger.new[0].addError(vulnerableHTMLGoesHere, false);
    +    Trigger.new[0].addError(vulnerableHTMLGoesHere, false);
     }
     
    @@ -1998,8 +2010,8 @@ to avoid XSS attacks.

    Example(s):

    public without sharing class Foo {
    -    String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param');
    -    String usedLater = unescapedstring;
    +    String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param');
    +    String usedLater = unescapedstring;
     }
     
    @@ -2056,7 +2068,7 @@ to avoid XSS attacks.

    diff --git a/pmd_rules_ecmascript.html b/pmd_rules_ecmascript.html index 1ad3e08852..7b743c2de7 100644 --- a/pmd_rules_ecmascript.html +++ b/pmd_rules_ecmascript.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1462,7 +1474,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_ecmascript_bestpractices.html b/pmd_rules_ecmascript_bestpractices.html index 883512ac1b..1ef5a32f53 100644 --- a/pmd_rules_ecmascript_bestpractices.html +++ b/pmd_rules_ecmascript_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1507,9 +1519,9 @@ is better to explicitly scope the variable name to the nearest enclosing scope w
    // Ok
     function foo() {
    -    var p = 'clean';
    +    var p = 'clean';
         function() {
    -        var obj = { dirty: 'dirty' };
    +        var obj = { dirty: 'dirty' };
             for (var p in obj) { // Use 'var' here.
                 obj[p] = obj[p];
             }
    @@ -1520,9 +1532,9 @@ is better to explicitly scope the variable name to the nearest enclosing scope w
     }
     // Bad
     function bar() {
    -    var p = 'clean';
    +    var p = 'clean';
         function() {
    -        var obj = { dirty: 'dirty' };
    +        var obj = { dirty: 'dirty' };
             for (p in obj) { // Oh no, missing 'var' here!
                 obj[p] = obj[p];
             }
    @@ -1559,9 +1571,9 @@ It also improves readability, if the base is given.

    Example(s):

    -
    parseInt("010");    // unclear, could be interpreted as 10 or 7 (with a base of 7)
    +
    parseInt("010");    // unclear, could be interpreted as 10 or 7 (with a base of 7)
     
    -parseInt("10", 10); // good
    +parseInt("10", 10); // good
     

    Use this rule by referencing it:

    @@ -1584,7 +1596,7 @@ It also improves readability, if the base is given.

    diff --git a/pmd_rules_ecmascript_codestyle.html b/pmd_rules_ecmascript_codestyle.html index 29dbc2fc38..916ac225ae 100644 --- a/pmd_rules_ecmascript_codestyle.html +++ b/pmd_rules_ecmascript_codestyle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1385,7 +1397,7 @@ indicative of the bug where the assignment operator ‘=’ was used instead of
    var x = 2;
     // Bad
     if ((x = getX()) == 3) {
    -    alert('3!');
    +    alert('3!');
     }
     
     function getX() {
    @@ -1726,7 +1738,7 @@ will never execute.  This is a bug, or extremely poor style.

    diff --git a/pmd_rules_ecmascript_errorprone.html b/pmd_rules_ecmascript_errorprone.html index b2459090fd..4f2a64cb97 100644 --- a/pmd_rules_ecmascript_errorprone.html +++ b/pmd_rules_ecmascript_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1508,7 +1520,7 @@ precision in a floating point number. This may result in numeric calculations b
    diff --git a/pmd_rules_java.html b/pmd_rules_java.html index bf84c1bf17..d28451422d 100644 --- a/pmd_rules_java.html +++ b/pmd_rules_java.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -2018,7 +2030,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_java_bestpractices.html b/pmd_rules_java_bestpractices.html index c5905c26a7..6f1f633d54 100644 --- a/pmd_rules_java_bestpractices.html +++ b/pmd_rules_java_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1408,7 +1420,7 @@ This turns a private constructor effectively into one with package scope, and is
    public class Outer {
      void method(){
    -  Inner ic = new Inner();//Causes generation of accessor class
    +  Inner ic = new Inner();//Causes generation of accessor class
      }
      public class Inner {
       private Inner(){}
    @@ -1439,12 +1451,12 @@ be avoided by changing the visibility of the field / method from private to pack
         /* package */ int id;
     
         public class InnerClass {
    -        InnerClass() {
    -            OuterClass.this.counter++; // wrong accessor method will be generated
    +        InnerClass() {
    +            OuterClass.this.counter++; // wrong accessor method will be generated
             }
     
             public int getOuterClassId() {
    -            return OuterClass.this.id; // id is package-private, no accessor method needed
    +            return OuterClass.this.id; // id is package-private, no accessor method needed
             }
         }
     }
    @@ -1468,8 +1480,8 @@ This prevents future changes from the user from affecting the original array.

    Example(s):

    public class Foo {
    -    private String [] x;
    -        public void foo (String [] param) {
    +    private String [] x;
    +        public void foo (String [] param) {
             // Don't do this, make a copy of the array at least
             this.x=param;
         }
    @@ -1500,9 +1512,9 @@ Creating a new instance is easier than synchronizing access to a shared instance
     
     
    import java.security.MessageDigest;
     public class AvoidMessageDigestFieldExample {
    -    private final MessageDigest sharedMd;
    -    public AvoidMessageDigestFieldExample() throws Exception {
    -        sharedMd = MessageDigest.getInstance("SHA-256");
    +    private final MessageDigest sharedMd;
    +    public AvoidMessageDigestFieldExample() throws Exception {
    +        sharedMd = MessageDigest.getInstance("SHA-256");
         }
         public byte[] calculateHashShared(byte[] data) {
             // sharing a MessageDigest like this without synchronizing access
    @@ -1513,8 +1525,8 @@ Creating a new instance is easier than synchronizing access to a shared instance
         }
     
         // better
    -    public byte[] calculateHash(byte[] data) throws Exception {
    -        MessageDigest md = MessageDigest.getInstance("SHA-256");
    +    public byte[] calculateHash(byte[] data) throws Exception {
    +        MessageDigest md = MessageDigest.getInstance("SHA-256");
             md.update(data);
             return md.digest();
         }
    @@ -1545,7 +1557,7 @@ Creating a new instance is easier than synchronizing access to a shared instance
         void bar() {
             try {
                 // do something
    -        } catch (Exception e) {
    +        } catch (Exception e) {
                 e.printStackTrace();
             }
         }
    @@ -1586,7 +1598,7 @@ Creating a new instance is easier than synchronizing access to a shared instance
     
     
    public class Foo {
       private void foo() {
    -    for (String s : listOfStrings()) {
    +    for (String s : listOfStrings()) {
           s = s.trim(); // OK, when foreachReassign is "firstOnly" or "allow"
           doSomethingWith(s);
     
    @@ -1660,7 +1672,7 @@ Creating a new instance is easier than synchronizing access to a shared instance
     

    Example(s):

    public class Foo {
    -  private void foo(String bar) {
    +  private void foo(String bar) {
         bar = "something else";
       }
     }
    @@ -1686,7 +1698,7 @@ if held within objects with long lifetimes.

    Example(s):

    public class Foo {
    -    private StringBuffer buffer;    // potential memory leak as an instance variable;
    +    private StringBuffer buffer;    // potential memory leak as an instance variable;
     }
     
    @@ -1708,7 +1720,7 @@ Externalizing IP adresses is preferable.

    Example(s):

    public class Foo {
    -    private String ip = "127.0.0.1";     // not recommended
    +    private String ip = "127.0.0.1";     // not recommended
     }
     
    @@ -1758,15 +1770,15 @@ If the value return is ‘false’, it should be handled properly.

    Example(s):

    -
    Statement stat = conn.createStatement();
    -ResultSet rst = stat.executeQuery("SELECT name FROM person");
    +
    Statement stat = conn.createStatement();
    +ResultSet rst = stat.executeQuery("SELECT name FROM person");
     rst.next();     // what if it returns false? bad form
    -String firstName = rst.getString(1);
    +String firstName = rst.getString(1);
     
    -Statement stat = conn.createStatement();
    -ResultSet rst = stat.executeQuery("SELECT name FROM person");
    +Statement stat = conn.createStatement();
    +ResultSet rst = stat.executeQuery("SELECT name FROM person");
     if (rst.next()) {    // result is properly examined and used
    -    String firstName = rst.getString(1);
    +    String firstName = rst.getString(1);
         } else  {
             // handle missing data
     }
    @@ -1792,22 +1804,22 @@ better placed in classes or enums. See Effective Java, item 19.

    Example(s):

    public interface ConstantInterface {
    -    public static final int CONST1 = 1; // violation, no fields allowed in interface!
    -    static final int CONST2 = 1;        // violation, no fields allowed in interface!
    -    final int CONST3 = 1;               // violation, no fields allowed in interface!
    -    int CONST4 = 1;                     // violation, no fields allowed in interface!
    +    public static final int CONST1 = 1; // violation, no fields allowed in interface!
    +    static final int CONST2 = 1;        // violation, no fields allowed in interface!
    +    final int CONST3 = 1;               // violation, no fields allowed in interface!
    +    int CONST4 = 1;                     // violation, no fields allowed in interface!
     }
     
     // with ignoreIfHasMethods = false
     public interface AnotherConstantInterface {
    -    public static final int CONST1 = 1; // violation, no fields allowed in interface!
    +    public static final int CONST1 = 1; // violation, no fields allowed in interface!
     
         int anyMethod();
     }
     
     // with ignoreIfHasMethods = true
     public interface YetAnotherConstantInterface {
    -    public static final int CONST1 = 1; // no violation
    +    public static final int CONST1 = 1; // no violation
     
         int anyMethod();
     }
    @@ -1901,14 +1913,14 @@ accessible from outside the anonymous class, and those legit cases should be sup
     

    Example(s):

    // this is double-brace initialization
    -return new ArrayList<String>(){{
    +return new ArrayList<String>(){{
         add("a");
         add("b");
         add("c");
     }};
     
     // the better way is to not create an anonymous class:
    -List<String> a = new ArrayList<>();
    +List<String> a = new ArrayList<>();
     a.add("a");
     a.add("b");
     a.add("c");
    @@ -1937,13 +1949,13 @@ element of the list or array left to right.

    Example(s):

    public class MyClass {
    -  void loop(List<String> l) {
    +  void loop(List<String> l) {
         for (int i = 0; i < l.size(); i++) { // pre Java 1.5
    -      System.out.println(l.get(i));
    +      System.out.println(l.get(i));
         }
     
    -    for (String s : l) {        // post Java 1.5
    -      System.out.println(s);
    +    for (String s : l) {        // post Java 1.5
    +      System.out.println(s);
         }
       }
     }
    @@ -2081,15 +2093,15 @@ through the @RunWith(Suite.class) annotation.

    Example(s):

    -
    public class BadExample extends TestCase{
    +
    public class BadExample extends TestCase{
     
    -    public static Test suite(){
    +    public static Test suite(){
             return new Suite();
         }
     }
     
    -@RunWith(Suite.class)
    -@SuiteClasses( { TestOne.class, TestTwo.class })
    +@RunWith(Suite.class)
    +@SuiteClasses( { TestOne.class, TestTwo.class })
     public class GoodTest {
     }
     
    @@ -2258,7 +2270,7 @@ assertEquals(), not the two-argument version.

    Example(s):

    -
    public class Foo extends TestCase {
    +
    public class Foo extends TestCase {
         public void testSomething() {
             assertEquals("foo", "bar");
             // Use the form:
    @@ -2299,7 +2311,7 @@ Customize the maximum number of assertions used by this Rule to suit your needs.
     
     

    Example(s):

    -
    public class MyTestCase extends TestCase {
    +
    public class MyTestCase extends TestCase {
         // Ok
         public void testMyCaseWithOneAssert() {
             boolean myVar = false;
    @@ -2361,9 +2373,9 @@ with messages provide the developer a clearer idea of what the test does.

    Example(s):

    -
    public class Foo extends TestCase {
    +
    public class Foo extends TestCase {
        public void testSomething() {
    -      Bar b = findBar();
    +      Bar b = findBar();
        // This is better than having a NullPointerException
        // assertNotNull("bar not found", b);
        b.work();
    @@ -2393,11 +2405,11 @@ with messages provide the developer a clearer idea of what the test does.

    try { doSomething(); fail("should have thrown an exception"); - } catch (Exception e) { + } catch (Exception e) { } } - @Test(expected=Exception.class) + @Test(expected=Exception.class) public void testGood() { doSomething(); } @@ -2427,17 +2439,17 @@ by their interface types (i.e, Set) provides much more flexibility.

    public class Bar { // sub-optimal approach - private ArrayList<SomeType> list = new ArrayList<>(); + private ArrayList<SomeType> list = new ArrayList<>(); - public HashSet<SomeType> getFoo() { - return new HashSet<SomeType>(); + public HashSet<SomeType> getFoo() { + return new HashSet<SomeType>(); } // preferred approach - private List<SomeType> list = new ArrayList<>(); + private List<SomeType> list = new ArrayList<>(); - public Set<SomeType> getFoo() { - return new HashSet<SomeType>(); + public Set<SomeType> getFoo() { + return new HashSet<SomeType>(); } }
    @@ -2460,8 +2472,8 @@ removed or replaced outside of the object that owns it. It is safer to return a

    Example(s):

    public class SecureSystem {
    -    UserData [] ud;
    -    public UserData [] getUserData() {
    +    UserData [] ud;
    +    public UserData [] getUserData() {
             // Don't return directly the internal array, return a copy
             return ud;
         }
    @@ -2487,7 +2499,7 @@ the method really overrides one, which helps refactoring and clarifies intent.Example(s):

    -
    public class Foo implements Runnable {
    +
    public class Foo implements Runnable {
                     // This method is overridden, and should have an @Override annotation
                     public void run() {
     
    @@ -2521,12 +2533,12 @@ can lead to quite messy code. This rule looks for several declarations on the sa
     
     

    Example(s):

    -
    String name;            // separate declarations
    -String lastname;
    +
    String name;            // separate declarations
    +String lastname;
     
    -String name, lastname;  // combined declaration, a violation
    +String name, lastname;  // combined declaration, a violation
     
    -String name,
    +String name,
            lastname;        // combined declaration on multiple lines, no violation by default.
                             // Set property strictMode to true to mark this as violation.
     
    @@ -2593,7 +2605,7 @@ can be avoided, they will just return false.

    Example(s):

    class Foo {
    -  boolean bar(String x) {
    +  boolean bar(String x) {
         return x.equalsIgnoreCase("2"); // should be "2".equalsIgnoreCase(x)
       }
     }
    @@ -2628,7 +2640,7 @@ can be avoided, they will just return false.

    Example(s):

    class Foo {
    -  boolean bar(String x) {
    +  boolean bar(String x) {
         return x.equals("2"); // should be "2".equals(x)
       }
     }
    @@ -2655,20 +2667,20 @@ effectively.

    public class Foo {
         void good() {
             try{
    -            Integer.parseInt("a");
    -        } catch (Exception e) {
    +            Integer.parseInt("a");
    +        } catch (Exception e) {
                 throw new Exception(e); // first possibility to create exception chain
             }
             try {
    -            Integer.parseInt("a");
    -        } catch (Exception e) {
    -            throw (IllegalStateException)new IllegalStateException().initCause(e); // second possibility to create exception chain.
    +            Integer.parseInt("a");
    +        } catch (Exception e) {
    +            throw (IllegalStateException)new IllegalStateException().initCause(e); // second possibility to create exception chain.
             }
         }
         void bad() {
             try{
    -            Integer.parseInt("a");
    -        } catch (Exception e) {
    +            Integer.parseInt("a");
    +        } catch (Exception e) {
                 throw new Exception(e.getMessage());
             }
         }
    @@ -2693,13 +2705,13 @@ effectively.

    Example(s):

    -
    public class Foo implements Enumeration {
    +
    public class Foo implements Enumeration {
         private int x = 42;
         public boolean hasMoreElements() {
             return true;
         }
    -    public Object nextElement() {
    -        return String.valueOf(i++);
    +    public Object nextElement() {
    +        return String.valueOf(i++);
         }
     }
     
    @@ -2724,7 +2736,7 @@ effectively.

    public class Foo {
         void bar() {
    -        Hashtable h = new Hashtable();
    +        Hashtable h = new Hashtable();
         }
     }
     
    @@ -2749,7 +2761,7 @@ effectively.

    public class Foo {
         void bar() {
    -        Vector v = new Vector();
    +        Vector v = new Vector();
         }
     }
     
    @@ -2807,9 +2819,9 @@ will (and by priority) and avoid clogging the Standard out log.

    Example(s):

    class Foo{
    -    Logger log = Logger.getLogger(Foo.class.getName());
    +    Logger log = Logger.getLogger(Foo.class.getName());
         public void testA () {
    -        System.out.println("Entering test");
    +        System.out.println("Entering test");
             // Better use this
             log.fine("Entering test");
         }
    @@ -2836,7 +2848,7 @@ Hence, by default, this rule only considers private methods. To include non-priv
     

    Example(s):

    public class Foo {
    -    private void bar(String howdy) {
    +    private void bar(String howdy) {
             // howdy is not used
         }
     }
    @@ -2934,7 +2946,7 @@ This rule will also find unused on demand imports, i.e. import com.foo.*.

    Example(s):

    public class Something {
    -    private static int FOO = 2; // Unused
    +    private static int FOO = 2; // Unused
         private int i = 5; // Unused
         private int j = 6;
         public int addOne() {
    @@ -3053,9 +3065,9 @@ This rule will also find unused on demand imports, i.e. import com.foo.*.

    Example(s):

    -
    public class FooTest extends TestCase {
    +
    public class FooTest extends TestCase {
         void testCode() {
    -        Object a, b;
    +        Object a, b;
             assertTrue(a.equals(b));                    // bad usage
             assertEquals(?a should equals b?, a, b);    // good usage
         }
    @@ -3095,9 +3107,9 @@ more specific methods, like assertNull, assertNotNull.

    Example(s):

    -
    public class FooTest extends TestCase {
    +
    public class FooTest extends TestCase {
         void testCode() {
    -        Object a = doSomething();
    +        Object a = doSomething();
             assertTrue(a==null);    // bad usage
             assertNull(a);          // good usage
             assertTrue(a != null);  // bad usage
    @@ -3139,9 +3151,9 @@ by more specific methods, like assertSame, assertNotSame.

    Example(s):

    -
    public class FooTest extends TestCase {
    +
    public class FooTest extends TestCase {
         void testCode() {
    -        Object a, b;
    +        Object a, b;
             assertTrue(a == b); // bad usage
             assertSame(a, b);   // good usage
         }
    @@ -3172,7 +3184,7 @@ by more specific methods, like assertSame, assertNotSame.

    Example(s):

    -
    public class MyTestCase extends TestCase {
    +
    public class MyTestCase extends TestCase {
         public void testMyCase() {
             boolean myVar = true;
             // Ok
    @@ -3182,9 +3194,9 @@ by more specific methods, like assertSame, assertNotSame.

    // Bad assertEquals("myVar is false", false, myVar); // Bad - assertEquals("myVar is true", Boolean.TRUE, myVar); + assertEquals("myVar is true", Boolean.TRUE, myVar); // Bad - assertEquals("myVar is false", Boolean.FALSE, myVar); + assertEquals("myVar is false", Boolean.FALSE, myVar); } }
    @@ -3208,14 +3220,14 @@ Comparing the value of size() to 0 does not convey intent as well as the isEmpty
    public class Foo {
         void good() {
    -        List foo = getList();
    +        List foo = getList();
             if (foo.isEmpty()) {
                 // blah
             }
         }
     
         void bad() {
    -        List foo = getList();
    +        List foo = getList();
             if (foo.size() == 0) {
                 // blah
             }
    @@ -3255,22 +3267,22 @@ preserved.

    public class TryWithResources {
         public void run() {
    -        InputStream in = null;
    +        InputStream in = null;
             try {
                 in = openInputStream();
                 int i = in.read();
    -        } catch (IOException e) {
    +        } catch (IOException e) {
                 e.printStackTrace();
             } finally {
                 try {
                     if (in != null) in.close();
    -            } catch (IOException ignored) {
    +            } catch (IOException ignored) {
                     // ignored
                 }
             }
     
             // better use try-with-resources
    -        try (InputStream in2 = openInputStream()) {
    +        try (InputStream in2 = openInputStream()) {
                 int i = in2.read();
             }
         }
    @@ -3347,11 +3359,11 @@ having to deal with the creation of an array.

    Example(s):

    public class Foo {
    -    public void foo(String s, Object[] args) {
    +    public void foo(String s, Object[] args) {
             // Do something here...
         }
     
    -    public void bar(String s, Object... args) {
    +    public void bar(String s, Object... args) {
             // Ahh, varargs tastes much better...
         }
     }
    @@ -3412,7 +3424,7 @@ a block {} is sufficient.

    diff --git a/pmd_rules_java_codestyle.html b/pmd_rules_java_codestyle.html index 1283a31118..5916203c7c 100644 --- a/pmd_rules_java_codestyle.html +++ b/pmd_rules_java_codestyle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1531,7 +1543,7 @@ If the goal is to avoid defining constants in a scope smaller than the class, th
    public class MyClass {
         public void foo() {
    -        final String finalLocalVariable;
    +        final String finalLocalVariable;
         }
     }
     
    @@ -1567,7 +1579,7 @@ by the more general rule public class Foo { public void bar( int inLeftOperand, - Result outRightOperand) { + Result outRightOperand) { outRightOperand.setValue(inLeftOperand * outRightOperand.getValue()); } } @@ -1582,7 +1594,7 @@ by the more general rule public void bar( int leftOperand, - Result rightOperand) { + Result rightOperand) { rightOperand.setValue(leftOperand * rightOperand.getValue()); } } @@ -1612,7 +1624,7 @@ Clarify your intent by using private or package access modifiers instead.

    public final class Bar {
       private int x;
       protected int y;  // bar cannot be subclassed, so is y really private or package visible?
    -  Bar() {}
    +  Bar() {}
     }
     
    @@ -1666,15 +1678,15 @@ and increases the maintenance burden.

    public class SomeJNIClass {
     
          public SomeJNIClass() {
    -         System.loadLibrary("nativelib");
    +         System.loadLibrary("nativelib");
          }
     
          static {
    -         System.loadLibrary("nativelib");
    +         System.loadLibrary("nativelib");
          }
     
    -     public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException {
    -         System.loadLibrary("nativelib");
    +     public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException {
    +         System.loadLibrary("nativelib");
          }
     }
     
    @@ -1761,7 +1773,7 @@ another constructor (such as an overloaded constructor) is called, this rule wil

    Example(s):

    -
    public class Foo extends Bar{
    +
    public class Foo extends Bar{
       public Foo() {
        // call the constructor of Bar
        super();
    @@ -1895,8 +1907,8 @@ property "ignoredAnnotations" to customize the recognized annotations.

    Example(s):

    public class Foo {
    -    final String stringValue = "some string";
    -    String getString() {
    +    final String stringValue = "some string";
    +    String getString() {
            return stringValue;
         }
     
    @@ -1906,8 +1918,8 @@ property "ignoredAnnotations" to customize the recognized annotations.

    // should be public class Foo { - /* default */ final String stringValue = "some string"; - /* default */ String getString() { + /* default */ final String stringValue = "some string"; + /* default */ String getString() { return stringValue; } @@ -2243,7 +2255,7 @@ usage by developers who should be implementing their own versions in the concret

    Example(s):

    public abstract class ShouldBeAbstract {
    -    public Object couldBeAbstract() {
    +    public Object couldBeAbstract() {
             // Should be abstract method ?
             return null;
         }
    @@ -2271,7 +2283,7 @@ usage by developers who should be implementing their own versions in the concret
     
     

    Example(s):

    -
    public class Foo extends Object {     // not required
    +
    public class Foo extends Object {     // not required
     }
     
    @@ -2294,14 +2306,14 @@ usage by developers who should be implementing their own versions in the concret
    public class HelloWorldBean {
     
       // Field declared before methods / inner classes - OK
    -  private String _thing;
    +  private String _thing;
     
    -  public String getMessage() {
    +  public String getMessage() {
         return "Hello World!";
       }
     
       // Field declared after methods / inner classes - avoid this
    -  private String _fieldInWrongLocation;
    +  private String _fieldInWrongLocation;
     }
     
    @@ -2374,15 +2386,15 @@ convention for constants and enum constants.

    int my_Field = 1; // This contains an underscore, it's not ok by default // but you may allow it, or even require the "my_" prefix - final int FinalField = 1; // you may configure a different convention for final fields, + final int FinalField = 1; // you may configure a different convention for final fields, // e.g. here PascalCase: [A-Z][a-zA-Z0-9]* interface Interface { - double PI = 3.14; // interface "fields" use the constantPattern property + double PI = 3.14; // interface "fields" use the constantPattern property } - enum AnEnum { - ORG, NET, COM; // These use a separate property but are set to ALL_UPPER by default + enum AnEnum { + ORG, NET, COM; // These use a separate property but are set to ALL_UPPER by default } }
    @@ -2548,10 +2560,10 @@ configured through properties.

    void lambdas() { // lambdas parameters can be configured separately - Consumer<String> lambda1 = s_str -> { }; + Consumer<String> lambda1 = s_str -> { }; // lambda parameters with an explicit type can be configured separately - Consumer<String> lambda1 = (String str) -> { }; + Consumer<String> lambda1 = (String str) -> { }; } @@ -2630,19 +2642,19 @@ configured through properties.

    Example(s):

    -
    public interface GenericDao<E extends BaseModel, K extends Serializable> extends BaseDao {
    +
    public interface GenericDao<E extends BaseModel, K extends Serializable> extends BaseDao {
         // This is ok...
     }
     
    -public interface GenericDao<E extends BaseModel, K extends Serializable> {
    +public interface GenericDao<E extends BaseModel, K extends Serializable> {
         // Also this
     }
     
    -public interface GenericDao<e extends BaseModel, K extends Serializable> {
    +public interface GenericDao<e extends BaseModel, K extends Serializable> {
         // 'e' should be an 'E'
     }
     
    -public interface GenericDao<EF extends BaseModel, K extends Serializable> {
    +public interface GenericDao<EF extends BaseModel, K extends Serializable> {
        // 'EF' is not ok.
     }
     
    @@ -2669,15 +2681,15 @@ branch.

    try {
         // do something
    -} catch (IllegalArgumentException e) {
    +} catch (IllegalArgumentException e) {
         throw e;
    -} catch (IllegalStateException e) { // Can be collapsed into the previous block
    +} catch (IllegalStateException e) { // Can be collapsed into the previous block
         throw e;
     }
     
     try {
         // do something
    -} catch (IllegalArgumentException | IllegalStateException e) { // This is better
    +} catch (IllegalArgumentException | IllegalStateException e) { // This is better
         throw e;
     }
     
    @@ -3001,8 +3013,8 @@ Developers Perceive Them.

    public class Bar {
         public void foo () {
    -    String txtA = "a";          // if txtA will not be assigned again it is better to do this:
    -    final String txtB = "b";
    +    String txtA = "a";          // if txtA will not be assigned again it is better to do this:
    +    final String txtB = "b";
         }
     }
     
    @@ -3066,7 +3078,7 @@ properties.

    try { foo(); - } catch (IllegalArgumentException e_illegal) { + } catch (IllegalArgumentException e_illegal) { // exception block parameters can be configured separately } @@ -3137,7 +3149,7 @@ properties.

    public class Something {
         int reallyLongIntName = -3;             // VIOLATION - Field
    -    public static void main( String argumentsList[] ) { // VIOLATION - Formal
    +    public static void main( String argumentsList[] ) { // VIOLATION - Formal
             int otherReallyLongName = -5;       // VIOLATION - Local
             for (int interestingIntIndex = 0;   // VIOLATION - For
                  interestingIntIndex < 10;
    @@ -3205,9 +3217,9 @@ properties.

    Example(s):

    -
    public class SomeBean implements SessionBean{}                  // proper name
    +
    public class SomeBean implements SessionBean{}                  // proper name
     
    -public class MissingTheProperSuffix implements SessionBean {}   // non-standard name
    +public class MissingTheProperSuffix implements SessionBean {}   // non-standard name
     

    Use this rule by referencing it:

    @@ -3226,11 +3238,11 @@ properties.

    Example(s):

    -
    public void foo1 (String param) {       // do stuff with param never assigning it
    +
    public void foo1 (String param) {       // do stuff with param never assigning it
     
     }
     
    -public void foo2 (final String param) { // better, do stuff with param never assigning it
    +public void foo2 (final String param) { // better, do stuff with param never assigning it
     
     }
     
    @@ -3353,7 +3365,7 @@ by the more general rule
    public class Foo {
         private int m_foo; // OK
    -    public void bar(String m_baz) { // Bad
    +    public void bar(String m_baz) { // Bad
           int m_boz = 42; // Bad
         }
     }
    @@ -3448,13 +3460,13 @@ by the more general rule
     
     

    Example(s):

    -
    public int getLength(String[] strings) {
    +
    public int getLength(String[] strings) {
     
         int length = 0; // declared prematurely
     
         if (strings == null || strings.length == 0) return 0;
     
    -    for (String str : strings) {
    +    for (String str : strings) {
             length += str.length();
         }
     
    @@ -3668,12 +3680,12 @@ by the more general rule
     
     
    public class Something {
         private int q = 15;                         // field - too short
    -    public static void main( String as[] ) {    // formal arg - too short
    +    public static void main( String as[] ) {    // formal arg - too short
             int r = 20 + q;                         // local var - too short
             for (int i = 0; i < 10; i++) {          // not a violation (inside 'for' loop)
                 r += q;
             }
    -        for (Integer i : numbers) {             // not a violation (inside 'for-each' loop)
    +        for (Integer i : numbers) {             // not a violation (inside 'for-each' loop)
                 r += q;
             }
         }
    @@ -3740,7 +3752,7 @@ by the more general rule // this is bad, since someone could accidentally
      // do PI = 2.71828; which is actually e
      // final double PI = 3.16; is ok
    -  double PI = 3.16;
    +  double PI = 3.16;
     }
     
    @@ -3765,11 +3777,11 @@ which class a static member comes from (Sun 1.5 Language Guide).

    Example(s):

    -
    import static Lennon;
    -import static Ringo;
    -import static George;
    -import static Paul;
    -import static Yoko; // Too much !
    +
    import static Lennon;
    +import static Ringo;
    +import static George;
    +import static Paul;
    +import static Yoko; // Too much !
     

    This rule has the following properties:

    @@ -3821,7 +3833,7 @@ which class a static member comes from (Sun 1.5 Language Guide).

    public class Foo { @TestMemberAnnotation(value = "TEST") - private String y; + private String y; @TestMethodAnnotation(value = "TEST") public void bar() { @@ -3836,7 +3848,7 @@ which class a static member comes from (Sun 1.5 Language Guide).

    public class Foo { @TestMemberAnnotation("TEST") - private String y; + private String y; @TestMethodAnnotation("TEST") public void bar() { @@ -3919,7 +3931,7 @@ which is covered by an import statement is redundant. Consider using the non-fu public class Foo { private java.util.List list1; // Unnecessary FQN - private List list2; // More appropriate given import of 'java.util.List' + private List list2; // More appropriate given import of 'java.util.List' }
    @@ -3996,22 +4008,22 @@ For historical reasons, modifiers which are implied by the context are accepted

    Example(s):

    -
    public @interface Annotation {
    +
    public @interface Annotation {
         public abstract void bar();     // both abstract and public are ignored by the compiler
    -    public static final int X = 0;  // public, static, and final all ignored
    +    public static final int X = 0;  // public, static, and final all ignored
         public static class Bar {}      // public, static ignored
         public static interface Baz {}  // ditto
     }
     public interface Foo {
         public abstract void bar();     // both abstract and public are ignored by the compiler
    -    public static final int X = 0;  // public, static, and final all ignored
    +    public static final int X = 0;  // public, static, and final all ignored
         public static class Bar {}      // public, static ignored
         public static interface Baz {}  // ditto
     }
     public class Bar {
         public static interface Baz {}  // static ignored
    -    public static enum FoorBar {    // static ignored
    -        FOO;
    +    public static enum FoorBar {    // static ignored
    +        FOO;
         }
     }
     
    @@ -4071,8 +4083,8 @@ which makes the code also more readable.

    Example(s):

    -
    List<String> strings = new ArrayList<String>(); // unnecessary duplication of type parameters
    -List<String> stringsWithDiamond = new ArrayList<>(); // using the diamond operator is more concise
    +
    List<String> strings = new ArrayList<String>(); // unnecessary duplication of type parameters
    +List<String> stringsWithDiamond = new ArrayList<>(); // using the diamond operator is more concise
     

    Use this rule by referencing it:

    @@ -4149,10 +4161,10 @@ which makes the code also more readable.

    public class Foo {
     
         private int _bar1;
    -    private Integer _bar2;
    +    private Integer _bar2;
     
         public void setBar(int n) {
    -        _bar1 = Integer.valueOf((n)); // here
    +        _bar1 = Integer.valueOf((n)); // here
             _bar2 = (n); // and here
         }
     }
    @@ -4182,27 +4194,27 @@ which makes the code also more readable.

    Example(s):

    public class Foo {
    -    final Foo otherFoo = Foo.this;  // use "this" directly
    +    final Foo otherFoo = Foo.this;  // use "this" directly
     
         public void doSomething() {
    -         final Foo anotherFoo = Foo.this;  // use "this" directly
    +         final Foo anotherFoo = Foo.this;  // use "this" directly
         }
     
    -    private ActionListener returnListener() {
    +    private ActionListener returnListener() {
             return new ActionListener() {
                 @Override
    -            public void actionPerformed(ActionEvent e) {
    -                doSomethingWithQualifiedThis(Foo.this);  // This is fine
    +            public void actionPerformed(ActionEvent e) {
    +                doSomethingWithQualifiedThis(Foo.this);  // This is fine
                 }
             };
         }
     
         private class Foo3 {
    -        final Foo myFoo = Foo.this;  // This is fine
    +        final Foo myFoo = Foo.this;  // This is fine
         }
     
         private class Foo2 {
    -        final Foo2 myFoo2 = Foo2.this;  // Use "this" direclty
    +        final Foo2 myFoo2 = Foo2.this;  // Use "this" direclty
         }
     }
     
    @@ -4230,8 +4242,8 @@ using new. Instead one can simply define

    Example(s):

    -
    Foo[] x = new Foo[] { ... }; // Overly verbose
    -Foo[] x = { ... }; //Equivalent to above line
    +
    Foo[] x = new Foo[] { ... }; // Overly verbose
    +Foo[] x = { ... }; //Equivalent to above line
     

    Use this rule by referencing it:

    @@ -4340,9 +4352,9 @@ by the more general rules
    public class Foo {
    -    public static final int MY_NUM = 0;
    -    public String myTest = "";
    -    DataModule dmTest = new DataModule();
    +    public static final int MY_NUM = 0;
    +    public String myTest = "";
    +    DataModule dmTest = new DataModule();
     }
     
    @@ -4505,7 +4517,7 @@ by the rule
    diff --git a/pmd_rules_java_design.html b/pmd_rules_java_design.html index 7e8033282f..726f83594a 100644 --- a/pmd_rules_java_design.html +++ b/pmd_rules_java_design.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1377,7 +1389,7 @@ protected constructor in order to prevent instantiation than make the class misl

    Example(s):

    public abstract class Example {
    -    String field;
    +    String field;
         int otherField;
     }
     
    @@ -1409,12 +1421,12 @@ protected constructor in order to prevent instantiation than make the class misl public void downCastPrimitiveType() { try { - System.out.println(" i [" + i + "]"); - } catch(Exception e) { + System.out.println(" i [" + i + "]"); + } catch(Exception e) { e.printStackTrace(); - } catch(RuntimeException e) { + } catch(RuntimeException e) { e.printStackTrace(); - } catch(NullPointerException e) { + } catch(NullPointerException e) { e.printStackTrace(); } } @@ -1503,7 +1515,7 @@ protected constructor in order to prevent instantiation than make the class misl
    public void bar() {
         try {
             // do something
    -    }  catch (SomeException se) {
    +    }  catch (SomeException se) {
            throw se;
         }
     }
    @@ -1539,7 +1551,7 @@ code size and runtime complexity.

    public void bar() {
         try {
             // do something
    -    } catch (SomeException se) {
    +    } catch (SomeException se) {
             // harmless comment
             throw new SomeException(se);
         }
    @@ -1627,7 +1639,7 @@ Exception, or Error, use a subclassed exception or error instead.

    Example(s):

    public class Foo {
    -    public void bar() throws Exception {
    +    public void bar() throws Exception {
             throw new Exception();
         }
     }
    @@ -1656,7 +1668,7 @@ exceptional cases with a @throws Javadoc
     
     

    Example(s):

    -
    public void foo() throws RuntimeException {
    +
    public void foo() throws RuntimeException {
     }
     
    @@ -1748,14 +1760,14 @@ A number higher than the specified threshold can indicate a high degree of coupl import org.Bardo; public class Foo { - private Blah var1; - private Bar var2; + private Blah var1; + private Bar var2; //followed by many imports of unique objects - void ObjectC doWork() { - Bardo var55; - ObjectA var44; - ObjectZ var93; + void ObjectC doWork() { + Bardo var55; + ObjectA var44; + ObjectZ var93; return something; } } @@ -1953,7 +1965,7 @@ into the former client classes.

    Example(s):

    -
    public class Foo extends Error { }
    +
    public class Foo extends Error { }
     

    Use this rule by referencing it:

    @@ -1976,11 +1988,11 @@ Either add the necessary validation or use an alternate control structure.

    public void bar() {
         try {
             try {
    -        } catch (Exception e) {
    +        } catch (Exception e) {
                 throw new WrapperException(e);
                 // this is essentially a GOTO to the WrapperException catch block
             }
    -    } catch (WrapperException e) {
    +    } catch (WrapperException e) {
             // do some more stuff
         }
     }
    @@ -2149,8 +2161,8 @@ Try to reduce the method length by creating helper methods and removing any copy
     

    Example(s):

    public void doSomething() {
    -    System.out.println("Hello world!");
    -    System.out.println("Hello world!");
    +    System.out.println("Hello world!");
    +    System.out.println("Hello world!");
         // 98 copies omitted for brevity.
     }
     
    @@ -2220,7 +2232,7 @@ same datatype. These situations usually denote the need for new objects to wrap } public void addPerson( // preferred approach - Date birthdate, BodyMeasurements measurements, int ssn) { + Date birthdate, BodyMeasurements measurements, int ssn) { . . . . } @@ -2287,9 +2299,9 @@ developed easily.

    Example(s):

    public class Foo {
    -    public String value;
    -    public Bar something;
    -    public Variable var;
    +    public String value;
    +    public Bar something;
    +    public Variable var;
         // [... more more public attributes ...]
     
         public void doWork() {}
    @@ -2363,7 +2375,7 @@ in each object at runtime.

    Example(s):

    public class Foo {
    -  public final int BAR = 42; // this could be static and save some space
    +  public final int BAR = 42; // this could be static and save some space
     }
     
    @@ -2477,9 +2489,9 @@ or objects.

    /** * This example will result in two violations. */ - public void example(Bar b) { + public void example(Bar b) { // this method call is ok, as b is a parameter of "example" - C c = b.getC(); + C c = b.getC(); // this method call is a violation, as we are using c, which we got from B. // We should ask b directly instead, e.g. "b.doItOnC();" @@ -2489,7 +2501,7 @@ or objects.

    b.getC().doIt(); // a constructor call, not a method call. - D d = new D(); + D d = new D(); // this method call is ok, because we have create the new instance of D locally. d.doSomethingElse(); } @@ -2550,7 +2562,7 @@ except when using one of the configured allowed classes.

    import some.other.package.subpackage.subsubpackage.DontUseThisClass; public class Bar { - DontUseThisClass boo = new DontUseThisClass(); + DontUseThisClass boo = new DontUseThisClass(); }
    @@ -2719,7 +2731,7 @@ by the rule
    public class Foo extends Bar {
    +
    public class Foo extends Bar {
         public Foo() {
             super();
     
    @@ -2799,7 +2811,7 @@ the 
     class Foo {                         // +1, total Ncss = 12
     
       public void bigMethod()           // +1
    -      throws IOException {
    +      throws IOException {
         int x = 0, y = 2;               // +1
         boolean a = false, b = true;    // +1
     
    @@ -2809,8 +2821,8 @@ the 
               x += 2;                   // +1
             } while (x < 12);
     
    -        System.exit(0);             // +1
    -      } catch (IOException ioe) {   // +1
    +        System.exit(0);             // +1
    +      } catch (IOException ioe) {   // +1
             throw new PatheticFailException(ioe); // +1
           }
         } else {
    @@ -2886,7 +2898,7 @@ by the rule 
    public class Foo extends Bar {
    +
    public class Foo extends Bar {
         public int methd() {
             super.methd();
     
    @@ -2965,7 +2977,7 @@ by the rule 
    public class Foo extends Bar {
    +
    public class Foo extends Bar {
         public Foo() {
             //this class only has 6 NCSS lines
             super();
    @@ -3048,20 +3060,20 @@ complexity and increase readability.

    boolean a, b = true; try { // 2 * 2 + 2 = 6 if (true) { // 2 - List buz = new ArrayList(); + List buz = new ArrayList(); } for(int i = 0; i < 19; i++) { // * 2 - List buz = new ArrayList(); + List buz = new ArrayList(); } - } catch(Exception e) { + } catch(Exception e) { if (true) { // 2 e.printStackTrace(); } } while (j++ < 20) { // * 2 - List buz = new ArrayList(); + List buz = new ArrayList(); } switch(j) { // * 7 @@ -3073,7 +3085,7 @@ complexity and increase readability.

    } do { // * 3 - List buz = new ArrayList(); + List buz = new ArrayList(); } while (a && j++ < 30); } } @@ -3133,7 +3145,7 @@ derived from RuntimeException or a checked exception.

    Example(s):

    -
    public void foo() throws Exception {
    +
    public void foo() throws Exception {
     }
     
    @@ -3256,7 +3268,7 @@ or

    Example(s):

    -
    public class SimpleTest extends TestCase {
    +
    public class SimpleTest extends TestCase {
         public void testX() {
             assertTrue("not empty", !r.isEmpty());  // replace with assertFalse("not empty", r.isEmpty())
             assertFalse(!r.isEmpty());              // replace with assertTrue(r.isEmpty())
    @@ -3364,8 +3376,8 @@ the conditional test can be returned instead.

    Example(s):

    class Foo {
    -  void bar(Object x) {
    -    if (x != null && x instanceof Bar) {
    +  void bar(Object x) {
    +    if (x != null && x instanceof Bar) {
           // just drop the "x != null" check
         }
       }
    @@ -3648,8 +3660,8 @@ city/state/zip fields could park them within a single Address field.

    } public class Person { // this is more manageable - Date birthDate; - BodyMeasurements measurements; + Date birthDate; + BodyMeasurements measurements; }
    @@ -3755,16 +3767,16 @@ complexity and find a way to have more fine grained objects.

    Example(s):

    -
    public void foo(String bar) {
    +
    public void foo(String bar) {
         super.foo(bar);      // why bother overriding?
     }
     
    -public String foo() {
    +public String foo() {
         return super.foo();  // why bother overriding?
     }
     
     @Id
    -public Long getId() {
    +public Long getId() {
         return super.getId();  // OK if 'ignoreAnnotations' is false, which is the default behavior
     }
     
    @@ -3824,10 +3836,10 @@ your API.

    Example(s):

    public class MyClass {
    -    public void connect(String username,
    -        String pssd,
    -        String databaseName,
    -        String databaseAdress)
    +    public void connect(String username,
    +        String pssd,
    +        String databaseName,
    +        String databaseAdress)
             // Instead of those parameters object
             // would ensure a cleaner API and permit
             // to add extra data transparently (no code change):
    @@ -3913,7 +3925,7 @@ remember to add a private constructor to prevent instantiation.
                 
    diff --git a/pmd_rules_java_documentation.html b/pmd_rules_java_documentation.html index b7ef51f11a..cad43f89e6 100644 --- a/pmd_rules_java_documentation.html +++ b/pmd_rules_java_documentation.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1694,7 +1706,7 @@ empty methods.

    diff --git a/pmd_rules_java_errorprone.html b/pmd_rules_java_errorprone.html index 6c4a722fc5..89a36e41a9 100644 --- a/pmd_rules_java_errorprone.html +++ b/pmd_rules_java_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1372,7 +1384,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    public void bar() {
         int x = 2;
         if ((x = getX()) == 3) {
    -      System.out.println("3!");
    +      System.out.println("3!");
         }
     }
     
    @@ -1497,26 +1509,26 @@ method visibility, even if they are private. This violates the principle of enca import java.security.PrivilegedAction; public class Violation { - public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException { + public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException { // Possible call to forbidden getDeclaredConstructors - Class[] arrayOfClass = new Class[1]; + Class[] arrayOfClass = new Class[1]; this.getClass().getDeclaredConstructors(); this.getClass().getDeclaredConstructor(arrayOfClass); - Class clazz = this.getClass(); + Class clazz = this.getClass(); clazz.getDeclaredConstructor(arrayOfClass); clazz.getDeclaredConstructors(); // Possible call to forbidden setAccessible clazz.getMethod("", arrayOfClass).setAccessible(false); - AccessibleObject.setAccessible(null, false); - Method.setAccessible(null, false); - Method[] methodsArray = clazz.getMethods(); + AccessibleObject.setAccessible(null, false); + Method.setAccessible(null, false); + Method[] methodsArray = clazz.getMethods(); int nbMethod; for ( nbMethod = 0; nbMethod < methodsArray.length; nbMethod++ ) { methodsArray[nbMethod].setAccessible(false); } // Possible call to forbidden PrivilegedAction - PrivilegedAction priv = (PrivilegedAction) new Object(); priv.run(); + PrivilegedAction priv = (PrivilegedAction) new Object(); priv.run(); } }
    @@ -1541,7 +1553,7 @@ method visibility, even if they are private. This violates the principle of enca
    public class A {
         public class Foo {
    -        String assert = "foo";
    +        String assert = "foo";
         }
     }
     
    @@ -1642,7 +1654,7 @@ that there are no more references to the object. It should not be invoked by app

    Example(s):

    void foo() {
    -    Bar b = new Bar();
    +    Bar b = new Bar();
         b.finalize();
     }
     
    @@ -1671,7 +1683,7 @@ original error, causing other, more subtle problems later on.

    void bar() { try { // do something - } catch (NullPointerException npe) { + } catch (NullPointerException npe) { } } } @@ -1697,7 +1709,7 @@ OutOfMemoryError that should be exposed and managed separately.

    public void bar() {
         try {
             // do something
    -    } catch (Throwable th) {  // should not catch Throwable
    +    } catch (Throwable th) {  // should not catch Throwable
             th.printStackTrace();
         }
     }
    @@ -1747,11 +1759,11 @@ exactly equal to 0.1, as one would expect.  Therefore, it is generally recommend
     
     

    Example(s):

    -
    BigDecimal bd = new BigDecimal(1.123);       // loss of precision, this would trigger the rule
    +
    BigDecimal bd = new BigDecimal(1.123);       // loss of precision, this would trigger the rule
     
    -BigDecimal bd = new BigDecimal("1.123");     // preferred approach
    +BigDecimal bd = new BigDecimal("1.123");     // preferred approach
     
    -BigDecimal bd = new BigDecimal(12);          // preferred approach, ok for integer values
    +BigDecimal bd = new BigDecimal(12);          // preferred approach, ok for integer values
     

    Use this rule by referencing it:

    @@ -1776,7 +1788,7 @@ exactly equal to 0.1, as one would expect. Therefore, it is generally recommend buz("Howdy"); buz("Howdy"); } -private void buz(String x) {} +private void buz(String x) {}

    This rule has the following properties:

    @@ -1862,7 +1874,7 @@ exactly equal to 0.1, as one would expect. Therefore, it is generally recommend
    public class A {
         public class Foo {
    -        String enum = "foo";
    +        String enum = "foo";
         }
     }
     
    @@ -1886,7 +1898,7 @@ Smalltalk often prefer this approach as the methods denote accessor methods.

    Example(s):

    public class Foo {
    -    Object bar;
    +    Object bar;
         // bar is data or an action or both?
         void bar() {
         }
    @@ -1910,7 +1922,7 @@ This probably means that type and/or field names should be chosen more carefully
     
     

    Example(s):

    -
    public class Foo extends Bar {
    +
    public class Foo extends Bar {
         int foo;    // There is probably a better name that can be used
     }
     
    @@ -1940,15 +1952,15 @@ This probably means that type and/or field names should be chosen more carefully
    try { // Avoid this
         // do something
    -} catch (Exception ee) {
    -    if (ee instanceof IOException) {
    +} catch (Exception ee) {
    +    if (ee instanceof IOException) {
             cleanup();
         }
     }
     
     try {  // Prefer this:
         // do something
    -} catch (IOException ee) {
    +} catch (IOException ee) {
         cleanup();
     }
     
    @@ -1998,7 +2010,7 @@ the property ignoreMagicNumbers is not taken into account, if there are multiple

    Example(s):

    -
    private static final int MAX_NUMBER_OF_REQUESTS = 10;
    +
    private static final int MAX_NUMBER_OF_REQUESTS = 10;
     
     public void checkRequests() {
     
    @@ -2006,7 +2018,7 @@ the property ignoreMagicNumbers is not taken into account, if there are multiple
           doSomething();
         }
     
    -    if (i == MAX_NUMBER_OF_REQUESTS) {    // preferred approach
    +    if (i == MAX_NUMBER_OF_REQUESTS) {    // preferred approach
           doSomething();
         }
     
    @@ -2014,11 +2026,11 @@ the property ignoreMagicNumbers is not taken into account, if there are multiple
         if (aString.indexOf('.') >= 0) { }     // alternative approach
     
         if (aDouble > 0.0) {}                  // magic number 0.0
    -    if (aDouble >= Double.MIN_VALUE) {}    // preferred approach
    +    if (aDouble >= Double.MIN_VALUE) {}    // preferred approach
     
         // with rule property "ignoreExpressions" set to "false"
         if (i == pos + 5) {}  // violation: magic number 5 within an (additive) expression
    -    if (i == pos + SUFFIX_LENGTH) {} // preferred approach
    +    if (i == pos + SUFFIX_LENGTH) {} // preferred approach
     }
     
    @@ -2091,7 +2103,7 @@ only add to code size. Either remove the invocation, or use the return result.<
    public void bar() {
         try {
             // do something
    -    } catch (SomeException se) {
    +    } catch (SomeException se) {
             se.getMessage();
         }
     }
    @@ -2205,7 +2217,7 @@ precision when comparing floating point numbers these are likely to cause logic
     
     

    Example(s):

    -
    boolean x = (y == Double.NaN);
    +
    boolean x = (y == Double.NaN);
     

    Use this rule by referencing it:

    @@ -2294,7 +2306,7 @@ It is likely that you used || instead of && or vice versa.

    Example(s):

    -
    public String bar(String string) {
    +
    public String bar(String string) {
       // should be &&
         if (string!=null || !string.equals(""))
             return string;
    @@ -2338,8 +2350,8 @@ It is likely that you used || instead of && or vice versa.

    Example(s):

    -
    public class DummyActivity extends Activity {
    -    public void onCreate(Bundle bundle) {
    +
    public class DummyActivity extends Activity {
    +    public void onCreate(Bundle bundle) {
             // missing call to super.onCreate(bundle)
             foo();
         }
    @@ -2378,7 +2390,7 @@ It is likely that you used || instead of && or vice versa.

    Example(s):

    -
    public class DummyActivity extends Activity {
    +
    public class DummyActivity extends Activity {
         public void onPause() {
             foo();
             // missing call to super.onPause()
    @@ -2404,13 +2416,13 @@ It is likely that you used || instead of && or vice versa.

    public class Foo {
     
    -   private FileInputStream _s = new FileInputStream("file");
    +   private FileInputStream _s = new FileInputStream("file");
     
    -   public void skip(int n) throws IOException {
    +   public void skip(int n) throws IOException {
           _s.skip(n); // You are not sure that exactly n bytes are skipped
        }
     
    -   public void skipExactly(int n) throws IOException {
    +   public void skipExactly(int n) throws IOException {
           while (n != 0) {
              long skipped = _s.skip(n);
              if (skipped == 0)
    @@ -2448,15 +2460,15 @@ in a ClassCastException.

    Example(s):

    -
    Collection c = new ArrayList();
    -Integer obj = new Integer(1);
    +
    Collection c = new ArrayList();
    +Integer obj = new Integer(1);
     c.add(obj);
     
         // this would trigger the rule (and throw a ClassCastException if executed)
    -Integer[] a = (Integer [])c.toArray();
    +Integer[] a = (Integer [])c.toArray();
     
        // this is fine and will not trigger the rule
    -Integer[] b = (Integer [])c.toArray(new Integer[c.size()]);
    +Integer[] b = (Integer [])c.toArray(new Integer[c.size()]);
     

    Use this rule by referencing it:

    @@ -2480,21 +2492,21 @@ Object.clone (which is protected) with a public method."

    Example(s):

    -
    public class Foo implements Cloneable {
    +
    public class Foo implements Cloneable {
         @Override
    -    protected Object clone() throws CloneNotSupportedException { // Violation, must be public
    +    protected Object clone() throws CloneNotSupportedException { // Violation, must be public
         }
     }
     
    -public class Foo implements Cloneable {
    +public class Foo implements Cloneable {
         @Override
    -    protected Foo clone() { // Violation, must be public
    +    protected Foo clone() { // Violation, must be public
         }
     }
     
    -public class Foo implements Cloneable {
    +public class Foo implements Cloneable {
         @Override
    -    public Object clone() // Ok
    +    public Object clone() // Ok
     }
     
    @@ -2518,7 +2530,7 @@ a final method that only throws CloneNotSupportedException.

    Example(s):

    public class MyClass {
    - public Object clone() throws CloneNotSupportedException {
    + public Object clone() throws CloneNotSupportedException {
       return foo;
      }
     }
    @@ -2552,15 +2564,15 @@ of the clone method doesn’t need to cast the returned clone to the correct typ
     
     

    Example(s):

    -
    public class Foo implements Cloneable {
    +
    public class Foo implements Cloneable {
         @Override
    -    protected Object clone() { // Violation, Object must be Foo
    +    protected Object clone() { // Violation, Object must be Foo
         }
     }
     
    -public class Foo implements Cloneable {
    +public class Foo implements Cloneable {
         @Override
    -    public Foo clone() { //Ok
    +    public Foo clone() { //Ok
         }
     }
     
    @@ -2592,9 +2604,9 @@ of the clone method doesn’t need to cast the returned clone to the correct typ

    Example(s):

    -
    public class MyClass implements Cloneable{
    -    public Object clone() { // will cause an error
    -         MyClass clone = (MyClass)super.clone();
    +
    public class MyClass implements Cloneable{
    +    public Object clone() { // will cause an error
    +         MyClass clone = (MyClass)super.clone();
              return clone;
         }
     }
    @@ -2628,10 +2640,10 @@ just remove "AutoCloseable" from the types.

    public class Bar {
         public void withSQL() {
    -        Connection c = pool.getConnection();
    +        Connection c = pool.getConnection();
             try {
                 // do stuff
    -        } catch (SQLException ex) {
    +        } catch (SQLException ex) {
                // handle exception
             } finally {
                 // oops, should close the connection using 'close'!
    @@ -2640,10 +2652,10 @@ just remove "AutoCloseable" from the types.

    } public void withFile() { - InputStream file = new FileInputStream(new File("/tmp/foo")); + InputStream file = new FileInputStream(new File("/tmp/foo")); try { int c = file.in(); - } catch (IOException e) { + } catch (IOException e) { // handle exception } finally { // TODO: close file @@ -2719,7 +2731,7 @@ just remove "AutoCloseable" from the types.

    Example(s):

    class Foo {
    -  boolean bar(String a, String b) {
    +  boolean bar(String a, String b) {
         return a == b;
       }
     }
    @@ -2751,17 +2763,17 @@ private method bar() that calls a public method buz(), this denotes a problem.public SeniorClass(){
           toString(); //may throw NullPointerException if overridden
       }
    -  public String toString(){
    +  public String toString(){
         return "IAmSeniorClass";
       }
     }
    -public class JuniorClass extends SeniorClass {
    -  private String name;
    +public class JuniorClass extends SeniorClass {
    +  private String name;
       public JuniorClass(){
         super(); //Automatic call leads to NullPointerException
         name = "JuniorClass";
       }
    -  public String toString(){
    +  public String toString(){
         return name.toUpperCase();
       }
     }
    @@ -2913,22 +2925,22 @@ leaks develop within an application, it should be dealt with JVM options rather
     
    public class GCCall {
         public GCCall() {
             // Explicit gc call !
    -        System.gc();
    +        System.gc();
         }
     
         public void doSomething() {
             // Explicit gc call !
    -        Runtime.getRuntime().gc();
    +        Runtime.getRuntime().gc();
         }
     
         public explicitGCcall() {
             // Explicit gc call !
    -        System.gc();
    +        System.gc();
         }
     
         public void doSomething() {
             // Explicit gc call !
    -        Runtime.getRuntime().gc();
    +        Runtime.getRuntime().gc();
         }
     }
     
    @@ -2957,10 +2969,10 @@ application server should stop the JVM. This rule also checks for the equivalent

    Example(s):

    public void bar() {
    -    System.exit(0);                 // never call this when running in an application server!
    +    System.exit(0);                 // never call this when running in an application server!
     }
     public void foo() {
    -    Runtime.getRuntime().exit(0);   // never stop the JVM manually, the container will do this.
    +    Runtime.getRuntime().exit(0);   // never stop the JVM manually, the container will do this.
     }
     
    @@ -2983,7 +2995,7 @@ application server should stop the JVM. This rule also checks for the equivalent

    Example(s):

    -
    public class Foo extends Throwable { }
    +
    public class Foo extends Throwable { }
     

    Use this rule by referencing it:

    @@ -3004,11 +3016,11 @@ application server should stop the JVM. This rule also checks for the equivalent

    Example(s):

    -
    public class MyActivity extends Activity {
    +
    public class MyActivity extends Activity {
         protected void foo() {
    -        String storageLocation = "/sdcard/mypackage";   // hard-coded, poor approach
    +        String storageLocation = "/sdcard/mypackage";   // hard-coded, poor approach
     
    -       storageLocation = Environment.getExternalStorageDirectory() + "/mypackage"; // preferred approach
    +       storageLocation = Environment.getExternalStorageDirectory() + "/mypackage"; // preferred approach
         }
     }
     
    @@ -3037,7 +3049,7 @@ Note: This is a PMD implementation of the Lint4j rule "A throw in a finally bloc public void bar() { try { // Here do some stuff - } catch( Exception e) { + } catch( Exception e) { // Handling the issue } finally { // is this really a good idea ? @@ -3089,13 +3101,13 @@ performance need (space or time).

    Example(s):

    public class Count {
    -  public static void main(String[] args) {
    -    final int START = 2000000000;
    +  public static void main(String[] args) {
    +    final int START = 2000000000;
         int count = 0;
    -    for (float f = START; f < START + 50; f++)
    +    for (float f = START; f < START + 50; f++)
           count++;
           //Prints 0 because (float) START == (float) (START + 50).
    -      System.out.println(count);
    +      System.out.println(count);
           //The termination test misbehaves due to floating point granularity.
         }
     }
    @@ -3128,8 +3140,8 @@ or reported.

    public void doSomething() {
         try {
    -        FileInputStream fis = new FileInputStream("/tmp/bugger");
    -    } catch (IOException ioe) {
    +        FileInputStream fis = new FileInputStream("/tmp/bugger");
    +    } catch (IOException ioe) {
             // not good
         }
     }
    @@ -3342,7 +3354,7 @@ and should be removed.

    // this is probably not what you meant to do ; // the extra semicolon here this is not necessary - System.out.println("look at the extra semicolon");; + System.out.println("look at the extra semicolon");; }
    @@ -3421,7 +3433,7 @@ and should be removed.

    public class Foo {
         public void bar() {
             try {
    -        } catch (Exception e) {
    +        } catch (Exception e) {
                 e.printStackTrace();
             }
         }
    @@ -3485,7 +3497,7 @@ a while loop that does a lot in the exit expression, rewrite it to make it clear
     
     

    Example(s):

    -
    String x = "foo";
    +
    String x = "foo";
     
     if (x.equals(null)) {   // bad form
         doSomething();
    @@ -3688,10 +3700,10 @@ other classes may invoke it at inappropriate times.

    Example(s):

    // replace this
    -Class c = new String().getClass();
    +Class c = new String().getClass();
     
     // with this:
    -Class c = String.class;
    +Class c = String.class;
     

    Use this rule by referencing it:

    @@ -3710,9 +3722,9 @@ other classes may invoke it at inappropriate times.

    Example(s):

    -
    LOGGER.error("forget the arg {}");
    -LOGGER.error("too many args {}", "arg1", "arg2");
    -LOGGER.error("param {}", "arg1", new IllegalStateException("arg")); //The exception is shown separately, so is correct.
    +
    LOGGER.error("forget the arg {}");
    +LOGGER.error("too many args {}", "arg1", "arg2");
    +LOGGER.error("param {}", "arg1", new IllegalStateException("arg")); //The exception is shown separately, so is correct.
     

    Use this rule by referencing it:

    @@ -3742,7 +3754,7 @@ other classes may invoke it at inappropriate times.

    public void foo() { for (int i = 0; i < 10; i++) { // only references 'i' for (int k = 0; k < 20; i++) { // references both 'i' and 'k' - System.out.println("Hello"); + System.out.println("Hello"); } } } @@ -3781,7 +3793,7 @@ other classes may invoke it at inappropriate times.

    import junit.framework.*;
     
    -public class Foo extends TestCase {
    +public class Foo extends TestCase {
         public void setup() {}    // oops, should be setUp
         public void TearDown() {} // oops, should be tearDown
     }
    @@ -3817,7 +3829,7 @@ other classes may invoke it at inappropriate times.

    import junit.framework.*;
     
    -public class Foo extends TestCase {
    +public class Foo extends TestCase {
         public void suite() {}         // oops, should be static
         private static void suite() {} // oops, should be public
     }
    @@ -3852,9 +3864,9 @@ The rule is replaced by Example(s):

    public class Foo{
    -    Logger log = Logger.getLogger(Foo.class.getName());                 // not recommended
    +    Logger log = Logger.getLogger(Foo.class.getName());                 // not recommended
     
    -    static final Logger log = Logger.getLogger(Foo.class.getName());    // preferred approach
    +    static final Logger log = Logger.getLogger(Foo.class.getName());    // preferred approach
     }
     
    @@ -4002,7 +4014,7 @@ chain needs an own serialVersionUID field. See also
    public class Foo implements java.io.Serializable {
    -    String name;
    +    String name;
         // Define serialization id to avoid serialization related bugs
         // i.e., public static final long serialVersionUID = 4328743;
     }
    @@ -4125,10 +4137,10 @@ log4j2 (since 6.19.0).

    Example(s):

    public class Foo {
    -    Logger log = Logger.getLogger(Foo.class.getName());
    +    Logger log = Logger.getLogger(Foo.class.getName());
         // It is very rare to see two loggers on a class, normally
         // log information is multiplexed by levels
    -    Logger log2= Logger.getLogger(Foo.class.getName());
    +    Logger log2= Logger.getLogger(Foo.class.getName());
     }
     
    @@ -4189,7 +4201,7 @@ confusing.

    public class MyClass {
       // this block gets run before any call to a constructor
       {
    -    System.out.println("I am about to construct myself");
    +    System.out.println("I am about to construct myself");
       }
     }
     
    @@ -4214,8 +4226,8 @@ of assignment is an indication that the programmer doesn’t completely understa

    Example(s):

    public void bar() {
    -  Object x = null; // this is OK
    -  x = new Object();
    +  Object x = null; // this is OK
    +  x = new Object();
          // big, complex piece of code here
       x = null; // this is not required
          // big, complex piece of code here
    @@ -4239,7 +4251,7 @@ of assignment is an indication that the programmer doesn’t completely understa
     

    Example(s):

    public class Bar {        // poor, missing a hashcode() method
    -    public boolean equals(Object o) {
    +    public boolean equals(Object o) {
           // do some comparison
         }
     }
    @@ -4251,7 +4263,7 @@ of assignment is an indication that the programmer doesn’t completely understa
     }
     
     public class Foo {        // perfect, both methods provided
    -    public boolean equals(Object other) {
    +    public boolean equals(Object other) {
           // do some comparison
         }
         public int hashCode() {
    @@ -4287,7 +4299,7 @@ of assignment is an indication that the programmer doesn’t completely understa
     

    Example(s):

    class Foo{
    -    public Object clone(){
    +    public Object clone(){
             return new Foo(); // This is bad
         }
     }
    @@ -4339,9 +4351,9 @@ with the restriction that the logger needs to be passed into the constructor.

    public class Foo {
     
    -    private static final Log LOG = LogFactory.getLog(Foo.class);    // proper way
    +    private static final Log LOG = LogFactory.getLog(Foo.class);    // proper way
     
    -    protected Log LOG = LogFactory.getLog(Testclass.class);         // wrong approach
    +    protected Log LOG = LogFactory.getLog(Testclass.class);         // wrong approach
     }
     
    @@ -4421,9 +4433,9 @@ NullPointerExceptions.

    } // Good behavior - public String[] bonnePratique() { + public String[] bonnePratique() { //... - return new String[0]; + return new String[0]; } }
    @@ -4447,10 +4459,10 @@ NullPointerExceptions.

    Example(s):

    public class Bar {
    -    public String foo() {
    +    public String foo() {
             try {
                 throw new Exception( "My Exception" );
    -        } catch (Exception e) {
    +        } catch (Exception e) {
                 throw e;
             } finally {
                 return "A. O. K."; // return not recommended here
    @@ -4482,7 +4494,7 @@ formatting is used.

    public class Foo {
       // Should specify Locale.US (or whatever)
    -  private SimpleDateFormat sdf = new SimpleDateFormat("pattern");
    +  private SimpleDateFormat sdf = new SimpleDateFormat("pattern");
     }
     
    @@ -4506,16 +4518,16 @@ for each call and new objects will be created for every invocation.

    public class Singleton {
     
    -    private static Singleton singleton = new Singleton( );
    +    private static Singleton singleton = new Singleton( );
     
         private Singleton(){ }
     
    -    public static Singleton getInstance( ) {
    +    public static Singleton getInstance( ) {
             return singleton;
         }
     
    -    public static Singleton getInstance(Object obj){
    -        Singleton singleton = (Singleton) obj;
    +    public static Singleton getInstance(Object obj){
    +        Singleton singleton = (Singleton) obj;
             return singleton;           //violation
         }
     }
    @@ -4540,9 +4552,9 @@ for each call and new objects will be created for every invocation.

    Example(s):

    class Singleton {
    -    private static Singleton instance = null;
    -    public static Singleton getInstance() {
    -        synchronized(Singleton.class) {
    +    private static Singleton instance = null;
    +    public static Singleton getInstance() {
    +        synchronized(Singleton.class) {
                 return new Singleton();
             }
         }
    @@ -4587,11 +4599,11 @@ behavior especially when instances are distributed by the container on several J
     
     

    Example(s):

    -
    public class SomeEJB extends EJBObject implements EJBLocalHome {
    +
    public class SomeEJB extends EJBObject implements EJBLocalHome {
     
    -    private static int CountA;          // poor, field can be edited
    +    private static int CountA;          // poor, field can be edited
     
    -    private static final int CountB;    // preferred, read-only access
    +    private static final int CountB;    // preferred, read-only access
     }
     
    @@ -4635,12 +4647,12 @@ new StringBuilder("A") // 1 + 16 = 17
    // misleading instantiation, these buffers
     // are actually sized to 99 characters long
    -StringBuffer  sb1 = new StringBuffer('c');
    -StringBuilder sb2 = new StringBuilder('c');
    +StringBuffer  sb1 = new StringBuffer('c');
    +StringBuilder sb2 = new StringBuilder('c');
     
     // in these forms, just single characters are allocated
    -StringBuffer  sb3 = new StringBuffer("c");
    -StringBuilder sb4 = new StringBuilder("c");
    +StringBuffer  sb3 = new StringBuffer("c");
    +StringBuilder sb4 = new StringBuilder("c");
     

    Use this rule by referencing it:

    @@ -4681,13 +4693,13 @@ intention to override the equals(Object) method.

    Example(s):

    public class Foo {
    -   public int equals(Object o) {
    +   public int equals(Object o) {
          // oops, this probably was supposed to be boolean equals
        }
    -   public boolean equals(String s) {
    +   public boolean equals(String s) {
          // oops, this probably was supposed to be equals(Object)
        }
    -   public boolean equals(Object o1, Object o2) {
    +   public boolean equals(Object o1, Object o2) {
          // oops, this probably was supposed to be equals(Object)
        }
     }
    @@ -4744,7 +4756,7 @@ the literal character "8".

    public void foo() {
       // interpreted as octal 12, followed by character '8'
    -  System.out.println("suspicious: \128");
    +  System.out.println("suspicious: \128");
     }
     
    @@ -4768,7 +4780,7 @@ since most people will assume it is a test case. Test classes have test methods
    //Consider changing the name of the class if it is not a test
     //Consider adding test methods if it is a test
     public class CarTest {
    -   public static void main(String[] args) {
    +   public static void main(String[] args) {
         // do something
        }
        // code
    @@ -4842,7 +4854,7 @@ an error, use the fail() method and provide an indication message of why it did.
     
     

    Example(s):

    -
    public class SimpleTest extends TestCase {
    +
    public class SimpleTest extends TestCase {
         public void testX() {
             assertTrue(true);       // serves no real purpose
         }
    @@ -4887,10 +4899,10 @@ on the wrapper classes instead.

    Example(s):

    -
    public String convert(int x) {
    -    String foo = new Integer(x).toString(); // this wastes an object
    +
    public String convert(int x) {
    +    String foo = new Integer(x).toString(); // this wastes an object
     
    -    return Integer.toString(x);             // preferred approach
    +    return Integer.toString(x);             // preferred approach
     }
     
    @@ -4920,11 +4932,11 @@ on the wrapper classes instead.

    public class Test {
     
    -    public String method1() { return "ok";}
    -    public String method2() { return null;}
    +    public String method1() { return "ok";}
    +    public String method2() { return null;}
     
    -    public void method(String a) {
    -        String b;
    +    public void method(String a) {
    +        String b;
             // I don't know it method1() can be "null"
             // but I know "a" is not null..
             // I'd better write a.equals(method1())
    @@ -4980,12 +4992,12 @@ on the wrapper classes instead.

    Example(s):

    public class Main {
    -    private static final Log _LOG = LogFactory.getLog( Main.class );
    +    private static final Log _LOG = LogFactory.getLog( Main.class );
         void bar() {
             try {
    -        } catch( Exception e ) {
    +        } catch( Exception e ) {
                 _LOG.error( e ); //Wrong!
    -        } catch( OtherException oe ) {
    +        } catch( OtherException oe ) {
                 _LOG.error( oe.getMessage(), oe ); //Correct
             }
         }
    @@ -5015,7 +5027,7 @@ Use the equals() method instead.

    Example(s):

    -
    public boolean test(String s) {
    +
    public boolean test(String s) {
         if (s == "one") return true;        // unreliable
         if ("two".equals(s)) return true;   // better
         return false;
    @@ -5043,12 +5055,12 @@ since the result of the operation is a new object. Therefore, ignoring the opera
     
     class Test {
         void method1() {
    -        BigDecimal bd=new BigDecimal(10);
    -        bd.add(new BigDecimal(5));      // this will trigger the rule
    +        BigDecimal bd=new BigDecimal(10);
    +        bd.add(new BigDecimal(5));      // this will trigger the rule
         }
         void method2() {
    -        BigDecimal bd=new BigDecimal(10);
    -        bd = bd.add(new BigDecimal(5)); // this won't trigger the rule
    +        BigDecimal bd=new BigDecimal(10);
    +        bd = bd.add(new BigDecimal(5)); // this won't trigger the rule
         }
     }
     
    @@ -5100,15 +5112,15 @@ to future readers.

    // The above will not match "LIST" on a system with a Turkish locale. // It could be replaced with -if (x.toLowerCase(Locale.US).equals("list")) { } +if (x.toLowerCase(Locale.US).equals("list")) { } // or simply if (x.equalsIgnoreCase("list")) { } // ok - system independent conversion -String z = a.toLowerCase(Locale.ROOT); +String z = a.toLowerCase(Locale.ROOT); // ok - explicit system-dependent conversion -String z2 = a.toLowerCase(Locale.getDefault()); +String z2 = a.toLowerCase(Locale.getDefault());

    Use this rule by referencing it:

    @@ -5131,7 +5143,7 @@ Thread.currentThread().getContextClassLoader() instead.

    Example(s):

    public class Foo {
    -    ClassLoader cl = Bar.class.getClassLoader();
    +    ClassLoader cl = Bar.class.getClassLoader();
     }
     
    @@ -5155,7 +5167,7 @@ Thread.currentThread().getContextClassLoader() instead.

    diff --git a/pmd_rules_java_multithreading.html b/pmd_rules_java_multithreading.html index 73fd29f3d9..fd59e18be1 100644 --- a/pmd_rules_java_multithreading.html +++ b/pmd_rules_java_multithreading.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1389,7 +1401,7 @@ gets it.

    // Prefer this: static void barStatic() { - synchronized(Foo.class) { + synchronized(Foo.class) { } } } @@ -1417,10 +1429,10 @@ it contains methods that are not thread-safe.

    public class Bar {
         void buz() {
    -        ThreadGroup tg = new ThreadGroup("My threadgroup");
    -        tg = new ThreadGroup(tg, "my thread group");
    -        tg = Thread.currentThread().getThreadGroup();
    -        tg = System.getSecurityManager().getThreadGroup();
    +        ThreadGroup tg = new ThreadGroup("My threadgroup");
    +        tg = new ThreadGroup(tg, "my thread group");
    +        tg = Thread.currentThread().getThreadGroup();
    +        tg = System.getSecurityManager().getThreadGroup();
         }
     }
     
    @@ -1446,8 +1458,8 @@ the volatile keyword should not be used for maintenance purpose and portability.

    Example(s):

    public class ThrDeux {
    -  private volatile String var1; // not suggested
    -  private          String var2; // preferred
    +  private volatile String var1; // not suggested
    +  private          String var2; // preferred
     }
     
    @@ -1474,15 +1486,15 @@ Also EJB’s might be moved between machines in a cluster and only managed resou

    Example(s):

    // This is not allowed
    -public class UsingThread extends Thread {
    +public class UsingThread extends Thread {
     
     }
     
     // Neither this,
    -public class OtherThread implements Runnable {
    +public class OtherThread implements Runnable {
         // Nor this ...
         public void methode() {
    -        Runnable thread = new Thread(); thread.run();
    +        Runnable thread = new Thread(); thread.run();
         }
     }
     
    @@ -1515,7 +1527,7 @@ Also EJB’s might be moved between machines in a cluster and only managed resou

    Example(s):

    -
    Thread t = new Thread();
    +
    Thread t = new Thread();
     t.run();            // use t.start() instead
     new Thread().run(); // same violation
     
    @@ -1544,12 +1556,12 @@ or
    public class Foo {
    -    /*volatile */ Object baz = null; // fix for Java5 and later: volatile
    -    Object bar() {
    +    /*volatile */ Object baz = null; // fix for Java5 and later: volatile
    +    Object bar() {
             if (baz == null) { // baz may be non-null yet not fully created
                 synchronized(this) {
                     if (baz == null) {
    -                    baz = new Object();
    +                    baz = new Object();
                     }
                   }
             }
    @@ -1584,12 +1596,12 @@ performance penalty. 
    private static Foo foo = null;
    +
    private static Foo foo = null;
     
     //multiple simultaneous callers may see partially initialized objects
    -public static Foo getFoo() {
    +public static Foo getFoo() {
         if (foo==null) {
    -        foo = new Foo();
    +        foo = new Foo();
         }
         return foo;
     }
    @@ -1654,7 +1666,7 @@ synchronized on block level.

    Example(s):

    public class Foo {
    -    private static final SimpleDateFormat sdf = new SimpleDateFormat();
    +    private static final SimpleDateFormat sdf = new SimpleDateFormat();
         void bar() {
             sdf.format(); // poor, no thread-safety
         }
    @@ -1715,7 +1727,7 @@ synchronized on block level.

    Example(s):

    public class Foo {
    -    private static final SimpleDateFormat sdf = new SimpleDateFormat();
    +    private static final SimpleDateFormat sdf = new SimpleDateFormat();
         void bar() {
             sdf.format(); // poor, no thread-safety
         }
    @@ -1780,11 +1792,11 @@ perform efficient map reads without blocking other threads.

    public class ConcurrentApp {
       public void getMyInstance() {
    -    Map map1 = new HashMap();           // fine for single-threaded access
    -    Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads
    +    Map map1 = new HashMap();           // fine for single-threaded access
    +    Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads
     
         // the following case will be ignored by this rule
    -    Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
    +    Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
       }
     }
     
    @@ -1844,7 +1856,7 @@ one is chosen. The thread chosen is arbitrary; thus its usually safer to call n
    diff --git a/pmd_rules_java_performance.html b/pmd_rules_java_performance.html index 49d70dd881..79e3a52cac 100644 --- a/pmd_rules_java_performance.html +++ b/pmd_rules_java_performance.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1372,8 +1384,8 @@ It is much better to use one of the type-specific toString() methods instead.

    Example(s):

    -
    String s = "" + 123;                // inefficient
    -String t = Integer.toString(456);   // preferred approach
    +
    String s = "" + 123;                // inefficient
    +String t = Integer.toString(456);   // preferred approach
     

    Use this rule by referencing it:

    @@ -1392,10 +1404,10 @@ It is much better to use one of the type-specific toString() methods instead.

    Example(s):

    -
    StringBuffer sb = new StringBuffer();
    +
    StringBuffer sb = new StringBuffer();
     sb.append("a");     // avoid this
     
    -StringBuffer sb = new StringBuffer();
    +StringBuffer sb = new StringBuffer();
     sb.append('a');     // use this instead
     
    @@ -1493,20 +1505,20 @@ that one covers both.

    // these instantiations cause garbage collection pauses, even if properly closed
     
    -    FileInputStream fis = new FileInputStream(fileName);
    -    FileOutputStream fos = new FileOutputStream(fileName);
    -    FileReader fr = new FileReader(fileName);
    -    FileWriter fw = new FileWriter(fileName);
    +    FileInputStream fis = new FileInputStream(fileName);
    +    FileOutputStream fos = new FileOutputStream(fileName);
    +    FileReader fr = new FileReader(fileName);
    +    FileWriter fw = new FileWriter(fileName);
     
         // the following instantiations help prevent Garbage Collection pauses, no finalization
     
    -    try(InputStream is = Files.newInputStream(Paths.get(fileName))) {
    +    try(InputStream is = Files.newInputStream(Paths.get(fileName))) {
         }
    -    try(OutputStream os = Files.newOutputStream(Paths.get(fileName))) {
    +    try(OutputStream os = Files.newOutputStream(Paths.get(fileName))) {
         }
    -    try(BufferedReader br = Files.newBufferedReader(Paths.get(fileName), StandardCharsets.UTF_8)) {
    +    try(BufferedReader br = Files.newBufferedReader(Paths.get(fileName), StandardCharsets.UTF_8)) {
         }
    -    try(BufferedWriter wr = Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8)) {
    +    try(BufferedWriter wr = Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8)) {
         }
     
    @@ -1527,9 +1539,9 @@ that one covers both.

    Example(s):

    public class Something {
    -    public static void main( String as[] ) {
    +    public static void main( String as[] ) {
             for (int i = 0; i < 10; i++) {
    -            Foo f = new Foo(); // Avoid this whenever you can it's really expensive
    +            Foo f = new Foo(); // Avoid this whenever you can it's really expensive
             }
         }
     }
    @@ -1593,11 +1605,11 @@ for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal
     
     

    Example(s):

    -
    BigInteger bi = new BigInteger(1);       // reference BigInteger.ONE instead
    -BigInteger bi2 = new BigInteger("0");    // reference BigInteger.ZERO instead
    -BigInteger bi3 = new BigInteger(0.0);    // reference BigInteger.ZERO instead
    -BigInteger bi4;
    -bi4 = new BigInteger(0);                 // reference BigInteger.ZERO instead
    +
    BigInteger bi = new BigInteger(1);       // reference BigInteger.ONE instead
    +BigInteger bi2 = new BigInteger("0");    // reference BigInteger.ZERO instead
    +BigInteger bi3 = new BigInteger(0.0);    // reference BigInteger.ZERO instead
    +BigInteger bi4;
    +bi4 = new BigInteger(0);                 // reference BigInteger.ZERO instead
     

    Use this rule by referencing it:

    @@ -1617,8 +1629,8 @@ Note that new Boolean() is deprecated since JDK 9 for that reason.

    Example(s):

    -
    Boolean bar = new Boolean("true");        // unnecessary creation, just reference Boolean.TRUE;
    -Boolean buz = Boolean.valueOf(false);    // ...., just reference Boolean.FALSE;
    +
    Boolean bar = new Boolean("true");        // unnecessary creation, just reference Boolean.TRUE;
    +Boolean buz = Boolean.valueOf(false);    // ...., just reference Boolean.FALSE;
     

    Use this rule by referencing it:

    @@ -1644,7 +1656,7 @@ Note that new Byte() is deprecated since JDK 9 for that reason.

    Example(s):

    public class Foo {
    -    private Byte i = new Byte(0); // change to Byte i = Byte.valueOf(0);
    +    private Byte i = new Byte(0); // change to Byte i = Byte.valueOf(0);
     }
     
    @@ -1665,14 +1677,14 @@ by producing a smaller bytecode, reducing overhead and improving inlining. A com

    Example(s):

    -
    String foo = " ";
    +
    String foo = " ";
     
    -StringBuffer buf = new StringBuffer();
    +StringBuffer buf = new StringBuffer();
     buf.append("Hello"); // poor
     buf.append(foo);
     buf.append("World");
     
    -StringBuffer buf = new StringBuffer();
    +StringBuffer buf = new StringBuffer();
     buf.append("Hello").append(foo).append("World"); // good
     
    @@ -1694,7 +1706,7 @@ can be appended in a single method call.

    Example(s):

    -
    StringBuilder buf = new StringBuilder();
    +
    StringBuilder buf = new StringBuilder();
     buf.append("Hello").append(" ").append("World");    // poor
     buf.append("Hello World");                          // good
     
    @@ -1750,9 +1762,9 @@ Consider creating a static function that loops through a string, checking Charac
     on each character and returning false if a non-whitespace character is found. A Smarter code to
     check for an empty string would be:

    -
    private boolean checkTrimEmpty(String str) {
    +
    private boolean checkTrimEmpty(String str) {
         for(int i = 0; i < str.length(); i++) {
    -        if(!Character.isWhitespace(str.charAt(i))) {
    +        if(!Character.isWhitespace(str.charAt(i))) {
                 return false;
             }
         }
    @@ -1769,7 +1781,7 @@ include the check for != null).

    Example(s):

    -
    public void bar(String string) {
    +
    public void bar(String string) {
         if (string != null && string.trim().length() > 0) {
             doSomething();
         }
    @@ -1794,11 +1806,11 @@ need to be be created and destroyed by the JVM.

    Example(s):

    // Avoid this, two buffers are actually being created here
    -StringBuffer sb = new StringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));
    +StringBuffer sb = new StringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));
     
     // do this instead
    -StringBuffer sb = new StringBuffer("tmp = ");
    -sb.append(System.getProperty("java.io.tmpdir"));
    +StringBuffer sb = new StringBuffer("tmp = ");
    +sb.append(System.getProperty("java.io.tmpdir"));
     

    Use this rule by referencing it:

    @@ -1821,10 +1833,10 @@ is assumed if the length of the constructor can not be determined.

    Example(s):

    -
    StringBuffer bad = new StringBuffer();
    +
    StringBuffer bad = new StringBuffer();
     bad.append("This is a long string that will exceed the default 16 characters");
     
    -StringBuffer good = new StringBuffer(41);
    +StringBuffer good = new StringBuffer(41);
     good.append("This is a long string, which is pre-sized");
     
    @@ -1851,7 +1863,7 @@ Note that new Integer() is deprecated since JDK 9 for that reason.

    Example(s):

    public class Foo {
    -    private Integer i = new Integer(0); // change to Integer i = Integer.valueOf(0);
    +    private Integer i = new Integer(0); // change to Integer i = Integer.valueOf(0);
     }
     
    @@ -1878,7 +1890,7 @@ Note that new Long() is deprecated since JDK 9 for that reason.

    Example(s):

    public class Foo {
    -    private Long i = new Long(0); // change to Long i = Long.valueOf(0);
    +    private Long i = new Long(0); // change to Long i = Long.valueOf(0);
     }
     
    @@ -1918,14 +1930,14 @@ is faster, but returns only an array of type Obj

    Example(s):

    -
    List<Foo> foos = getFoos();
    +
    List<Foo> foos = getFoos();
     
     // much better; this one allows the jvm to allocate an array of the correct size and effectively skip
     // the zeroing, since each array element will be overridden anyways
    -Foo[] fooArray = foos.toArray(new Foo[0]);
    +Foo[] fooArray = foos.toArray(new Foo[0]);
     
     // inefficient, the array needs to be zeroed out by the jvm before it is handed over to the toArray method
    -Foo[] fooArray = foos.toArray(new Foo[foos.size()]);
    +Foo[] fooArray = foos.toArray(new Foo[foos.size()]);
     

    Use this rule by referencing it:

    @@ -1955,9 +1967,9 @@ is redundant and results in a larger class file (approximately three additional float f = .0f; // all possible float literals doable d = 0d; // all possible double literals - Object o = null; + Object o = null; - MyClass mca[] = null; + MyClass mca[] = null; int i1 = 0, ia1[] = null; class Nested { @@ -1989,7 +2001,7 @@ Note that new Short() is deprecated since JDK 9 for that reason.

    Example(s):

    public class Foo {
    -    private Short i = new Short(0); // change to Short i = Short.valueOf(0);
    +    private Short i = new Short(0); // change to Short i = Short.valueOf(0);
     }
     
    @@ -2023,11 +2035,11 @@ at the expense of some readability.

    public class Foo {
     
    -    boolean checkIt(String x) {
    +    boolean checkIt(String x) {
             return x.startsWith("a");   // suboptimal
         }
     
    -    boolean fasterCheckIt(String x) {
    +    boolean fasterCheckIt(String x) {
             return x.charAt(0) == 'a';  // faster approach
         }
     }
    @@ -2049,7 +2061,7 @@ at the expense of some readability.

    Example(s):

    -
    private String bar = new String("bar"); // just do a String bar = "bar";
    +
    private String bar = new String("bar"); // just do a String bar = "bar";
     

    Use this rule by referencing it:

    @@ -2068,8 +2080,8 @@ at the expense of some readability.

    Example(s):

    -
    private String baz() {
    -    String bar = "howdy";
    +
    private String baz() {
    +    String bar = "howdy";
         return bar.toString();
     }
     
    @@ -2157,17 +2169,17 @@ garbage-collected later.

    Example(s):

    -
    public int convert(String s) {
    +
    public int convert(String s) {
         int i, i2;
     
    -    i = Integer.valueOf(s).intValue();  // this wastes an object
    -    i = Integer.parseInt(s);            // this is better
    +    i = Integer.valueOf(s).intValue();  // this wastes an object
    +    i = Integer.parseInt(s);            // this is better
     
    -    i2 = Integer.valueOf(i).intValue(); // this wastes an object
    +    i2 = Integer.valueOf(i).intValue(); // this wastes an object
         i2 = i;                             // this is better
     
    -    String s3 = Integer.valueOf(i2).toString(); // this wastes an object
    -    s3 = Integer.toString(i2);                  // this is better
    +    String s3 = Integer.valueOf(i2).toString(); // this wastes an object
    +    s3 = Integer.toString(i2);                  // this is better
     
         return i2;
     }
    @@ -2193,10 +2205,10 @@ garbage-collected later.

    Example(s):

    -
    public class SimpleTest extends TestCase {
    +
    public class SimpleTest extends TestCase {
         public void testX() {
    -    Collection c1 = new Vector();
    -    Collection c2 = new ArrayList();    // achieves the same with much better performance
    +    Collection c1 = new Vector();
    +    Collection c2 = new ArrayList();    // achieves the same with much better performance
         }
     }
     
    @@ -2254,9 +2266,9 @@ You must use new ArrayList<>(Arrays.asList(…)) if that is inconvenient f

    Example(s):

    public class Test {
    -    public void foo(Integer[] ints) {
    +    public void foo(Integer[] ints) {
             // could just use Arrays.asList(ints)
    -        List<Integer> l= new ArrayList<>(100);
    +        List<Integer> l= new ArrayList<>(100);
             for (int i=0; i< 100; i++) {
                 l.add(ints[i]);
             }
    @@ -2283,7 +2295,7 @@ You must use new ArrayList<>(Arrays.asList(…)) if that is inconvenient f
     
     

    Example(s):

    -
    String s = "hello world";
    +
    String s = "hello world";
     // avoid this
     if (s.indexOf("d") {}
     // instead do this
    @@ -2306,9 +2318,9 @@ You must use new ArrayList<>(Arrays.asList(…)) if that is inconvenient f
     
     

    Example(s):

    -
    public String convert(int i) {
    -    String s;
    -    s = "a" + String.valueOf(i);    // not required
    +
    public String convert(int i) {
    +    String s;
    +    s = "a" + String.valueOf(i);    // not required
         s = "a" + i;                    // preferred approach
         return s;
     }
    @@ -2334,7 +2346,7 @@ threadsafe StringBuffer is recommended to avoid this.

    public class Foo {
         void bar() {
    -        String a;
    +        String a;
             a = "foo";
             a += " bar";
             // better would be:
    @@ -2361,7 +2373,7 @@ or StringBuffer.toString().length() == …

    Example(s):

    -
    StringBuffer sb = new StringBuffer();
    +
    StringBuffer sb = new StringBuffer();
     
     if (sb.toString().equals("")) {}        // inefficient
     
    @@ -2388,7 +2400,7 @@ or StringBuffer.toString().length() == …

    diff --git a/pmd_rules_java_security.html b/pmd_rules_java_security.html index 30441a2653..a38e4419c0 100644 --- a/pmd_rules_java_security.html +++ b/pmd_rules_java_security.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1371,11 +1383,11 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    public class Foo {
         void good() {
    -        SecretKeySpec secretKeySpec = new SecretKeySpec(Properties.getKey(), "AES");
    +        SecretKeySpec secretKeySpec = new SecretKeySpec(Properties.getKey(), "AES");
         }
     
         void bad() {
    -        SecretKeySpec secretKeySpec = new SecretKeySpec("my secret here".getBytes(), "AES");
    +        SecretKeySpec secretKeySpec = new SecretKeySpec("my secret here".getBytes(), "AES");
         }
     }
     
    @@ -1398,7 +1410,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    public class Foo {
         void good() {
    -        SecureRandom random = new SecureRandom();
    +        SecureRandom random = new SecureRandom();
             byte iv[] = new byte[16];
             random.nextBytes(bytes);
         }
    @@ -1433,7 +1445,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
                 
    diff --git a/pmd_rules_jsp.html b/pmd_rules_jsp.html index 497383a699..74df08f29d 100644 --- a/pmd_rules_jsp.html +++ b/pmd_rules_jsp.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1444,7 +1456,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_jsp_bestpractices.html b/pmd_rules_jsp_bestpractices.html index d94b56eeb0..8b21a784cb 100644 --- a/pmd_rules_jsp_bestpractices.html +++ b/pmd_rules_jsp_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1371,16 +1383,16 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

    Example(s):

    -
    <html>
    -  <body>
    -    <ul>
    -      <c:forEach items='${books}' var='b'>
    -        <li> <h:outputText value='#{b}' /> </li>
    -      </c:forEach>
    -    </ul>
    -  </body>
    -</html>
    -
    +
    <html>
    +  <body>
    +    <ul>
    +      <c:forEach items='${books}' var='b'>
    +        <li> <h:outputText value='#{b}' /> </li>
    +      </c:forEach>
    +    </ul>
    +  </body>
    +</html>
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/bestpractices.xml/DontNestJsfInJstlIteration" />
    @@ -1400,10 +1412,10 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
     
     

    Example(s):

    -
    <HTML> <BODY>
    -<P class="MajorHeading">Some text</P>
    -</BODY> </HTML>
    -
    +
    <HTML> <BODY>
    +<P class="MajorHeading">Some text</P>
    +</BODY> </HTML>
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/bestpractices.xml/NoClassAttribute" />
    @@ -1425,14 +1437,14 @@ little other purpose. Consider switching to JSP comments.

    Example(s):

    -
    <HTML><title>bad example><BODY>
    -<!-- HTML comment -->
    -</BODY> </HTML>
    +
    <HTML><title>bad example><BODY>
    +<!-- HTML comment -->
    +</BODY> </HTML>
     
    -<HTML><title>good example><BODY>
    -<%-- JSP comment --%>
    -</BODY> </HTML>
    -
    +<HTML><title>good example><BODY> +<%-- JSP comment --%> +</BODY> </HTML> +

    Use this rule by referencing it:

    <rule ref="category/jsp/bestpractices.xml/NoHtmlComments" />
    @@ -1452,8 +1464,8 @@ little other purpose. Consider switching to JSP comments.

    Example(s):

    -
    <jsp:forward page='UnderConstruction.jsp'/>
    -
    +
    <jsp:forward page='UnderConstruction.jsp'/>
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/bestpractices.xml/NoJspForward" />
    @@ -1475,7 +1487,7 @@ little other purpose. Consider switching to JSP comments.

    diff --git a/pmd_rules_jsp_codestyle.html b/pmd_rules_jsp_codestyle.html index 08607a0ede..bc4d31dfcc 100644 --- a/pmd_rules_jsp_codestyle.html +++ b/pmd_rules_jsp_codestyle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1369,8 +1381,8 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

    Example(s):

    -
    <%@ page import=\"com.foo.MyClass,com.foo.MyClass\"%><html><body><b><img src=\"<%=Some.get()%>/foo\">xx</img>text</b></body></html>
    -
    +
    <%@ page import=\"com.foo.MyClass,com.foo.MyClass\"%><html><body><b><img src=\"<%=Some.get()%>/foo\">xx</img>text</b></body></html>
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/codestyle.xml/DuplicateJspImports" />
    @@ -1392,7 +1404,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
                 
    diff --git a/pmd_rules_jsp_design.html b/pmd_rules_jsp_design.html index b37eca5394..da52b44063 100644 --- a/pmd_rules_jsp_design.html +++ b/pmd_rules_jsp_design.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1387,8 +1399,8 @@ tags, or attributes like "align=’center’".

    Example(s):

    -
    <html><body><p align='center'><b>text</b></p></body></html>
    -
    +
    <html><body><p align='center'><b>text</b></p></body></html>
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/design.xml/NoInlineStyleInformation" />
    @@ -1408,11 +1420,11 @@ tags, or attributes like "align=’center’".

    Example(s):

    -
    <HTML>
    -<BODY>
    -<!--Java Script-->
    -<SCRIPT language="JavaScript" type="text/javascript">
    -<!--
    +
    <HTML>
    +<BODY>
    +<!--Java Script-->
    +<SCRIPT language="JavaScript" type="text/javascript">
    +<!--
     function calcDays(){
       var date1 = document.getElementById('d1').lastChild.data;
       var date2 = document.getElementById('d2').lastChild.data;
    @@ -1425,11 +1437,11 @@ function calcDays(){
     }
     
     onload=calcDays;
    -//-->
    -</SCRIPT>
    -</BODY>
    -</HTML>
    -
    +//--> +</SCRIPT> +</BODY> +</HTML> +

    Use this rule by referencing it:

    <rule ref="category/jsp/design.xml/NoLongScripts" />
    @@ -1451,17 +1463,17 @@ onload=calcDays;
     
     

    Example(s):

    -
    <HTML>
    -<HEAD>
    -<%
    -response.setHeader("Pragma", "No-cache");
    -%>
    -</HEAD>
    -    <BODY>
    -        <jsp:scriptlet>String title = "Hello world!";</jsp:scriptlet>
    -    </BODY>
    -</HTML>
    -
    +
    <HTML>
    +<HEAD>
    +<%
    +response.setHeader("Pragma", "No-cache");
    +%>
    +</HEAD>
    +    <BODY>
    +        <jsp:scriptlet>String title = "Hello world!";</jsp:scriptlet>
    +    </BODY>
    +</HTML>
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/design.xml/NoScriptlets" />
    @@ -1483,7 +1495,7 @@ response.setHeader("Pragma", "No-cache");
                 
    diff --git a/pmd_rules_jsp_errorprone.html b/pmd_rules_jsp_errorprone.html index 54051ad49f..afa76ac270 100644 --- a/pmd_rules_jsp_errorprone.html +++ b/pmd_rules_jsp_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1377,12 +1389,12 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

    Example(s):

    -
    Most browsers should be able to interpret the following headers:
    +
    Most browsers should be able to interpret the following headers:
     
    -<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    +<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
     
    -<meta http-equiv="Content-Type"  content="text/html; charset=UTF-8" />
    -
    +<meta http-equiv="Content-Type"  content="text/html; charset=UTF-8" /> +

    Use this rule by referencing it:

    <rule ref="category/jsp/errorprone.xml/JspEncoding" />
    @@ -1404,7 +1416,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
                 
    diff --git a/pmd_rules_jsp_security.html b/pmd_rules_jsp_security.html index 5b48525c54..8ab69d7973 100644 --- a/pmd_rules_jsp_security.html +++ b/pmd_rules_jsp_security.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1372,14 +1384,14 @@ through SSL. See http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q261188

    Example(s):

    -
    <HTML><title>bad example><BODY>
    -<iframe></iframe>
    -</BODY> </HTML>
    +
    <HTML><title>bad example><BODY>
    +<iframe></iframe>
    +</BODY> </HTML>
     
    -<HTML><title>good example><BODY>
    -<iframe src="foo"></iframe>
    -</BODY> </HTML>
    -
    +<HTML><title>good example><BODY> +<iframe src="foo"></iframe> +</BODY> </HTML> +

    Use this rule by referencing it:

    <rule ref="category/jsp/security.xml/IframeMissingSrcAttribute" />
    @@ -1398,12 +1410,12 @@ would be interpreted by the browser directly (e.g. "<script>alert(‘hello
     
     

    Example(s):

    -
    <%@ page contentType="text/html; charset=UTF-8" %>
    -<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    -${expression}                    <!-- don't use this -->
    -${fn:escapeXml(expression)}      <!-- instead, escape it -->
    -<c:out value="${expression}" />  <!-- or use c:out -->
    -
    +
    <%@ page contentType="text/html; charset=UTF-8" %>
    +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    +${expression}                    <!-- don't use this -->
    +${fn:escapeXml(expression)}      <!-- instead, escape it -->
    +<c:out value="${expression}" />  <!-- or use c:out -->
    +

    Use this rule by referencing it:

    <rule ref="category/jsp/security.xml/NoUnsanitizedJSPExpression" />
    @@ -1425,7 +1437,7 @@ ${fn:escapeXml(expression)}      <!-- instead, escape it -->
                 
    diff --git a/pmd_rules_modelica.html b/pmd_rules_modelica.html index 5213b95dba..ce3511f043 100644 --- a/pmd_rules_modelica.html +++ b/pmd_rules_modelica.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1393,7 +1405,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_modelica_bestpractices.html b/pmd_rules_modelica_bestpractices.html index 59a57c9d03..29af54ac6b 100644 --- a/pmd_rules_modelica_bestpractices.html +++ b/pmd_rules_modelica_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1467,7 +1479,7 @@ end Example;
    diff --git a/pmd_rules_plsql.html b/pmd_rules_plsql.html index 9a88ad04e0..6e14364dcc 100644 --- a/pmd_rules_plsql.html +++ b/pmd_rules_plsql.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1473,7 +1485,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_plsql_bestpractices.html b/pmd_rules_plsql_bestpractices.html index e07b7d79ad..ff9f4f893a 100644 --- a/pmd_rules_plsql_bestpractices.html +++ b/pmd_rules_plsql_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1433,7 +1445,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_plsql_codestyle.html b/pmd_rules_plsql_codestyle.html index 0af1664ffe..c2d3adba03 100644 --- a/pmd_rules_plsql_codestyle.html +++ b/pmd_rules_plsql_codestyle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1685,7 +1697,7 @@ https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/static.htm#BABIIHBJ

    / create or replace package body inline_pragma_error is - procedure do_transaction(p_input_token in varchar(200)) is + procedure do_transaction(p_input_token in varchar(200)) is PRAGMA AUTONOMOUS_TRANSACTION; /* this is correct place for PRAGMA */ begin PRAGMA AUTONOMOUS_TRANSACTION; /* this is the wrong place for PRAGMA -> violation */ @@ -1717,7 +1729,7 @@ https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/static.htm#BABIIHBJ

    diff --git a/pmd_rules_plsql_design.html b/pmd_rules_plsql_design.html index e524c1a3b5..cb9343af71 100644 --- a/pmd_rules_plsql_design.html +++ b/pmd_rules_plsql_design.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1852,7 +1864,7 @@ same datatype. These situations usually denote the need for new objects to wrap CREATE OR REPLACE PROCEDURE addPerson( -- preferred approach - birthdate DATE, measurements BodyMeasurements , ssn INTEGER) BEGIN + birthdate DATE, measurements BodyMeasurements , ssn INTEGER) BEGIN . . . . END; @@ -1996,7 +2008,7 @@ lines of code that are split are counted as one.

    Example(s):

    CREATE OR REPLACE PACKAGE BODY AS
    - FUNCTION methd RETURN INTEGER IS
    + FUNCTION methd RETURN INTEGER IS
      BEGIN
        RETURN 1;;
      END;
    @@ -2225,10 +2237,10 @@ city/state/zip fields could park them within a single Address field.

    Example(s):

    CREATE OR REPLACE PACKAGE pkg_too_many_fields AS
    -    C_CHAR_A CONSTANT CHAR(1 CHAR) := 'A';
    -    C_CHAR_B CONSTANT CHAR(1 CHAR) := 'B';
    +    C_CHAR_A CONSTANT CHAR(1 CHAR) := 'A';
    +    C_CHAR_B CONSTANT CHAR(1 CHAR) := 'B';
         ...
    -    C_CHAR_Z CONSTANT CHAR(1 CHAR) := 'Z';
    +    C_CHAR_Z CONSTANT CHAR(1 CHAR) := 'Z';
     END pkg_too_many_fields;
     
    @@ -2357,7 +2369,7 @@ have more fine grained objects.

    diff --git a/pmd_rules_plsql_errorprone.html b/pmd_rules_plsql_errorprone.html index 14b93a1abb..d18318d9f7 100644 --- a/pmd_rules_plsql_errorprone.html +++ b/pmd_rules_plsql_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1377,7 +1389,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 IS -- Take single parameter, relying on current default NLS date format -FUNCTION strip_time (p_date IN DATE) RETURN DATE +FUNCTION strip_time (p_date IN DATE) RETURN DATE IS BEGIN RETURN TO_DATE(TO_CHAR(p_date)); @@ -1411,21 +1423,21 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 IS -- Take single parameter, relying on current default NLS date format -FUNCTION to_date_single_parameter (p_date_string IN VARCHAR2) RETURN DATE +FUNCTION to_date_single_parameter (p_date_string IN VARCHAR2) RETURN DATE IS BEGIN RETURN TO_DATE(p_date_string); END to_date_single_parameter ; -- Take 2 parameters, using an explicit date format string -FUNCTION to_date_two_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2) RETURN DATE +FUNCTION to_date_two_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2) RETURN DATE IS BEGIN TO_DATE(p_date_string, p_date_format); END to_date_two_parameters; -- Take 3 parameters, using an explicit date format string and an explicit language -FUNCTION to_date_three_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2, p_nls_language VARCHAR2 ) RETURN DATE +FUNCTION to_date_three_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2, p_nls_language VARCHAR2 ) RETURN DATE IS BEGIN TO_DATE(p_date_string, p_format_mask, p_nls_language); @@ -1458,21 +1470,21 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 IS -- Take single parameter, relying on current default NLS date format -FUNCTION to_timestamp_single_parameter (p_date_string IN VARCHAR2) RETURN DATE +FUNCTION to_timestamp_single_parameter (p_date_string IN VARCHAR2) RETURN DATE IS BEGIN RETURN TO_TIMESTAMP(p_date_string); END to_timestamp_single_parameter; -- Take 2 parameters, using an explicit date format string -FUNCTION to_timestamp_two_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2) RETURN DATE +FUNCTION to_timestamp_two_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2) RETURN DATE IS BEGIN TO_TIMESTAMP(p_date_string, p_date_format); END to_timestamp_two_parameters; -- Take 3 parameters, using an explicit date format string and an explicit language -FUNCTION to_timestamp_three_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2, p_nls_language VARCHAR2 ) RETURN DATE +FUNCTION to_timestamp_three_parameters (p_date_string IN VARCHAR2, p_format_mask IN VARCHAR2, p_nls_language VARCHAR2 ) RETURN DATE IS BEGIN TO_TIMESTAMP(p_date_string, p_format_mask, p_nls_language); @@ -1502,7 +1514,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_pom.html b/pmd_rules_pom.html index 8ee1b08e94..e682bc6a9c 100644 --- a/pmd_rules_pom.html +++ b/pmd_rules_pom.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1406,7 +1418,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_pom_errorprone.html b/pmd_rules_pom_errorprone.html index 38b33fb8f1..a454636089 100644 --- a/pmd_rules_pom_errorprone.html +++ b/pmd_rules_pom_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1473,7 +1485,7 @@ By far the most common problem is the use of ${project.version} in a BOM or pare
    diff --git a/pmd_rules_scala.html b/pmd_rules_scala.html index 1619f8e0af..c1fc2a6246 100644 --- a/pmd_rules_scala.html +++ b/pmd_rules_scala.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1386,7 +1398,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_vf.html b/pmd_rules_vf.html index b81919e47d..4ec156deb6 100644 --- a/pmd_rules_vf.html +++ b/pmd_rules_vf.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1406,7 +1418,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_vf_security.html b/pmd_rules_vf_security.html index f6e01191fd..c022e06040 100644 --- a/pmd_rules_vf_security.html +++ b/pmd_rules_vf_security.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1411,7 +1423,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_vm.html b/pmd_rules_vm.html index d2d538f823..af2916e5bc 100644 --- a/pmd_rules_vm.html +++ b/pmd_rules_vm.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1427,7 +1439,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_vm_bestpractices.html b/pmd_rules_vm_bestpractices.html index 81b7dbe556..3983778c86 100644 --- a/pmd_rules_vm_bestpractices.html +++ b/pmd_rules_vm_bestpractices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1401,7 +1413,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_vm_design.html b/pmd_rules_vm_design.html index 49dcb038ee..b3c96bfbd1 100644 --- a/pmd_rules_vm_design.html +++ b/pmd_rules_vm_design.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1515,7 +1527,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_vm_errorprone.html b/pmd_rules_vm_errorprone.html index 066ee6a168..3673ad7d9f 100644 --- a/pmd_rules_vm_errorprone.html +++ b/pmd_rules_vm_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1401,7 +1413,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_xml.html b/pmd_rules_xml.html index d0cd78180c..bad1e94347 100644 --- a/pmd_rules_xml.html +++ b/pmd_rules_xml.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1405,7 +1417,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_xml_errorprone.html b/pmd_rules_xml_errorprone.html index 291b8338c7..f65517d034 100644 --- a/pmd_rules_xml_errorprone.html +++ b/pmd_rules_xml_errorprone.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1405,7 +1417,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_xsl.html b/pmd_rules_xsl.html index d557ac7b38..98d37bf711 100644 --- a/pmd_rules_xsl.html +++ b/pmd_rules_xsl.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1413,7 +1425,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_xsl_codestyle.html b/pmd_rules_xsl_codestyle.html index 6b00327ab4..9bc8a16ea0 100644 --- a/pmd_rules_xsl_codestyle.html +++ b/pmd_rules_xsl_codestyle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1396,7 +1408,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/pmd_rules_xsl_performance.html b/pmd_rules_xsl_performance.html index 469e32b689..fc6dfc204e 100644 --- a/pmd_rules_xsl_performance.html +++ b/pmd_rules_xsl_performance.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1439,7 +1451,7 @@ cutting through 100% of the document.

    diff --git a/pmd_userdocs_best_practices.html b/pmd_userdocs_best_practices.html index b0ec5b3fb3..5de499c0a1 100644 --- a/pmd_userdocs_best_practices.html +++ b/pmd_userdocs_best_practices.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1408,7 +1420,7 @@ and soon you’ll be fixing problems much faster.

    diff --git a/pmd_userdocs_cli_reference.html b/pmd_userdocs_cli_reference.html index 021b91694a..983ed0b981 100644 --- a/pmd_userdocs_cli_reference.html +++ b/pmd_userdocs_cli_reference.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -2127,7 +2139,7 @@ which can be specified with the -property
    diff --git a/pmd_userdocs_configuring_rules.html b/pmd_userdocs_configuring_rules.html index c638b13ba6..238f156520 100644 --- a/pmd_userdocs_configuring_rules.html +++ b/pmd_userdocs_configuring_rules.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1434,7 +1446,7 @@ will cause the rule to be ignored.

    diff --git a/pmd_userdocs_cpd.html b/pmd_userdocs_cpd.html index 5d2ac98efe..33a8832b1a 100644 --- a/pmd_userdocs_cpd.html +++ b/pmd_userdocs_cpd.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -2304,7 +2316,7 @@ the CPD task as usual and right after it invoke the Ant XSLT script like this:Arbitrary blocks of code can be ignored through comments on Java, C/C++, Dart, Go, Javascript, Kotlin, Lua, Matlab, Objective-C, PL/SQL, Python and Swift by including the keywords CPD-OFF and CPD-ON.

    -
        public Object someParameterizedFactoryMethod(int x) throws Exception {
    +
        public Object someParameterizedFactoryMethod(int x) throws Exception {
             // some unignored code
     
             // tell cpd to start ignoring code - CPD-OFF
    @@ -2332,11 +2344,11 @@ It’s legacy and the new comment’s based approach should be favored.

        //enable suppression
         @SuppressWarnings("CPD-START")
    -    public Object someParameterizedFactoryMethod(int x) throws Exception {
    +    public Object someParameterizedFactoryMethod(int x) throws Exception {
             // any code here will be ignored for the duplication detection
         }
         //disable suppression
    -    @SuppressWarnings("CPD-END)
    +    @SuppressWarnings("CPD-END)
         public void nextMethod() {
         }
     
    @@ -2387,7 +2399,7 @@ the comment based approach will be extended to those of them that can support it
    diff --git a/pmd_userdocs_extending_defining_properties.html b/pmd_userdocs_extending_defining_properties.html index c97ac878af..8fc3c855a6 100644 --- a/pmd_userdocs_extending_defining_properties.html +++ b/pmd_userdocs_extending_defining_properties.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1357,11 +1369,16 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 -

    Defining properties

    +

    Rule properties are a way to make your rules configurable directly from the +ruleset XML. Their usage is described on the Configuring Rules page.

    -

    If you’re a rule developer, you may want to think about what would be useful for a user of your rule to parameterise. It could be a numeric report level, a boolean flag changing the behaviour of your rule… PMD ships with many types of properties ready to use!

    +

    If you’re a rule developer, you may want to think about what would be useful for +a user of your rule to parameterise. It could be a numeric report level, a boolean +flag changing the behaviour of your rule… Chances are there is some detail +that can be abstracted away from your implementation, and in that case, this +page can help you squeeze that sweet flexibility out of your rule.

    -

    Overview of properties

    +

    Overview of properties

    The basic thing you need to do as a developer is to define a property descriptor and declare that your rule uses it. A property descriptor defines a number of attributes for your property:

      @@ -1372,151 +1389,84 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

      Don’t worry, all of these attributes can be specified in a single Java statement (or xml element for XPath rules).

      -

      Without further ado, here is the list of available (single-value) properties:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Class nameValue type
      IntegerPropertyint
      DoublePropertydouble
      FloatPropertyfloat
      LongPropertylong
      EnumeratedProperty<E>E
      StringPropertyString
      BooleanPropertyboolean
      CharacterPropertychar
      FilePropertyjava.io.File
      MethodPropertyjava.lang.reflect.Method
      TypePropertyjava.lang.Class<?>
      RegexPropertyjava.util.regex.Pattern
      - -

      Each of these is complemented by a multivalued variant, whose name ends with “MultiProperty”, and which returns a list of values, e.g.

      - - - - - - - - - - - - - - - - - - -
      Class nameValue type
      LongMultiPropertyList<Long>
      EnumeratedMultiProperty<E>List<E>
      - -

      Note that RegexProperty doesn’t have a multivalued variant, since the delimiters could be part of a specific value.

      - -

      For Java rules

      +

      For Java rules

      The procedure to define a property is quite straightforward:

      -

      You can then retrieve the value of the property at any time using getProperty(PropertyDescriptor).

      +

      You can then retrieve the value of the property at any time using getProperty(PropertyDescriptor).

      -

      Creating a descriptor

      +

      Creating a descriptor

      -

      From version 6.0.0 on, properties can be built using specific builders. For example, to build a string property, you’d call

      -
      StringProperty.named("myProperty")
      -              .desc("This is my property")
      -              .defaultValue("foo")
      -              .build();
      +

      Properties can be built using type-specific builders, which can be obtained +from the factory methods of PropertyFactory. For example, to build a +string property, you’d call

      +
      PropertyFactory.stringProperty("myProperty")
      +               .desc("This is my property")
      +               .defaultValue("foo")
      +               .build();
       

      This is fairly more readable than a constructor call, but keep in mind the description and the default value are not optional.

      - + -

      For numeric properties, you’d add a call to range to define the range of acceptable values, e.g.

      -
      IntegerProperty.named("myIntProperty")
      +

      For numeric properties, you can add constraints on the range of acceptable values, e.g.

      +
      PropertyFactory.intProperty("myIntProperty")
                      .desc("This is my property")
                      .defaultValue(3)
      +               .require(positive())
                      .range(0, 100)
                      .build();
       
      -

      Enumerated properties are a bit less straightforward to define, though they are arguably more powerful. These properties don’t have a specific value type, instead, you can choose any type of value, provided the values are from a closed set. To make that actionable, you give string labels to each of the acceptable values, and the user will provide one of those labels as a value in the XML. The property will give you back the associated value, not the label. Here’s an example:

      -
      static Map<String, ModeStrategy> map = new HashMap<>();
      +

      The positive method is part of +the NumericConstraints class, which provides some +other constraints. The constraint mechanism will be completely unlocked with 7.0.0, +since we’ll be migrating our API to Java 8.

      + +

      Enumerated properties are a bit less straightforward to define, though they are +arguably more powerful. These properties don’t have a specific value type, instead, +you can choose any type of value, provided the values are from a closed set. To make +that actionable, you give string labels to each of the acceptable values, and the user +will provide one of those labels as a value in the XML. The property will give you back +the associated value, not the label. Here’s an example:

      +
      static Map<String, ModeStrategy> map = new HashMap<>();
       
       static {
      -  map.put("easyMode", new EasyStrategy());
      -  map.put("hardMode", new HardStrategy());
      +  map.put("easyMode", new EasyStrategy());
      +  map.put("hardMode", new HardStrategy());
       }
       
      -static EnumeratedProperty<ModeStrategy> modeProperty
      - = EnumeratedProperty.<ModeStrategy>named("modeProperty")
      -                     .desc("This is my property")
      -                     .defaultValue(new EasyStrategy())
      -                     .mappings(map)
      -                     .type(ModeStrategy.class)
      -                     .build();
      +static PropertyDescriptor<ModeStrategy> modeProperty
      + = PropertyFactory.enumProperty("modeProperty", map)
      +                  .desc("This is my property")
      +                  .defaultValue(new EasyStrategy())
      +                  .build();
       
      -

      Note that you’re required to fill in the type of the values too, using type().

      +

      Example

      -

      Example

      - -

      You can see an example of properties used in a PMD rule here. +

      You can see an example of properties used in a PMD rule here. There are several things to notice here:

        -
      • The property descriptor is declared static final, which should generally be the case, as descriptors are immutable and can be shared between instances of the same rule;
      • -
      • The property is declared using definePropertyDescriptor in the constructor, which ensures the property gets recognised by PMD;
      • -
      • The value of the property is not retrieved in the constructor, but in one of the visit methods (typically on the highest node in the tree, since the property doesn’t change).
      • +
      • The property descriptors are declared static final, which should generally be +the case, as descriptors are immutable and can be shared between instances of the same rule;
      • +
      • The property is declared using definePropertyDescriptor` in the constructor, +which ensures the property gets recognised by PMD at the time the properties +are overridden (which happens before rule execution);
      • +
      • The value of the property is not retrieved in the constructor, but in one of +the visit methods (typically on the highest node in the tree, since the property +doesn’t change).
      -

      For XPath rules

      +

      For XPath rules

      XPath rules can also define their own properties. To do so, you must add a property element in the properties element of your rule, which declares the type attribute. This attribute conditions what type the underlying property has, and can have the following values:

      @@ -1524,52 +1474,51 @@ There are several things to notice here:

      type attribute - Property type + XSD type Integer - IntegerProperty - - - Double - DoubleProperty - - - Float - FloatProperty + xs:integer Long - LongProperty + xs:integer - String - StringProperty - - - Character - CharacterProperty + Double + xs:decimal Boolean - BooleanProperty + xs:boolean - Class - TypeProperty + String + xs:string + + + Character + xs:string Regex - RegexProperty + xs:string + +

      Note that enumerated properties are not available in XPath rules (yet?).

      -

      Properties defined in XPath also must declare the description attribute. Numeric properties also expect the min and max attributes. Here are a few examples to sum it up:

      +

      Properties defined in XPath also must declare the description attribute. +Numeric properties also expect the min and max attributes for now. Here are +a few examples to sum it up:

      <property name="stringProp" type="Boolean" value="true" description="A BooleanProperty."/>
       <property name="intProp" type="Integer" value="3" min="1" max="20" description="An IntegerProperty."/>
      @@ -1589,9 +1538,14 @@ There are several things to notice here:

      </rule>
      -

      Multivalued properties

      +

      Multivalued properties

      -

      Multivalued properties are also allowed and their type attribute has the form List[Boolean] or List[Character], with every above type allowed. These properties require XPath 2.0 to work properly, and make use of the sequence datatype provided by that language. You thus need to set the version property to 2.0 to use them. Properties can also declare the delimiter attribute.

      +

      Multivalued properties are also allowed and their type attribute has the form +List[Boolean] or List[Character], with every above type allowed. These +properties require XPath 2.0 to work properly, and make use of the +sequence datatype provided by that language. You thus need to set the +version property to 2.0 to use them. Properties can also declare the +delimiter attribute.

      <rule name="MyXpathRule" ...>
         <properties>
      @@ -1607,8 +1561,13 @@ There are several things to notice here:

      </rule>
      -

      Notice that in the example above, @Image = $reportedIdentifiers doesn’t test @Image for equality with the whole sequence ('foo', 'bar'), it tests whether the sequence contains @Image. That is, the above rule will report all variables named foo or bar. All other XPath 2.0 functions operating on sequences are supported.

      +

      Notice that in the example above, @Image = $reportedIdentifiers doesn’t test +@Image for equality with the whole sequence ('foo', 'bar'), it tests whether +the sequence contains @Image. That is, the above rule will report all variables +named foo or bar. All other XPath 2.0 functions operating on sequences +are supported.

      +
      @@ -1637,7 +1596,7 @@ There are several things to notice here:

      diff --git a/pmd_userdocs_extending_designer_reference.html b/pmd_userdocs_extending_designer_reference.html index 07c19bec3d..9c391dcb2a 100644 --- a/pmd_userdocs_extending_designer_reference.html +++ b/pmd_userdocs_extending_designer_reference.html @@ -340,13 +340,25 @@ -
    • Writing a rule
    • +
    • Introduction to writing rules
    • -
    • Writing XPath rules
    • +
    • Your first rule
    • + + + + + +
    • XPath rules
    • + + + + + +
    • Java rules
    • @@ -1623,7 +1635,7 @@ The available language modules are those on the classpath of the app’s JVM. Th
      diff --git a/pmd_userdocs_extending_metrics_howto.html b/pmd_userdocs_extending_metrics_howto.html index 096f85fd83..a011c9fab6 100644 --- a/pmd_userdocs_extending_metrics_howto.html +++ b/pmd_userdocs_extending_metrics_howto.html @@ -340,13 +340,25 @@ -
    • Writing a rule
    • +
    • Introduction to writing rules
    • -
    • Writing XPath rules
    • +
    • Your first rule
    • + + + + + +
    • XPath rules
    • + + + + + +
    • Java rules
    • @@ -1367,8 +1379,8 @@ a numeric result. In the Java framework, metrics can be computed on operation de method declaration), and type declaration nodes (class, interface, enum, and annotation declarations). A metric object in the framework can only handle either types or operations, but not both.

      -

      PMD ships with a library of already implemented metrics. These metrics are referenced by MetricKey objects, -which are listed in two public enums: JavaClassMetricKey and JavaOperationMetricKey. +

      PMD ships with a library of already implemented metrics. These metrics are referenced by MetricKey objects, +which are listed in two public enums: JavaClassMetricKey and JavaOperationMetricKey. Metric keys wrap a metric, and know which type of node their metric can be computed on. That way, you cannot compute an operation metric on a class declaration node. Metrics that can be computed on both operation and type declarations (e.g. NCSS) have one metric key in each enum.

      @@ -1381,9 +1393,9 @@ which is the name of the metric key as defined in ASTAnyTypeDeclaration or MethodLikeNode, that is, -it’s not one of ASTClassOrInterfaceDeclaration, ASTEnumDeclaration, ASTMethodDeclaration, -ASTConstructorDeclaration, or ASTLambdaExpression. +
    • The context node is neither an instance of ASTAnyTypeDeclaration or MethodLikeNode, that is, +it’s not one of ASTClassOrInterfaceDeclaration, ASTEnumDeclaration, ASTMethodDeclaration, +ASTConstructorDeclaration, or ASTLambdaExpression.
    • The metric key does not exist (the name is case insensitive) or is not defined for the type of the context node.
    @@ -1401,7 +1413,7 @@ CYCLO’s only defined for methods and constructors.

    For Java Rules

    -

    The static façade class JavaMetrics is the single entry point to compute metrics in the Java framework.

    +

    The static façade class JavaMetrics is the single entry point to compute metrics in the Java framework.

    This class provides the method get and its overloads. The following sections describes the interface of this class.

    @@ -1410,8 +1422,8 @@ CYCLO’s only defined for methods and constructors.

    The simplest overloads of JavaMetrics.get take two parameters: a MetricKey and a node of the corresponding type. Say you want to write a rule to report methods that have a high cyclomatic complexity. In your rule’s visitor, you can get the value of Cyclo for a method node like so:

    -
    public Object visit(ASTMethodDeclaration method, Object data) {
    -  int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method);
    +
    public Object visit(ASTMethodDeclaration method, Object data) {
    +  int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method);
       if (cyclo > 10) {
         // add violation
       }
    @@ -1429,13 +1441,13 @@ to JavaMetrics.get.

    Capability checking

    Metrics are not necessarily computable on any node of the type they handle. For example, Cyclo cannot be computed on -abstract methods. Metric keys provides a supports(Node) boolean method +abstract methods. Metric keys provides a supports(Node) boolean method to find out if the metric can be computed on the specified node. If the metric cannot be computed on the given node, JavaMetrics.get will return Double.NaN . If you’re concerned about that, you can condition your call on whether the node is supported or not:

    -
    public Object visit(ASTMethodDeclaration method, Object data) {
    -  if (JavaOperationMetricKey.CYCLO.supports(node)) {
    -    int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method);
    +
    public Object visit(ASTMethodDeclaration method, Object data) {
    +  if (JavaOperationMetricKey.CYCLO.supports(node)) {
    +    int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method);
         if (cyclo > 10) {
           // add violation
         }
    @@ -1450,12 +1462,12 @@ If you’re concerned about that, you can condition your call on whether the nod
     gathered inside an enum in the implementation class of the metric, for example CycloMetric.CycloOption. They’re
     also documented on the index of metrics.

    -

    To use options with a metric, you must first bundle them into a MetricOptions object. MetricOptions provides the +

    To use options with a metric, you must first bundle them into a MetricOptions object. MetricOptions provides the utility method ofOptions to get a MetricOptions bundle from a collection or with varargs parameters. You can then pass this bundle as a parameter to JavaMetrics.get:

    -
    public Object visit(ASTMethodDeclaration method, Object data) {
    -  int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method,
    -                                    MetricOptions.ofOptions(CycloOptions.IGNORE_BOOLEAN_PATHS));
    +
    public Object visit(ASTMethodDeclaration method, Object data) {
    +  int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method,
    +                                    MetricOptions.ofOptions(CycloOptions.IGNORE_BOOLEAN_PATHS));
       if (cyclo > 10) {
           // add violation
       }
    @@ -1472,9 +1484,9 @@ for an example usage.

    The Metrics API also gives you the possibility to aggregate the result of an operation metric on all operations of a class very simply. You can for example get the highest value of the metric over a class that way:

    -
    public Object visit(ASTClassOrInterfaceDeclaration clazz, Object data) {
    -  int highest = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, clazz,
    -                                      ResultOption.HIGHEST);
    +
    public Object visit(ASTClassOrInterfaceDeclaration clazz, Object data) {
    +  int highest = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, clazz,
    +                                      ResultOption.HIGHEST);
       if (highest > 10) {
           // add violation
       }
    @@ -1495,30 +1507,30 @@ user-configured with a rule property. More complete examples can be found in
     NcssCountRule,
     or GodClassRule.

    -
    public class CycloRule extends AbstractJavaMetricsRule {
    +
    public class CycloRule extends AbstractJavaMetricsRule {
     
    -  public static final BooleanProperty COUNT_BOOLEAN_PATHS
    -      = BooleanProperty.named("countBooleanPaths")
    +  public static final BooleanProperty COUNT_BOOLEAN_PATHS
    +      = BooleanProperty.named("countBooleanPaths")
                            .desc("Count boolean paths")
                            .defaultValue(true).build();
     
    -  private static final MetricOptions options;
    +  private static final MetricOptions options;
     
       public CycloRule() {
    -    definePropertyDescriptor(COUNT_BOOLEAN_PATHS);
    +    definePropertyDescriptor(COUNT_BOOLEAN_PATHS);
       }
     
       @Override
    -  public Object visit(ASTCompilationUnit node, Object data) {
    -    options = getProperty(COUNT_BOOLEAN_PATHS)
    -              ? MetricOptions.ofOptions(CycloOptions.IGNORE_BOOLEAN_PATHS)
    -              : MetricOptions.emptyOptions();
    +  public Object visit(ASTCompilationUnit node, Object data) {
    +    options = getProperty(COUNT_BOOLEAN_PATHS)
    +              ? MetricOptions.ofOptions(CycloOptions.IGNORE_BOOLEAN_PATHS)
    +              : MetricOptions.emptyOptions();
       }
     
       @Override
    -  public Object visit(ASTAnyTypeDeclaration clazz, Object data) {
    -    int total = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, clazz,
    -                                      options, ResultOption.SUM);
    +  public Object visit(ASTAnyTypeDeclaration clazz, Object data) {
    +    int total = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, clazz,
    +                                      options, ResultOption.SUM);
     
         if (total > 50) {
          // add violation
    @@ -1528,8 +1540,8 @@ or }
     
       @Override
    -  public Object visit(ASTMethodDeclaration method, Object data) {
    -    int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method,
    +  public Object visit(ASTMethodDeclaration method, Object data) {
    +    int cyclo = (int) JavaMetrics.get(JavaOperationMetricKey.CYCLO, method,
                                           options);
         if (cyclo > 10) { // this is safe if the node is not supported, as (Double.NaN > 10) == false
           // add violation
    @@ -1643,8 +1655,8 @@ define a predicate to check that the node is supported by your metric. For examp
     if your metric can only be computed on classes, you may override the default behaviour
     like so:

    @Override
    -public boolean supports(ASTAnyTypeDeclaration node) {
    -  return node.getTypeKind() == TypeKind.CLASS;
    +public boolean supports(ASTAnyTypeDeclaration node) {
    +  return node.getTypeKind() == TypeKind.CLASS;
     }
     
    @@ -1709,7 +1721,7 @@ classes. Here’s the default behaviour by language and type of metric:

    diff --git a/pmd_userdocs_extending_rule_guidelines.html b/pmd_userdocs_extending_rule_guidelines.html index 43ca525122..37c678f088 100644 --- a/pmd_userdocs_extending_rule_guidelines.html +++ b/pmd_userdocs_extending_rule_guidelines.html @@ -4,7 +4,7 @@ - + Rule guidelines | PMD Source Code Analyzer @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1327,7 +1339,7 @@
    -
    Rule Guidelines
    +
    Rule Guidelines, or the last touches to a rule
    @@ -1356,11 +1368,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 -

    Rule Guidelines

    - -

    Or - Last touches to a rules

    - -

    Here is a bunch of thing to do you may consider once your rule is “up and running”.

    +

    Here is a bunch of thing to do you may consider once your rule is “up and running”.

    How to define rules priority

    @@ -1376,15 +1384,6 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3

    For instance, let’s take the ExplicitCallToGC rule (“Do not explicitly trigger a garbage collection.”). Calling GC is a bad idea, but it doesn’t break the application. So we skip priority one. However, as explicit call to gc may really hinder application performances, we set for the priority 2.

    -

    Code formatting

    - -

    We try to keep a consistent code formatting through out PMD code base to ensure an easier maintenance and also make -the pull request as readable as possible.

    - -

    In order to ensure this, we use a PMD specific Eclipse formatter configuration, which is maintained in a -separate project - “build-tools”: eclipse-code-formatter.xml. -Please do not forget to use it before committing or any source code!

    -

    Correctness

    You should try to run the rule on a large code base, like the jdk source code for instance. This will help ensure that the rule does not raise exceptions when dealing with unusual constructs.

    @@ -1399,31 +1398,6 @@ Please do not forget to use it before committing or any source code!

    (TODO How does one know except by running in a debugger or horrendous performance?).

    -

    Adding test cases

    - -

    See Testing your rules for the general documentation

    - -

    … for a rule I want to submit (in a patch)

    - -

    Figure out the category to which you want to the rule. Then add your rule to the appropriate test class for -the category and add the XML test data in the correct xml subpackage.

    - -

    … for something too specific, that I won’t be able to submit

    - -

    See Using the test framework externally

    - -

    Code quality

    - -

    If you want to contribute a java rule to PMD, you should run PMD on it (Using the dogfood rulesets), to ensure that you rule follow the rules defined by the PMD community.

    - -

    Also note, that if this is not a strong policy, most developers uses the berkeley braces syntax.

    - -

    Committing

    - -

    Before committing changes, make sure the verify phase of a maven build succeeds without test failures. Drink a beer while you wait for it to finish.

    - -

    Then read the output to make sure no fatal errors are present.

    -
    @@ -1451,7 +1425,7 @@ the category and add the XML test data in the correct xml subpackage.

    diff --git a/pmd_userdocs_extending_testing.html b/pmd_userdocs_extending_testing.html index 3bb4896272..1976bd1488 100644 --- a/pmd_userdocs_extending_testing.html +++ b/pmd_userdocs_extending_testing.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1431,7 +1443,7 @@ belongs to the category “Best Practices”:

    import net.sourceforge.pmd.testframework.PmdRuleTst; -public class AbstractClassWithoutAbstractMethodTest extends PmdRuleTst { +public class AbstractClassWithoutAbstractMethodTest extends PmdRuleTst { // no additional unit tests }
    @@ -1607,7 +1619,7 @@ the rule test manually, as SimpleAggregatorTst will fail to determine it correct import net.sourceforge.pmd.testframework.SimpleAggregatorTst; -public class CustomRuleTest extends SimpleAggregatorTst { +public class CustomRuleTest extends SimpleAggregatorTst { @Override public void setUp() { addRule("com/example/pmd/ruleset.xml", "CustomRule"); @@ -1680,7 +1692,7 @@ will be executed twice.

    diff --git a/pmd_userdocs_extending_writing_java_rules.html b/pmd_userdocs_extending_writing_java_rules.html new file mode 100644 index 0000000000..d01bceb21a --- /dev/null +++ b/pmd_userdocs_extending_writing_java_rules.html @@ -0,0 +1,1571 @@ + + + + + + + + +Writing a custom rule | PMD Source Code Analyzer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    +
     
    + +
    + + + +
    + + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Writing a custom rule

    +
    + + + +
    + + +
    Learn how to write a custom rule for PMD
    + + + + + + + +
    + + + + + + + + + + Edit me + + + + + + + + +

    This page covers the specifics of writing a rule in Java. The basic development +process is very similar to the process for XPath rules, which is described in +Your First Rule.

    + +

    Basically, you open the designer, look at the structure of the AST, and refine +your rule as you add test cases.

    + +

    In this page we’ll talk about rules for the Java language, but the process is +very similar for other languages.

    + +

    Basics

    + +

    To write a rule in Java you’ll have to:

    +
      +
    1. write a Java class that implements the interface Rule. Each +language implementation provides a base rule class to ease your pain, +e.g. AbstractJavaRule.
    2. +
    3. compile this class, linking it to PMD APIs (eg using PMD as a maven dependency)
    4. +
    5. bundle this into a JAR and add it to the execution classpath of PMD
    6. +
    7. declare the rule in your ruleset XML
    8. +
    + +

    Rule execution

    + +

    Most base rule classes use a Visitor pattern +to explore the AST.

    + +

    Tree traversal

    + +

    When a rule is applied to a file, it’s handed the root of the AST and told +to traverse all the tree to look for violations. Each rule defines a specific +visit method for each type of node for of the language, which +by default just visits the children.

    + +

    So the following rule would traverse the whole tree and do nothing:

    + +
    public class MyRule extends AbstractJavaRule {
    +    // all methods are default implementations!
    +}
    +
    + +

    Generally, a rule wants to check for only some node types. In our XPath example +in Your First Rule, +we wanted to check for some VariableDeclaratorId nodes. That’s the XPath name, +but in Java, you’ll get access to the ASTVariableDeclaratorId +full API.

    + +

    If you want to check for some specific node types, you can override the +corresponding visit method:

    + +
    public class MyRule extends AbstractJavaRule {
    +
    +    @Override
    +    public Object visit(ASTVariableDeclaratorId node, Object data) {
    +        // This method is called on each node of type ASTVariableDeclaratorId
    +        // in the AST
    +
    +        if (node.getType() == short.class) {
    +            // reports a violation at the position of the node
    +            // the "data" parameter is a context object handed to by your rule
    +            // the message for the violation is the message defined in the rule declaration XML element
    +            addViolation(data, node);
    +        }
    +
    +        // this calls back to the default implementation, which recurses further down the subtree
    +        return super.visit(node, data);
    +    }
    +}
    +
    + +

    The super.visit(node, data) call is super common in rule implementations, +because it makes the traversal continue by visiting all the descendants of the +current node.

    + +

    Stopping the traversal

    + +

    Sometimes you have checked all you needed and you’re sure that the descendants +of a node may not contain violations. In that case, you can avoid calling the +super implementation and the traversal will not continue further down. This +means that your callbacks (visit implementations) won’t be called on the rest +of the subtree. The siblings of the current node may be visited +recursively nevertheless.

    + +

    Economic traversal: the rulechain

    + +

    If you don’t care about the order in which the nodes are traversed (e.g. your +rule doesn’t maintain any state between visits), then you can monumentally +speed-up your rule by using the rulechain.

    + +

    That mechanism doesn’t recurse on all the tree, instead, your rule will only be +passed the nodes it is interested in. To use the rulechain correctly:

    +
      +
    • Your rule must register those node types by calling addRuleChainVisit +in its constructor.
    • +
    • Your visit methods must not recurse! In effect, you should call never +call super.visit in the methods.
    • +
    + +

    Execution across files, thread-safety and statefulness

    + +

    When starting execution, PMD will instantiate a new instance of your rule. +If PMD is executed in multiple threads, then each thread is using its own +instance of the rule. This means, that the rule implementation does not need to care about +threading issues, as PMD makes sure, that a single instance is not used concurrently +by multiple threads.

    + +

    However, for performance reasons, the rule instances are used for multiple files. +This means, that the constructor of the rule is only executed once (per thread) +and the rule instance is reused. If you rely on a proper initialization of instance +properties, you can do the initialization e.g. in the visit-method of the ASTCompilationUnit +node - which is visited first and only once per file. However, this +solution would only work for rules written for the Java language. A language +independent way is to override the method start of the rule. +The start method is called exactly once per file.

    + + + +

    Rule lifecycle reference

    + +

    Construction

    + +

    Exactly once:

    + +
      +
    1. The rule’s no-arg constructor is called when loading the ruleset. +The rule’s constructor must define: + +
    2. +
    3. If the rule was included in the ruleset as a rule reference, +some properties may be overridden. +If an overridden property is unknown, an error is reported.
    4. +
    5. Misconfigured rules are removed from the ruleset
    6. +
    + +

    Execution

    + +

    For each thread, a deep copy of the rule is created. Each thread is given +a different set of files to analyse. Then, for each such file, for each +rule copy:

    + +
      +
    1. start is called once, before parsing
    2. +
    3. apply is called with the root +of the AST. That method performs the AST traversal that ultimately calls visit methods. +It’s not called for RuleChain rules.
    4. +
    5. end is called when the rule is done processing +the file
    6. +
    + + +
    + + Tags: + + + + extending + + + + userdocs + + + +
    + + + +
    + +
    + +
    +
    + +
    +
    + + +
    + +
    + +
    +
    + + + diff --git a/pmd_userdocs_extending_writing_pmd_rules.html b/pmd_userdocs_extending_writing_pmd_rules.html index 7701198bc6..5ae0b8c372 100644 --- a/pmd_userdocs_extending_writing_pmd_rules.html +++ b/pmd_userdocs_extending_writing_pmd_rules.html @@ -4,7 +4,7 @@ - + Writing a custom rule | PMD Source Code Analyzer @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1327,8 +1339,6 @@
    -
    Learn how to write a custom rule for PMD
    - @@ -1356,321 +1366,30 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 -

    How to write a PMD rule

    - -

    Writing PMD rules is cool because you don’t have to wait for us to get around to implementing feature requests.

    - -

    Get a development environment set up first

    -
    [Here’s some initial information on compiling PMD]
    -
    - -

    Java or XPath?

    - -

    There are two way to write rules:

    +

    The information on this page has been split into several separate pages. Please update your bookmarks:

    -

    We’ll cover the Java way first and the XPath way second. Most of this documentation is applicable to both methods, too, so read on.

    - -

    Figure out what you want to look for

    - -

    Lets’s figure out what problem we want to spot. We can use “While loops must use braces” as an example. In the source code below, it’s easy to get lost visually - it’s kind of hard to tell what the curly braces belong to.

    - -
    class Example {
    -	void bar() {
    -		while (baz)
    -		buz.doSomething();
    -	}
    -}
    -
    - -

    So we know what an example in source code looks like, which is half the battle.

    - -

    Write a test-data example and look at the AST

    - -

    PMD doesn’t use the source code directly; it uses a JavaCC generated parser to parse the source code and produce an AST (Abstract Syntax Tree). The AST for the code above looks like this:

    - -
    CompilationUnit
    - TypeDeclaration
    -  ClassDeclaration:(package private)
    -   UnmodifiedClassDeclaration(Example)
    -    ClassBody
    -     ClassBodyDeclaration
    -      MethodDeclaration:(package private)
    -       ResultType
    -       MethodDeclarator(bar)
    -        FormalParameters
    -       Block
    -        BlockStatement
    -         Statement
    -          WhileStatement
    -           Expression
    -            PrimaryExpression
    -             PrimaryPrefix
    -              Name:baz
    -           Statement
    -            StatementExpression:null
    -             PrimaryExpression
    -              PrimaryPrefix
    -               Name:buz.doSomething
    -              PrimarySuffix
    -               Arguments
    -
    - -

    You can generate this yourself by:

    - +

    To go further:

      -
    • Run the batch file bin/designer.bat
    • -
    • Paste the code into the left text area and click the “Go” button
    • -
    • Note that there’s another panel and a textfield to test out XPath expressions; more on that later.
    • -
    • Here’s a screenshot:
      Designer Screenshot
    • +
    • Defining Properties +describes how to make your rules more configurable with rule properties
    • +
    • Testing your Rules introduces +our testing framework and how you can use it to safeguard the quality of +your rule
    -

    So you can see in the example above that the AST for a WhileStatement looks kind of like this (excluding that expression gibberish for clarity):

    - -
    WhileStatement
    - Expression
    - Statement
    -  StatementExpression
    -
    - -

    If you were to add curly braces around the call to buz.doSomething() and click “Go” again, you’d see that the AST would change a bit. It’d look like this:

    - -
    WhileStatement
    - Expression
    - Statement
    -  Block
    -   BlockStatement
    -    Statement
    -     StatementExpression
    -
    - -

    Ah ha! We see that the curly braces add a couple more AST nodes - a Block and a BlockStatement. So all we have to do is write a rule to detect a WhileStatement that has a Statement that’s not followed by a Block, and we’ve got a rule violation.

    - -

    By the way, all this structural information - i.e., the fact that a Statement may be followed a Block - is concisely defined in the EBNF grammar. So, for example, the Statement definition looks like this:

    - -
    void Statement() :
    -{}
    -{
    -  LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement()
    -| LOOKAHEAD(2) LabeledStatement()
    -| Block()
    -| EmptyStatement()
    -| StatementExpression() ";"
    -| SwitchStatement()
    -| IfStatement()
    -| WhileStatement()
    -| DoStatement()
    -| ForStatement()
    -| BreakStatement()
    -| ContinueStatement()
    -| ReturnStatement()
    -| ThrowStatement()
    -| SynchronizedStatement()
    -| TryStatement()
    -}
    -
    - -

    showing that a Statement may be followed by all sorts of stuff.

    - -

    Write a rule class

    - -

    Create a new Java class that extends net.sourceforge.pmd.lang.java.rule.AbstractJavaRule:

    - -
    import net.sourceforge.pmd.lang.java.rule.*;
    -public class WhileLoopsMustUseBracesRule extends AbstractJavaRule {
    -}
    -
    - -

    That was easy. PMD works by creating the AST and then traverses it recursively so a rule can get a callback for any type it’s interested in. So let’s make sure our rule gets called whenever the AST traversal finds a WhileStatement:

    - -
    import net.sourceforge.pmd.lang.java.rule.*;
    -import net.sourceforge.pmd.lang.java.ast.*;
    -public class WhileLoopsMustUseBracesRule extends AbstractJavaRule {
    -    public Object visit(ASTWhileStatement node, Object data) {
    -        System.out.println("hello world");
    -        return data;
    -    }
    -}
    -
    - -

    We stuck a println() in there for now so we can see when our rule gets hit.

    - -

    Put the WhileLoopsMustUseBracesRule rule in a ruleset file

    - -

    Now our rule is written - at least, the shell of it is - and now we need to tell PMD about it. We need to add it to a ruleset XML file. Look at pmd-java/src/main/resources/category/java/bestpractices.xml; it’s got lots of rule definitions in it. Copy and paste one of these rules into a new ruleset - call it mycustomrules.xml or something. Then fill in the elements and attributes:

    - -
      -
    • name - WhileLoopsMustUseBracesRule
    • -
    • message - Use braces for while loops
    • -
    • class - Wherever you put the rule. Note this doesn’t have to be in net.sourceforge.pmd; it can be in com.yourcompany.util.pmd or whereever you want
    • -
    • description - Use braces for while loops
    • -
    • example - A little code snippet in CDATA tags that shows a rule violation
    • -
    - -

    The whole ruleset file should look something like this:

    - -
    <?xml version="1.0"?>
    -<ruleset name="My custom rules"
    -		xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
    -		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    -		xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
    -	<rule name="WhileLoopsMustUseBracesRule"
    -			message="Avoid using 'while' statements without curly braces"
    -			class="WhileLoopsMustUseBracesRule">
    -		<description>
    -			Avoid using 'while' statements without using curly braces
    -		</description>
    -		<priority>3</priority>
    -
    -		<example>
    -			<![CDATA[
    -				public void doSomething() {
    -					while (true)
    -					x++;
    -				}
    -			]]>
    -		</example>
    -	</rule>
    -</ruleset>
    -
    - -

    Run PMD using your new ruleset

    - -

    OK, let’s run the new rule so we can see something work. Like this:

    - -
    pmd.bat c:\path\to\my\src xml c:\path\to\mycustomrules.xml
    -
    - -

    This time your “hello world” will show up right after the AST gets printed out. If it doesn’t, post a message to the forum so we can improve this document :-)

    - -

    Write code to add rule violations where appropriate

    - -

    Now that we’ve identified our problem, recognized the AST pattern that illustrates the problem, written a new rule, and plugged it into a ruleset, we need to actually make our rule find the problem, create a RuleViolation, and put it in the Report, which is attached to the RuleContext. Like this:

    - -
    import net.sourceforge.pmd.lang.ast.*;
    -import net.sourceforge.pmd.lang.java.ast.*;
    -import net.sourceforge.pmd.lang.java.rule.*;
    -
    -public class WhileLoopsMustUseBracesRule extends AbstractJavaRule {
    -    public Object visit(ASTWhileStatement node, Object data) {
    -        Node firstStmt = node.jjtGetChild(1);
    -        if (!hasBlockAsFirstChild(firstStmt)) {
    -            addViolation(data, node);
    -        }
    -        return super.visit(node,data);
    -    }
    -    private boolean hasBlockAsFirstChild(Node node) {
    -        return (node.getNumChildren() != 0 && (node.jjtGetChild(0) instanceof ASTBlock));
    -    }
    -}
    -
    - -

    TODO - if you don’t understand the code for the rule, post a message to the forum so we can improve this document :-)

    - -

    Writing a rule as an XPath expression

    - -

    Daniel Sheppard integrated an XPath engine into PMD, so now you can write rules as XPath expressions. For example, the XPath expression for our WhileLoopsMustUseBracesRule looks like this:

    - -

    //WhileStatement[not(Statement/Block)]

    - -

    Concise, eh?

    - -

    Note that for XPath rules you’ll need to set the class attribute in the rule definition to net.sourceforge.pmd.lang.rule.XPathRule. Like this:

    - -
    <rule name="EmptyCatchBlock"
    -      message="Avoid empty catch blocks"
    -      class="net.sourceforge.pmd.lang.rule.XPathRule">
    -  <description>
    -  etc., etc.
    -
    - -

    Note that access modifiers are held as attributes, so, for example,

    - -

    //FieldDeclaration[@Private='true']

    - -

    finds all private fields. You can see the code that determines all the attributes here

    - -

    More information about writing XPath rules is available here.

    - -

    I need some kind of Type Resolution for my rule!

    - -

    Inside an XPath query

    - -

    PMD’s XPath extensions include two functions called typeIs and typeIsExactly, -which determine if a node is of a specific type (either any subtype or exactly, -respectively).

    - -

    Here a an example of use, inside an XPath query:

    - -
    //ClassOrInterfaceDeclaration/ExtendsList/ClassOrInterfaceType[typeIs('junit.framework.TestCase')]
    -
    - -

    This query will for instance match the following class declaration:

    - -
    import junit.framework.TestCase;
    -
    -public class Foo extends TestCase { }
    -
    - -

    It will also match against classes which extend a subtype of junit.framework.TestCase, -i.e. a base class itself extending TestCase transitively. If you don’t want this behaviour, -then use typeIsExactly instead of typeIs.

    - -

    Checking against an array type is possible with the double bracket syntax. -An array type is denoted by just appending [] to the fully qualified class name -of the component type. These can be repeated for arrays of arrays -(e.g. byte[][] or java.lang.String[]).

    - -

    With Java code

    - -

    Below an other sample of use of type resolution inside a java code:

    - -
    /**
    - * A simple to detect the use of the class 'com.forbidden.class'.
    - */
    -@SuppressWarnings("unchecked")
    -public Object visit(ASTClassOrInterfaceType type, Object ruleCtx) {
    -    Class clazz = type.getType();
    -    if ("com.forbidden.class".equals(clazz.getName())) {
    -        addViolation(ruleCtx,type);
    -    }
    -    return super.visit(type, ruleCtx);
    -}
    -
    - -
    -

    Note, that this will only work, if the auxiliary classpath for PMD is setup correctly, so that PMD can actually find the (compiled) class “com.forbidden.class” and you get the actual Class instance by calling getType().

    -
    - -

    Otherwise, you’ll have to string-compare the image, e.g. "com.forbidden.class".equals(node.getImage())

    - -

    Thread safety, concurrency issues and reuse of rule instances

    - -

    When executing the rule, PMD will instantiate a new instance of your rule. If PMD is executed in multiple threads, then each thread is using its own instance of the rule. This means, that the rule implementation does not need to care about threading issues, as PMD makes sure, that a single instance is not used concurrently by multiple threads.

    - -

    However, for performance reasons, the rule instances are used for multiple files. This means, that the constructor of the rule is only executed once (per thread) and the rule instance is reused. If you rely on a proper initialization of instance properties, you can do the initialization e.g. in the visit-method of the ASTCompilationUnit AST node - which is visited as first node and only once per file. However, this solution would only work for rules written for the Java language. A language independent way is to override the method apply of the rule (and call super). The apply method is called exactly once per file.

    - -

    If you want to share data across multiple files, see the above section “I want to implement a rule that analyze more than the class”.

    - -

    Bundle it up

    - -

    To use your rules as part of a nightly build or whatever, it’s helpful to bundle up both the rule and the ruleset.xml file in a jar file. Then you can put that jar file on the CLASSPATH of your build. Setting up a script or an Ant task to do this can save you some tedious typing.

    - -

    Repeat as necessary

    - -

    I’ve found that my rules usually don’t work the first time, and so I have to go back and tweak them a couple times. That’s OK, if we were perfect programmers PMD would be useless anyhow :-).

    - -

    As an acceptance test of sorts, I usually run a rule on the JDK 1.4 source code and make sure that a random sampling of the problems found are in fact legitimate rule violations. This also ensures that the rule doesn’t get confused by nested inner classes or any of the other oddities that appear at various points in the JDK source.

    - -

    You’re rolling now. If you think a rule would benefit the (Java) development community as a whole, -create a issue on github so we can get the rule moved into one of the core rulesets.

    - -

    Or, if you can improve one of the existing rules, that’d be great too! Thanks!

    -
    @@ -1698,7 +1417,7 @@ create a issue on github so we c
    diff --git a/pmd_userdocs_extending_writing_rules_intro.html b/pmd_userdocs_extending_writing_rules_intro.html new file mode 100644 index 0000000000..6eaa69783a --- /dev/null +++ b/pmd_userdocs_extending_writing_rules_intro.html @@ -0,0 +1,1547 @@ + + + + + + + + +Introduction to writing PMD rules | PMD Source Code Analyzer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    +
     
    + +
    + + + +
    + + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Introduction to writing PMD rules

    +
    + + + +
    + + +
    Writing your own PMD rules
    + + + + + + + +
    + + + + + + + + + + Edit me + + + +

    PMD is a framework to perform code analysis. You can create your own rules to +check for patterns specific to your codebase, or the coding practices of your +team.

    + +

    How rules work: the AST

    + +

    Before running rules, PMD parses the source file into a data structure called an +abstract syntax tree (AST). This tree represents the syntactic structure of the +code, and encodes syntactic relations between source code elements. For instance, +in Java, method declarations belong to a class: in the AST, the nodes representing +method declarations will be descendants of a node representing the declaration of +their enclosing class. This representation is thus much richer than the original +source code (which, for a program, is just a chain of characters), or the token +chain produced by a lexer (which is e.g. what Checkstyle works on). For example:

    + + ++++ + + + + + + + + + + + + +
    Sample code (Java)AST
    + +
    class Foo extends Object {
    +
    +}
    +
    + +
    + +
    └─ CompilationUnit
    +   └─ TypeDeclaration
    +      └─ ClassOrInterfaceDeclaration "Foo"
    +         ├─ ExtendsList
    +           └─ ClassOrInterfaceType "Object"
    +         └─ ClassOrInterfaceBody
    +
    + +
    + +

    Conceptually, PMD rules work by matching a “pattern” against the AST of a +file. +Rules explore the AST and find nodes that satisfy some conditions that are characteristic +of the specific thing the rule is trying to flag. Rules then report a violation on these nodes.

    + +

    Discovering the AST

    + +

    ASTs are represented by Java classes deriving from Node. +Each PMD language has its own set of such classes, and its own rules about how +these classes relate to one another, based on the grammar of the language. For +example, all Java AST nodes extend JavaNode.

    + +

    The structure of the AST can be discovered through

    + + +

    Writing new rules

    + +

    PMD supports two ways to define rules: using an XPath query, or using a +Java visitor. XPath rules are much easier to set up, since they’re defined +directly in your ruleset XML, and are expressive enough for nearly any task.

    + +

    On the other hand, some parts of PMD’s API are only accessible from Java, e.g. +accessing the usages of a declaration. And Java rules allow you to do some +complicated processing, to which an XPath rule couldn’t scale.

    + +

    In the end, choosing one strategy or the other depends on the difficulty of what +your rule does. I’d advise to keep to XPath unless you have no other choice.

    + +

    XML rule definition

    + +

    New rules must be declared in a ruleset before they’re referenced. This is the +case for both XPath and Java rules. To do this, the rule element is used, but +instead of mentioning the ref attribute, it mentions the class attribute, +with the implementation class of your rule.

    + +
      +
    • For Java rules: this is the class extending AbstractRule (transitively)
    • +
    • For XPath rules: this is net.sourceforge.pmd.lang.rule.XPathRule
    • +
    + +

    Example:

    + +
    <rule name="MyJavaRule"
    +      language="java"
    +      message="Violation!"
    +      class="com.me.MyJavaRule" >
    +    <description>
    +        Description
    +    </description>
    +    <priority>3</priority>
    +</rule>
    +
    + +

    Resource index

    + +

    To learn how to write a rule:

    + + + +

    To go further:

    +
      +
    • Defining Properties +describes how to make your rules more configurable with rule properties
    • +
    • Testing your Rules introduces +our testing framework and how you can use it to safeguard the quality of +your rule
    • +
    + + + +
    + + Tags: + + + + extending + + + + userdocs + + + + getting_started + + + +
    + + + +
    + +
    + +
    +
    + +
    +
    + + +
    + +
    + +
    +
    + + + diff --git a/pmd_userdocs_extending_writing_xpath_rules.html b/pmd_userdocs_extending_writing_xpath_rules.html index e65c2c61a7..fe814ab73b 100644 --- a/pmd_userdocs_extending_writing_xpath_rules.html +++ b/pmd_userdocs_extending_writing_xpath_rules.html @@ -4,7 +4,7 @@ - + Writing XPath rules | PMD Source Code Analyzer @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1327,7 +1339,7 @@
    -
    Writing XPath rules for PMD
    +
    This page describes XPath rule support in more details
    @@ -1356,189 +1368,402 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 -

    XPath Rule tutorial

    + +

    This page describes some points of XPath rule support in more details. See +also the tutorial about how to write an XPath rule.

    - + -

    Writing PMD rules with XPath can be a bit easier than writing rules with Java code. Here’s an introduction on how to do that.

    +

    XPath version

    -

    Introduction

    +

    PMD supports three XPath versions for now: 1.0, 2.0, and 1.0 compatibility mode. +The version can be specified with the version property in the rule definition, like so:

    -

    PMD provides a very handy method for writing rules by writing an XPath query. When the XPath query finds a match, a violation is added to the report. This document focuses on XPath rules. You can go here for more information about writing a rule.

    - -

    What is the Abstract Syntax Tree (AST)?

    - -

    From FOLDOC an AST is

    - -
    -

    A data structure representing something which has been parsed, often used as a compiler or interpreter’s internal representation of a program while it is being optimised and from which code generation is performed.

    -
    - -

    In our context, this means that we basically have a tree representation of the Java source file. This tree can viewed as a structured document - just like XML. And since it’s conceptually similar to XML, it can be queried with XPath to find a pattern.

    - -

    Using Designer

    - -

    PMD comes with a handy tool that you will love if you want to write an XPath rule. Designer, runnable from a script in bin/, is a very simple and useful utility for writing rules.

    - -

    The basic steps involved in writing XPath rules are these:

    - -
      -
    1. Write a simple Java example source snippet in Designer
    2. -
    3. See the AST for the class you wrote
    4. -
    5. Write an XPath expression that matches the violation you are searching
    6. -
    7. Modify the Java class and go back to previous step to refine the XPath expression
    8. -
    - -

    See Designer Reference for a more detailed explanation on how to use the designer.

    - -

    Simple XPath expressions

    - -

    This section provides hands-on examples of XPath queries over the AST. You will probably find this section more useful if you follow it with Designer and copy/paste the examples.

    - -

    Copy the following Java source code to Designer:

    - -
    public class a {
    -    int fOne;
    -    int fTwo;
    -
    -    private void run() {
    -        int one;
    -        int two;
    -    }
    -}
    +
    <property version="2.0" /> <!-- or "1.0", or "1.0 compatibility" -->
     
    -

    Let’s assume you want to match something on class variable names. You see in the ASTVviewer that VariableDeclaratorId contains the variable name - in XML terms, the name is in the @Image attribute. So you try an XPath expression as follows:

    +

    The default has always been version 1.0.

    -

    //VariableDeclaratorId

    +

    As of PMD version 6.22.0, XPath versions 1.0 and the 1.0 compatibility mode are +deprecated. XPath 2.0 is superior in many ways, for example for its support for +type checking, sequence values, or quantified expressions. For a detailed +but approachable review of the features of XPath 2.0 and above, see the Saxon documentation.

    -

    If you try this expression you’ll see that variables declared in methods are also matched. A more precise expression for matching field declarations is, well, using the FieldDeclaration node. This expression matches only the two fields declared in the class:

    +

    It is recommended that you migrate to 2.0 before 7.0.0, but we expect +to be able to provide an automatic migration tool when releasing 7.0.0. +See the migration guide below.

    -

    //FieldDeclaration

    +

    DOM representation of ASTs

    -

    In a similar way, you can match only local variables with this expression

    +

    XPath rules view the AST as an XML-like DOM, which is what the XPath language is +defined on. Concretely, this means:

    +
      +
    • Every AST node is viewed as an XML element +
        +
      • The element has for local name the value of getXPathNodeName +for the given node
      • +
      +
    • +
    • Some Java getters are exposed as XML attributes on those elements +
        +
      • This means, that documentation for attributes can be found in our Javadocs. For +example, the attribute @SimpleName of the Java node EnumDeclaration is backed +by the Java getter getSimpleName.
      • +
      +
    • +
    -

    //LocalVariableDeclaration

    +

    Value conversion

    -

    With local variables we need to be more careful. Consider the following class:

    +

    To represent attributes, we must map Java values to XPath Data Model (XDM) values. The conversion +depends on the XPath version used.

    -
    public class a {
    -    private void run() {
    -        final int one;
    -        int two;
    +

    XPath 1.0

    - { - int a; - } - } -} -
    +

    On XPath 1.0 we map every Java value to an xs:string value by using the toString +of the object. Since XPath 1.0 allows many implicit conversions this works, but it +causes some incompatibilities with XPath 2.0 (see the section about migration further + down).

    -

    Local variable declarations will match ‘a’, since it is a perfectly legal Java local variable. Now, a more interesting expression is to match variables declared in a method, and not on an internal block, nor in the class. Maybe you’ll start with an expression like this:

    +

    XPath 2.0

    -

    //MethodDeclaration//LocalVariableDeclaration

    +

    XPath 2.0 is a strongly typed language, and so we use more precise type annotations. +In the following table we refer to the type conversion function as conv, a +function from Java types to XDM types.

    -

    You’ll quickly see that all three local variables are matched. A possible solution for this is to request that the parent of the local variable declaration is the MethodDeclaration node:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Java type TXSD type conv(T)
    intxs:integer
    longxs:integer
    doublexs:decimal
    floatxs:decimal
    booleanxs:boolean
    Stringxs:string
    Characterxs:string
    List<E>conv(E)* (a sequence type)
    -

    //LocalVariableDeclaration[name(../../..) = 'MethodDeclaration']

    +

    The same conv function is used to translate rule property values to XDM values.

    -

    Matching variables by name

    +

    Migrating from 1.0 to 2.0

    -

    Let’s consider that we are writing rules for logger. Let’s assume we use the Java logging API and we want to find all classes that have more than one logger. The following expression returns all variable declarations whose type is ‘Logger’.

    +

    XPath 1.0 and 2.0 have some incompatibilities. The XPath 2.0 specification +describes them precisely. Those are however mostly corner cases and XPath +rules usually don’t feature any of them.

    -

    //VariableDeclarator[../Type/ReferenceType/ClassOrInterfaceType[@Image='Logger']]

    +

    The incompatibilities that are most relevant to migrating your rules are not +caused by the specification, but by the different engines we use to run +XPath 1.0 and 2.0 queries. Here’s a list of known incompatibilities:

    -

    Finding a class with more than one logger is quite easy now. This expression matches the classes we are looking for.

    +
      +
    • The namespace prefixes fn: and string: should not be mentioned explicitly. +In XPath 2.0 mode, the engine will complain about an undeclared namespace, but +the functions are in the default namespace. Removing the namespace prefixes fixes it. +
        +
      • fn:substring("Foo", 1)substring("Foo", 1)
      • +
      +
    • +
    • Conversely, calls to custom PMD functions like typeIs must be prefixed +with the namespace of the declaring module (pmd-java). +
        +
      • typeIs("Foo")pmd-java:typeIs("Foo")
      • +
      +
    • +
    • Boolean attribute values on our 1.0 engine are represented as the string values +"true" and "false". In 2.0 mode though, boolean values are truly represented +as boolean values, which in XPath may only be obtained through the functions +true() and false(). +If your XPath 1.0 rule tests an attribute like @Private="true", then it just +needs to be changed to @Private=true() when migrating. A type error will warn +you that you must update the comparison. More is explained on issue #1244. +
        +
      • "true", 'true'true()
      • +
      • "false", 'false'false()
      • +
      +
    • +
    • In XPath 1.0, comparing a number to a string coerces the string to a number. +In XPath 2.0, a type error occurs. Like for boolean values, numeric values are +represented by our 1.0 implementation as strings, meaning that @BeginLine > "1" +worked —that’s not the case in 2.0 mode. +
        +
      • @ArgumentCount > '1'@ArgumentCount > 1
      • +
      +
    • +
    -
    TypeDeclaration[count(//VariableDeclarator[../Type/ReferenceType/ClassOrInterfaceType[@Image='Logger']])>1
    -
    +

    Rule properties

    -

    But let’s refine this expression a little bit more. Consider the following class:

    +

    See Defining rule properties

    -
    public class a {
    -    Logger log = null;
    -    Logger log = null;
    -    int b;
    +

    PMD extension functions

    - void myMethod() { - Logger log = null; - int a; - } - class c { - Logger a; - Logger a; - } -} -
    +

    PMD provides some language-specific XPath functions to access semantic +information from the AST.

    -

    With this class we will only be matching one violation, when we probably would have wanted to produce two violations (one for each class). The following refined expression matches classes that contain more than one logger.

    +

    On XPath 2.0, the namespace of custom PMD function must be explicitly mentioned.

    -
    //ClassOrInterfaceBodyDeclaration[count(//VariableDeclarator[../Type/ReferenceType/ClassOrInterfaceType[@Image='Logger']])>1]
    -
    + -

    Let’s assume we have a Factory class, that could be always declared final. We’ll search an xpath expression that matches all declarations of Factory and reports a violation if it is not declared final. Consider the following class:

    +

    Java

    -
    public class a {
    -    Factory f1;
    +

    Java functions are in the namespace pmd-java.

    - void myMethod() { - Factory f2; - int a; - } -} -
    +
    + -

    The following expression does the magic we need:

    + + + + + + + -
    //VariableDeclarator
    -    [../Type/ReferenceType/ClassOrInterfaceType
    -        [@Image = 'Factory'] and ..[@Final='false']]
    -
    -

    We recommend at this point that you experiment with Designer putting the final modifier to the Factory and verifying that the results produced are those expected.

    + -

    Creating a new rule definition

    + -

    To actually use your new XPath rule, it needs to be in a ruleset. You can create a new custom ruleset which just -contains your new XPath rule. You can use the following template. Just make sure, to replace the xpath property, -the example code and give your rule a useful name and message.

    + -
    <?xml version="1.0"?>
    +            
    + + + -<ruleset name="Custom Rules" - xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - <description> -Custom rules - </description> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Function nameDescription (click for details)
    typeIsTests a node's static type + +
    +
    - <rule name="My Rule" - language="java" - message="violation message" - class="net.sourceforge.pmd.lang.rule.XPathRule"> - <description> -Rule Description - </description> - <priority>3</priority> - <properties> - <property name="xpath"> - <value><![CDATA[ ---- here comes your XPath expression -]]></value> - </property> - </properties> - <example> - <![CDATA[ -public class ExampleCode { - public void foo() { - } -} -]]> - </example> - </rule> -</ruleset> -
    +
    + + + +

    + pmd-java:typeIs(xs:string) as xs:boolean +

    + +
    + +
    +
    Returns true if the context node's static Java type is a subtype of the given type. This tests for the resolved type of the Java construct, not the type of the AST node. For example, the AST node for a literal (e.g. 5d) has type ASTLiteral, however this function will compare the type of the literal (eg here, double) against the argument.
    +
    Remarks
    +
    The context node must be a TypeNode
    + + + +
    Parameters
    + +
    +
    + +
    + javaQualifiedName + as xs:string +
    +
    The qualified name of a Java class, possibly with pairs of brackets to indicate an array type. Can also be a primitive type name.
    + +
    +
    + + + + + +
    Examples
    + +
    +
    + +
    //FormalParameter[pmd-java:typeIs("java.lang.String[]")]
    +
    Matches formal parameters of type String[] (including vararg parameters)
    + +
    //VariableDeclaratorId[pmd-java:typeIs("java.lang.List")]
    +
    Matches variable declarators of type List or any of its subtypes (including e.g. ArrayList)
    + +
    +
    + +
    +
    +
    + +
    typeIsExactlyTests a node's static type, ignoring subtypes + +
    +
    + +
    + + + +

    + pmd-java:typeIsExactly(xs:string) as xs:boolean +

    + +
    + +
    +
    Returns true if the context node's static type is exactly the given type. In particular, returns false if the context node's type is a subtype of the given type.
    +
    Remarks
    +
    The context node must be a TypeNode
    + + + +
    Parameters
    + +
    +
    + +
    + javaQualifiedName + as xs:string +
    +
    The qualified name of a Java class, possibly with pairs of brackets to indicate an array type. Can also be a primitive type name.
    + +
    +
    + + + + + +
    Examples
    + +
    +
    + +
    //VariableDeclaratorId[pmd-java:typeIsExactly("java.lang.List")]
    +
    Matches variable declarators of type List (but not e.g. ArrayList)
    + +
    +
    + +
    +
    +
    +
    +
    metricComputes and returns the value of a metric + +
    +
    + +
    + + + +

    + pmd-java:metric(xs:string) as xs:decimal? +

    + +
    + +
    +
    Returns the value of the metric as evaluated on the context node
    +
    Remarks
    +
    The context node must be a ASTAnyTypeDeclaration or a MethodLikeNode
    + + + +
    Parameters
    + +
    +
    + +
    + metricKey + as xs:string +
    +
    The name of an enum constant in JavaOperationMetricKey or JavaClassMetricKey
    + +
    +
    + + + + +
    +
    +
    +
    +
    + +
    + + @@ -1568,7 +1793,7 @@ public class ExampleCode {
    diff --git a/pmd_userdocs_extending_your_first_rule.html b/pmd_userdocs_extending_your_first_rule.html new file mode 100644 index 0000000000..703b3cf1c2 --- /dev/null +++ b/pmd_userdocs_extending_your_first_rule.html @@ -0,0 +1,1542 @@ + + + + + + + + +Your first rule XPath | PMD Source Code Analyzer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    +
     
    + +
    + + + +
    + + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Your first rule XPath

    +
    + + + +
    + + +
    Introduction to rule writing through an example.
    + + + + + + + +
    + + + + + + + + + + Edit me + + + +

    This page is a gentle introduction to rule writing, and the Rule Designer.

    + +

    Using the designer is useful both to write Java +rules and XPath rules, but it’s more specifically geared towards XPath rules. +This page uses a simple XPath rule to illustrate the common workflow. We assume +here that you already know what XPath is and how to read basic XPath queries. W3C +has a good tutorial here if +you don’t (in the context of XML only), and the Saxon documentation +features a comprehensive but approachable description of the syntax of XPath +expressions.

    + +

    The Rule Designer

    + +

    The rule designer is a tool that packs a lot of features to help you develop XPath +rules quickly and painlessly. Basically, it allows you to examine the AST of a code +snippet and evaluate an XPath expression against it.

    + +

    Like for PMD and CPD, you can launch it using run.sh designer on Linux/Unix +and designer.bat on Windows. The interface looks like the following:

    + +
    Designer overview
    + +

    The zone (2) is the main editor. When you write a code snippet in the + code area to the left, you’ll see that the tree to the right will be updated + automatically: it’s the AST of the code. + Note that the code snippet must be a syntactically valid compilation unit for the + language you’ve chosen, e.g. for Java, a compilation unit necessarily has a top-level + type declaration.

    + +

    If you select a node in the AST, its specific properties will also be displayed +in the panel (1): they’re the XPath attributes of the node. More on that later.

    + +

    The zone (3) is the XPath editor. If you enter an XPath query in that area, +it will be evaluated on the current AST and the results will be displayed in the +list to the bottom right.

    + +

    Rule development process

    + +

    The basic development process is straightforward:

    + +
      +
    1. Write a code snippet in the main editor that features the offending code you’re looking for
    2. +
    3. Examine the AST and determine what node the violation should be reported on
    4. +
    5. Write an XPath expression matching that node in the XPath editor
    6. +
    7. Refine the XPath expression iteratively using different code snippets, so that +it matches violation cases, but no other node
    8. +
    9. Export your XPath expression to an XML rule element, and place it in your ruleset
    10. +
    + +

    Each time you test your rule against a different snippet, it’s a good idea to +save it to make test cases.

    + +

    In the following sections, we walk through several examples to refine your rule.

    + +

    A simple rule

    + +

    Let’s say you want to prevent your coding team from naming variables of type +short after your boss, whose name is Bill. You try the designer on the following + offending code snippet:

    + +
    
    +public class KeepingItSerious {
    +
    +    public void method() {
    +        short bill; // LocalVariableDeclaration
    +    }
    +
    +}
    +
    +
    + +

    Examining the AST, you find out that the LocalVariableDeclaration has a VariableDeclaratorId +descendant, whose Image XPath attribute is exactly bill. You thus write your first attempt +in the XPath editor:

    +
    //VariableDeclaratorId[@Image = "bill"]
    +
    + +

    You can see the XPath result list is updated with the variable declarator. +If you try the query against the following updated snippet though, you can +see that the field declaration id is matched even though it’s not of type short.

    + +
    public class KeepingItSerious {
    +
    +    Delegator bill; // FieldDeclaration
    +
    +    public void method() {
    +        short bill; // LocalVariableDeclaration
    +    }
    +
    +}
    +
    + +

    You thus refine your XPath expression with an additional predicate, +based on your examination of the Type node of the field and local variable +declaration nodes.

    + +
    //VariableDeclaratorId[@Image = "bill" and ../../Type[@TypeImage = "short"]]
    +
    + +

    Exporting to XML

    + +

    You estimate that your rule is now production ready, and you’d like to use it in your ruleset. +The File > Export XPath to rule... allows you to do that in a few clicks: just enter some +additional metadata for your rule, and the popup will generate an XML element that you can +copy-paste into your ruleset XML. The resulting element looks like so:

    + +
    <rule name="DontCallBossShort"
    +      language="java"
    +      message="Boss wants to talk to you."
    +      class="net.sourceforge.pmd.lang.rule.XPathRule" >
    +    <description>
    +TODO
    +    </description>
    +    <priority>3</priority>
    +    <properties>
    +        <property name="xpath">
    +            <value>
    +<![CDATA[
    +//VariableDeclaratorId[../../Type[@TypeImage="short"] and @Image = "bill"]
    +]]>
    +            </value>
    +        </property>
    +    </properties>
    +</rule>
    +
    + +

    You can notice that your XPath expression ends up inside a property +of a rule of type XPathRule, which is how XPath rules are implemented.

    + + +
    + + Tags: + + + + extending + + + + userdocs + + + +
    + + + +
    + +
    + +
    +
    + +
    +
    + + +
    + +
    + +
    +
    + + + diff --git a/pmd_userdocs_incremental_analysis.html b/pmd_userdocs_incremental_analysis.html index 3507a805b6..30f20ae847 100644 --- a/pmd_userdocs_incremental_analysis.html +++ b/pmd_userdocs_incremental_analysis.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1403,7 +1415,7 @@ few runs, you can use the
    diff --git a/pmd_userdocs_installation.html b/pmd_userdocs_installation.html index 166a2195bf..e81c2f5b43 100644 --- a/pmd_userdocs_installation.html +++ b/pmd_userdocs_installation.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1541,7 +1553,7 @@ directory or a jar or zip file containing the sources.
    diff --git a/pmd_userdocs_making_rulesets.html b/pmd_userdocs_making_rulesets.html index 0fc97dafc2..411d59922f 100644 --- a/pmd_userdocs_making_rulesets.html +++ b/pmd_userdocs_making_rulesets.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1491,7 +1503,7 @@ a single rule reference.
    diff --git a/pmd_userdocs_suppressing_warnings.html b/pmd_userdocs_suppressing_warnings.html index 68ff2bd7b7..6bac5c72c0 100644 --- a/pmd_userdocs_suppressing_warnings.html +++ b/pmd_userdocs_suppressing_warnings.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1389,7 +1401,7 @@ PMD project.

    -

    If you need to modify the Rule, see How to write a rule. +

    If you need to modify the Rule, see How to write a rule. Otherwise, the other suppression methods are explained in the following sections.

    Annotations

    @@ -1408,7 +1420,7 @@ Otherwise, the other suppression methods are explained in the following sections

    When using Apex make sure to use single quotes instead of double quotes

    // This will suppress all the PMD warnings in this class
    -@SuppressWarnings('PMD')
    +@SuppressWarnings('PMD')
     

    Or you can suppress one rule with an annotation like this:

    @@ -1429,7 +1441,7 @@ Otherwise, the other suppression methods are explained in the following sections

    For Apex, the syntax for this is slightly different:

    -
    @SuppressWarnings('PMD.UnusedLocalVariable, PMD.UnusedPrivateMethod')
    +
    @SuppressWarnings('PMD.UnusedLocalVariable, PMD.UnusedPrivateMethod')
     

    PMD Java also obeys the JDK annotation @SuppressWarnings(“unused”), which will apply to all rules in the unused ruleset.

    @@ -1457,22 +1469,22 @@ Otherwise, the other suppression methods are explained in the following sections

    You can use whatever text string you want to suppress warnings, by using the -suppressmarker CLI option. For example, here’s how to use TURN_OFF_WARNINGS as the suppressor:

    -
    $ cat Foo.java
    +
    $ cat Foo.java
     public class Foo {
         void bar() {
             int x = 2; // TURN_OFF_WARNINGS
         }
     }
     
    -$ ./run.sh pmd -d Foo.java -f text -R java-unusedcode -suppressmarker TURN_OFF_WARNINGS
    -No problems found!
    -UnusedLocalVariable rule violation suppressed by //NOPMD in /home/tom/pmd/pmd/bin/Foo.java
    +$ ./run.sh pmd -d Foo.java -f text -R java-unusedcode -suppressmarker TURN_OFF_WARNINGS
    +No problems found!
    +UnusedLocalVariable rule violation suppressed by //NOPMD in /home/tom/pmd/pmd/bin/Foo.java
     

    Note that PMD expects the //NOPMD marker to be on the same line as the violation. So, for example, if you want to suppress an “empty if statement” warning, you’ll need to place it on the line containing the if keyword, e.g.:

    -
    $ cat ~/tmp/Foo.java
    +
    $ cat ~/tmp/Foo.java
     public class Foo {
         void bar() {
             int x = 42;
    @@ -1480,8 +1492,8 @@ the line containing the if keyword, e.g.:
             }
         }
     }
    -$ java net.sourceforge.pmd.PMD -d ~/tmp/Foo.java -f text -R java-basic
    -No problems found!
    +$ java net.sourceforge.pmd.PMD -d ~/tmp/Foo.java -f text -R java-basic
    +No problems found!
     

    A message placed after the NOPMD marker will get placed in the report, e.g.:

    @@ -1490,7 +1502,7 @@ the line containing the if keyword, e.g.: void bar() { try { bar(); - } catch (FileNotFoundException e) {} // NOPMD - this surely will never happen + } catch (FileNotFoundException e) {} // NOPMD - this surely will never happen } }
    @@ -1592,7 +1604,7 @@ violations you wish to suppress. XPath queries are explained in
    diff --git a/pmd_userdocs_tools.html b/pmd_userdocs_tools.html index 91fce40ffa..852acc91f8 100644 --- a/pmd_userdocs_tools.html +++ b/pmd_userdocs_tools.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1832,7 +1844,7 @@ the (blank Command Results) document, and then confirming that, “yes, I do rea
    diff --git a/pmd_userdocs_tools_ant.html b/pmd_userdocs_tools_ant.html index a849213e15..2aff901f2a 100644 --- a/pmd_userdocs_tools_ant.html +++ b/pmd_userdocs_tools_ant.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1806,7 +1818,7 @@ To prevent this from happening, increase the maximum memory usable by ant using
    diff --git a/pmd_userdocs_tools_ci.html b/pmd_userdocs_tools_ci.html index db777c672d..c0755bd9f0 100644 --- a/pmd_userdocs_tools_ci.html +++ b/pmd_userdocs_tools_ci.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1398,7 +1410,7 @@ result of the PMD maven plugin.

    diff --git a/pmd_userdocs_tools_gradle.html b/pmd_userdocs_tools_gradle.html index 209307aebb..8dfe8cb241 100644 --- a/pmd_userdocs_tools_gradle.html +++ b/pmd_userdocs_tools_gradle.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1441,7 +1453,7 @@ with the property toolVersion:

    diff --git a/pmd_userdocs_tools_java_api.html b/pmd_userdocs_tools_java_api.html index 9aefc9ed6c..dc0e744e94 100644 --- a/pmd_userdocs_tools_java_api.html +++ b/pmd_userdocs_tools_java_api.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1387,14 +1399,14 @@ as described here.

    import net.sourceforge.pmd.PMD;
     
     public class Example {
    -    public static void main(String[] args) {
    -        String[] pmdArgs = {
    +    public static void main(String[] args) {
    +        String[] pmdArgs = {
                 "-d", "/home/workspace/src/main/java/code",
                 "-R", "rulesets/java/quickstart.xml",
                 "-f", "xml",
                 "-r", "/home/workspace/pmd-report.xml"
             };
    -        PMD.main(pmdArgs);
    +        PMD.main(pmdArgs);
         }
     }
     
    @@ -1410,14 +1422,14 @@ as described here.

    public class PmdExample { - public static void main(String[] args) { - PMDConfiguration configuration = new PMDConfiguration(); + public static void main(String[] args) { + PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputPaths("/home/workspace/src/main/java/code"); configuration.setRuleSets("rulesets/java/quickstart.xml"); configuration.setReportFormat("xml"); configuration.setReportFile("/home/workspace/pmd-report.xml"); - PMD.doPMD(configuration); + PMD.doPMD(configuration); } }
    @@ -1431,8 +1443,8 @@ You can also provide your own listeners and renderers.

  • First we create a PMDConfiguration. This is currently the only way to specify a ruleset:

    -
    PMDConfiguration configuration = new PMDConfiguration();
    -configuration.setMinimumPriority(RulePriority.MEDIUM);
    +    
    PMDConfiguration configuration = new PMDConfiguration();
    +configuration.setMinimumPriority(RulePriority.MEDIUM);
     configuration.setRuleSets("rulesets/java/quickstart.xml");
     
  • @@ -1448,13 +1460,13 @@ Note: you can specify multiple class paths separated by
    RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.createFactory(configuration);
    +    
    RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.createFactory(configuration);
     
  • PMD operates on a list of DataSource. You can assemble a own list of FileDataSource, e.g.

    -
    List<DataSource> files = Arrays.asList(new FileDataSource(new File("/path/to/src/MyClass.java")));
    +    
    List<DataSource> files = Arrays.asList(new FileDataSource(new File("/path/to/src/MyClass.java")));
     
  • @@ -1462,8 +1474,8 @@ account:

    the renderer by setting a suitable Writer and calling start(). After the PMD run, you need to call end() and flush(). Then your writer should have received all output.

    -
    StringWriter rendererOutput = new StringWriter();
    -Renderer xmlRenderer = new XMLRenderer("UTF-8");
    +    
    StringWriter rendererOutput = new StringWriter();
    +Renderer xmlRenderer = new XMLRenderer("UTF-8");
     xmlRenderer.setWriter(rendererOutput);
     xmlRenderer.start();
     
    @@ -1473,7 +1485,7 @@ the renderer by setting a suitable Writer Note: when running in multi-threaded mode (which is the default), the rule context instance is cloned for each thread.

    -
    RuleContext ctx = new RuleContext();
    +    
    RuleContext ctx = new RuleContext();
     
  • @@ -1481,10 +1493,10 @@ each thread.

    use such a listener to implement your own renderer. The listener must implement the interface ThreadSafeReportListener and can be registered via ctx.getReport().addListener(...).

    -
    ctx.getReport().addListener(new ThreadSafeReportListener() {
    -    public void ruleViolationAdded(RuleViolation ruleViolation) {
    +    
    ctx.getReport().addListener(new ThreadSafeReportListener() {
    +    public void ruleViolationAdded(RuleViolation ruleViolation) {
         }
    -    public void metricAdded(Metric metric) {
    +    public void metricAdded(Metric metric) {
         }
     
  • @@ -1496,12 +1508,12 @@ any renderer. Note: The auxclasspath needs to be closed explicitly. Otherwise th remain open and file resources are leaked.

    try {
    -    PMD.processFiles(configuration, ruleSetFactory, files, ctx,
    -            Collections.singletonList(renderer));
    +    PMD.processFiles(configuration, ruleSetFactory, files, ctx,
    +            Collections.singletonList(renderer));
     } finally {
    -    ClassLoader auxiliaryClassLoader = configuration.getClassLoader();
    -    if (auxiliaryClassLoader instanceof ClasspathClassLoader) {
    -        ((ClasspathClassLoader) auxiliaryClassLoader).close();
    +    ClassLoader auxiliaryClassLoader = configuration.getClassLoader();
    +    if (auxiliaryClassLoader instanceof ClasspathClassLoader) {
    +        ((ClasspathClassLoader) auxiliaryClassLoader).close();
         }
     }
     
    @@ -1512,8 +1524,8 @@ Then you can check the rendered output.

    renderer.end();
     renderer.flush();
    -System.out.println("Rendered Report:");
    -System.out.println(rendererOutput.toString());
    +System.out.println("Rendered Report:");
    +System.out.println(rendererOutput.toString());
     
    @@ -1551,79 +1563,79 @@ Then you can check the rendered output.

    public class PmdExample2 { - public static void main(String[] args) throws IOException { - PMDConfiguration configuration = new PMDConfiguration(); - configuration.setMinimumPriority(RulePriority.MEDIUM); + public static void main(String[] args) throws IOException { + PMDConfiguration configuration = new PMDConfiguration(); + configuration.setMinimumPriority(RulePriority.MEDIUM); configuration.setRuleSets("rulesets/java/quickstart.xml"); configuration.prependClasspath("/home/workspace/target/classes"); - RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.createFactory(configuration); + RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.createFactory(configuration); - List<DataSource> files = determineFiles("/home/workspace/src/main/java/code"); + List<DataSource> files = determineFiles("/home/workspace/src/main/java/code"); - Writer rendererOutput = new StringWriter(); - Renderer renderer = createRenderer(rendererOutput); + Writer rendererOutput = new StringWriter(); + Renderer renderer = createRenderer(rendererOutput); renderer.start(); - RuleContext ctx = new RuleContext(); + RuleContext ctx = new RuleContext(); ctx.getReport().addListener(createReportListener()); // alternative way to collect violations try { - PMD.processFiles(configuration, ruleSetFactory, files, ctx, - Collections.singletonList(renderer)); + PMD.processFiles(configuration, ruleSetFactory, files, ctx, + Collections.singletonList(renderer)); } finally { - ClassLoader auxiliaryClassLoader = configuration.getClassLoader(); - if (auxiliaryClassLoader instanceof ClasspathClassLoader) { - ((ClasspathClassLoader) auxiliaryClassLoader).close(); + ClassLoader auxiliaryClassLoader = configuration.getClassLoader(); + if (auxiliaryClassLoader instanceof ClasspathClassLoader) { + ((ClasspathClassLoader) auxiliaryClassLoader).close(); } } renderer.end(); renderer.flush(); - System.out.println("Rendered Report:"); - System.out.println(rendererOutput.toString()); + System.out.println("Rendered Report:"); + System.out.println(rendererOutput.toString()); } - private static ThreadSafeReportListener createReportListener() { + private static ThreadSafeReportListener createReportListener() { return new ThreadSafeReportListener() { @Override - public void ruleViolationAdded(RuleViolation ruleViolation) { - System.out.printf("%-20s:%d %s%n", ruleViolation.getFilename(), + public void ruleViolationAdded(RuleViolation ruleViolation) { + System.out.printf("%-20s:%d %s%n", ruleViolation.getFilename(), ruleViolation.getBeginLine(), ruleViolation.getDescription()); } @Override - public void metricAdded(Metric metric) { + public void metricAdded(Metric metric) { // ignored } }; } - private static Renderer createRenderer(Writer writer) { - XMLRenderer xml = new XMLRenderer("UTF-8"); + private static Renderer createRenderer(Writer writer) { + XMLRenderer xml = new XMLRenderer("UTF-8"); xml.setWriter(writer); return xml; } - private static List<DataSource> determineFiles(String basePath) throws IOException { - Path dirPath = FileSystems.getDefault().getPath(basePath); - PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.java"); + private static List<DataSource> determineFiles(String basePath) throws IOException { + Path dirPath = FileSystems.getDefault().getPath(basePath); + PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.java"); - List<DataSource> files = new ArrayList<>(); + List<DataSource> files = new ArrayList<>(); - Files.walkFileTree(dirPath, new SimpleFileVisitor<Path>() { + Files.walkFileTree(dirPath, new SimpleFileVisitor<Path>() { @Override - public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { + public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { if (matcher.matches(path.getFileName())) { - System.out.printf("Using %s%n", path); - files.add(new FileDataSource(path.toFile())); + System.out.printf("Using %s%n", path); + files.add(new FileDataSource(path.toFile())); } else { - System.out.printf("Ignoring %s%n", path); + System.out.printf("Ignoring %s%n", path); } return super.visitFile(path, attrs); } }); - System.out.printf("Analyzing %d files in %s%n", files.size(), basePath); + System.out.printf("Analyzing %d files in %s%n", files.size(), basePath); return files; } } @@ -1657,7 +1669,7 @@ Then you can check the rendered output.

    diff --git a/pmd_userdocs_tools_maven.html b/pmd_userdocs_tools_maven.html index 6fb7824f53..4c6e3d2624 100644 --- a/pmd_userdocs_tools_maven.html +++ b/pmd_userdocs_tools_maven.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1619,7 +1631,7 @@ the previous paragraph. Add the following property to your project now:

    diff --git a/search.json b/search.json index f7204ce0ad..388ee88521 100644 --- a/search.json +++ b/search.json @@ -5160,7 +5160,7 @@ "tags": "extendinguserdocs", "keywords": "", "url": "pmd_userdocs_extending_rule_guidelines.html", -"summary": "Rule Guidelines" +"summary": "Rule Guidelines, or the last touches to a rule" } @@ -5568,7 +5568,7 @@ "title": "Writing a custom rule", "tags": "extendinguserdocs", "keywords": "", -"url": "pmd_userdocs_extending_writing_pmd_rules.html", +"url": "pmd_userdocs_extending_writing_java_rules.html", "summary": "Learn how to write a custom rule for PMD" } @@ -5580,12 +5580,44 @@ +{ +"title": "Writing a custom rule", +"tags": "extendinguserdocs", +"keywords": "", +"url": "pmd_userdocs_extending_writing_pmd_rules.html", +"summary": "" +} + + + +, + + + + + +{ +"title": "Introduction to writing PMD rules", +"tags": "extendinguserdocsgetting_started", +"keywords": "", +"url": "pmd_userdocs_extending_writing_rules_intro.html", +"summary": "Writing your own PMD rules" +} + + + +, + + + + + { "title": "Writing XPath rules", "tags": "extendinguserdocs", "keywords": "", "url": "pmd_userdocs_extending_writing_xpath_rules.html", -"summary": "Writing XPath rules for PMD" +"summary": "This page describes XPath rule support in more details" } @@ -5622,6 +5654,22 @@ +, + + + + + +{ +"title": "Your first rule XPath", +"tags": "extendinguserdocs", +"keywords": "", +"url": "pmd_userdocs_extending_your_first_rule.html", +"summary": "Introduction to rule writing through an example." +} + + + diff --git a/sitemap.xml b/sitemap.xml index e5cdee9fc5..f60892dcf9 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -619,12 +619,24 @@ + + https://pmd.github.io/pmd/pmd_userdocs_extending_writing_java_rules.html + + + + https://pmd.github.io/pmd/pmd_userdocs_extending_writing_pmd_rules.html + + https://pmd.github.io/pmd/pmd_userdocs_extending_writing_rules_intro.html + + + + https://pmd.github.io/pmd/pmd_userdocs_extending_writing_xpath_rules.html @@ -642,4 +654,10 @@ + + + https://pmd.github.io/pmd/pmd_userdocs_extending_your_first_rule.html + + + \ No newline at end of file diff --git a/tag_devdocs.html b/tag_devdocs.html index 171ff9899c..df2f9f9ef3 100644 --- a/tag_devdocs.html +++ b/tag_devdocs.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1824,6 +1836,26 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + @@ -1854,7 +1886,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_extending.html b/tag_extending.html index ee4a350547..3453d2bbd6 100644 --- a/tag_extending.html +++ b/tag_extending.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1708,7 +1720,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 Rule guidelines Page - Rule Guidelines + Rule Guidelines, or the last touches to a rule @@ -1804,7 +1816,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 - Writing a custom rule + Writing a custom rule Page Learn how to write a custom rule for PMD @@ -1816,9 +1828,35 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + Writing a custom rule + Page + The information on this page has been split into several separate pages. Please update your bookmarks: * [Introduction to writing rules](pmd_userdocs_extending_writing_rules_intro.html) * [Your First Rule](pmd_userdocs_extending_your_first_rule.html) introduces the basic development process of a rule with a running example * [Writing XPath Rules](pmd_userdocs_extending_writing_xpath_rules.html) explains a bit more about XPath rules and our... + + + + + + + + + + Introduction to writing PMD rules + Page + Writing your own PMD rules + + + + + + + + + + + Writing XPath rules Page - Writing XPath rules for PMD + This page describes XPath rule support in more details @@ -1837,6 +1875,18 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + Your first rule XPath + Page + Introduction to rule writing through an example. + + + + + + @@ -1860,7 +1910,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_getting_started.html b/tag_getting_started.html index 0de8c21a73..6c6f1ea271 100644 --- a/tag_getting_started.html +++ b/tag_getting_started.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1757,6 +1769,32 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + + + Introduction to writing PMD rules + Page + Writing your own PMD rules + + @@ -1806,7 +1844,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_languages.html b/tag_languages.html index 5e3d3b3abd..a9c3c4e756 100644 --- a/tag_languages.html +++ b/tag_languages.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1748,6 +1760,26 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + @@ -1788,7 +1820,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_metrics.html b/tag_metrics.html index 0803c0f15d..6cc508d39f 100644 --- a/tag_metrics.html +++ b/tag_metrics.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1772,6 +1784,26 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + @@ -1812,7 +1844,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_release_notes.html b/tag_release_notes.html index d6a6d76d58..e9f715bbaf 100644 --- a/tag_release_notes.html +++ b/tag_release_notes.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1748,6 +1760,26 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + @@ -1788,7 +1820,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_rule_references.html b/tag_rule_references.html index f41fa14728..fdef30dc1f 100644 --- a/tag_rule_references.html +++ b/tag_rule_references.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1809,6 +1821,20 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + @@ -1837,6 +1863,12 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + @@ -1860,7 +1892,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_tools.html b/tag_tools.html index b84977bca2..543c3119db 100644 --- a/tag_tools.html +++ b/tag_tools.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1784,6 +1796,26 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + @@ -1824,7 +1856,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_troubleshooting.html b/tag_troubleshooting.html index 5374729548..faa1db286e 100644 --- a/tag_troubleshooting.html +++ b/tag_troubleshooting.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1748,6 +1760,26 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + + + + + + + + + + + + + + + @@ -1788,7 +1820,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tag_userdocs.html b/tag_userdocs.html index d198bf9d30..72aac12e0a 100644 --- a/tag_userdocs.html +++ b/tag_userdocs.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1752,7 +1764,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 Rule guidelines Page - Rule Guidelines + Rule Guidelines, or the last touches to a rule @@ -1860,7 +1872,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 - Writing a custom rule + Writing a custom rule Page Learn how to write a custom rule for PMD @@ -1872,9 +1884,35 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + Writing a custom rule + Page + The information on this page has been split into several separate pages. Please update your bookmarks: * [Introduction to writing rules](pmd_userdocs_extending_writing_rules_intro.html) * [Your First Rule](pmd_userdocs_extending_your_first_rule.html) introduces the basic development process of a rule with a running example * [Writing XPath Rules](pmd_userdocs_extending_writing_xpath_rules.html) explains a bit more about XPath rules and our... + + + + + + + + + + Introduction to writing PMD rules + Page + Writing your own PMD rules + + + + + + + + + + + Writing XPath rules Page - Writing XPath rules for PMD + This page describes XPath rule support in more details @@ -1891,6 +1929,18 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3 + + + + + + Your first rule XPath + Page + Introduction to rule writing through an example. + + + + @@ -1914,7 +1964,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/titlepage/index.html b/titlepage/index.html index 8bb9cfe639..464dc9c768 100644 --- a/titlepage/index.html +++ b/titlepage/index.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1357,7 +1369,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    -
    Last generated: February 15, 2020
    +
    Last generated: February 16, 2020

    @@ -1387,7 +1399,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3
    diff --git a/tocpage/index.html b/tocpage/index.html index 7938fb8329..fe64d41d1a 100644 --- a/tocpage/index.html +++ b/tocpage/index.html @@ -340,13 +340,25 @@ -
  • Writing a rule
  • +
  • Introduction to writing rules
  • -
  • Writing XPath rules
  • +
  • Your first rule
  • + + + + + +
  • XPath rules
  • + + + + + +
  • Java rules
  • @@ -1387,7 +1399,7 @@ $('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3