From 6e02494e5ec3c4b00d723ce652dd1e3255e4ffbd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 14 Aug 2017 16:37:44 +0200 Subject: [PATCH] [doc] [java] Adjust externalInfoUrl properties to new site - Part 1 Note: I also took the chance to fix tab damage --- .../main/resources/rulesets/java/android.xml | 39 ++- .../main/resources/rulesets/java/basic.xml | 328 +++++++++--------- .../main/resources/rulesets/java/braces.xml | 31 +- .../main/resources/rulesets/java/clone.xml | 53 ++- .../main/resources/rulesets/java/codesize.xml | 243 +++++++------ .../main/resources/rulesets/java/comments.xml | 38 +- .../resources/rulesets/java/controversial.xml | 249 ++++++------- .../main/resources/rulesets/java/coupling.xml | 97 +++--- .../pmd/AbstractRuleSetFactoryTest.java | 9 +- pom.xml | 4 +- 10 files changed, 531 insertions(+), 560 deletions(-) diff --git a/pmd-java/src/main/resources/rulesets/java/android.xml b/pmd-java/src/main/resources/rulesets/java/android.xml index ff8daf3c9b..5988065afc 100644 --- a/pmd-java/src/main/resources/rulesets/java/android.xml +++ b/pmd-java/src/main/resources/rulesets/java/android.xml @@ -10,10 +10,11 @@ To get better results, make sure that the auxclasspath is defined for type resol + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_android.html#callsuperfirst"> Super should be called at the start of the method 3 @@ -42,20 +43,21 @@ To get better results, make sure that the auxclasspath is defined for type resol + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_android.html#callsuperlast"> Super should be called at the end of the method 3 @@ -84,20 +86,21 @@ public class DummyActivity extends Activity { + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_android.html#donothardcodesdcard"> Use Environment.getExternalStorageDirectory() instead of "/sdcard" 3 @@ -108,11 +111,11 @@ public class DummyActivity extends Activity { diff --git a/pmd-java/src/main/resources/rulesets/java/basic.xml b/pmd-java/src/main/resources/rulesets/java/basic.xml index df103cd678..d0777e9d47 100644 --- a/pmd-java/src/main/resources/rulesets/java/basic.xml +++ b/pmd-java/src/main/resources/rulesets/java/basic.xml @@ -8,28 +8,26 @@ The Basic ruleset contains a collection of good practices which should be followed. - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#jumbledincrementer"> Avoid jumbled loop incrementers - its usually a mistake, and is confusing even if intentional. 3 - - - + [ + ForUpdate/StatementExpressionList/StatementExpression/PostfixExpression/PrimaryExpression/PrimaryPrefix/Name/@Image + = + ancestor::ForStatement/ForInit//VariableDeclaratorId/@Image + ] +]]> @@ -43,7 +41,7 @@ public class JumbledIncrementerRule1 { } } } - ]]> +]]> @@ -52,31 +50,29 @@ public class JumbledIncrementerRule1 { since="1.02" message="This for loop could be simplified to a while loop" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#ForLoopShouldBeWhileLoop"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#forloopshouldbewhileloop"> Some for loops can be simplified to while loops, this makes them more concise. 3 - - 1] - [not(LocalVariableDeclaration)] - [not(ForInit)] - [not(ForUpdate)] - [not(Type and Expression and Statement)] - ]]> - + [count(*) > 1] + [not(LocalVariableDeclaration)] + [not(ForInit)] + [not(ForUpdate)] + [not(Type and Expression and Statement)] +]]> @@ -87,32 +83,32 @@ public class Foo { since="0.4" message="Ensure you override both equals() and hashCode()" class="net.sourceforge.pmd.lang.java.rule.basic.OverrideBothEqualsAndHashcodeRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#OverrideBothEqualsAndHashcode"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#overridebothequalsandhashcode"> Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass. 3 @@ -123,7 +119,7 @@ public class Foo { // perfect, both methods provided since="1.04" message="Double checked locking is not thread safe in Java." class="net.sourceforge.pmd.lang.java.rule.basic.DoubleCheckedLockingRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#DoubleCheckedLocking"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#doublecheckedlocking"> Partially created objects can be returned by the Double Checked Locking pattern when used in Java. An optimizing JRE may assign a reference to the baz variable before it calls the constructor of the object the @@ -131,24 +127,24 @@ reference points to. Note: With Java 5, you can make Double checked locking work, if you declare the variable to be `volatile`. -For more details refer to: http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html -or http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html +For more details refer to: <http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html> +or <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html> 1 @@ -159,7 +155,7 @@ public class Foo { since="1.05" message="Avoid returning from a finally block" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#ReturnFromFinallyBlock"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#returnfromfinallyblock"> Avoid returning from a finally block, this can discard exceptions. @@ -176,15 +172,15 @@ Avoid returning from a finally block, this can discard exceptions. @@ -195,7 +191,7 @@ public class Bar { since="1.5" message="Do not use 'if' statements that are always true or always false" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#UnconditionalIfStatement"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#unconditionalifstatement"> Do not use "if" statements whose conditionals are always true or always false. @@ -214,11 +210,11 @@ Do not use "if" statements whose conditionals are always true or always false. @@ -228,15 +224,15 @@ public class Foo { since="1.2" message="Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead." class="net.sourceforge.pmd.lang.java.rule.basic.BooleanInstantiationRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#BooleanInstantiation"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#booleaninstantiation"> Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead. 2 @@ -246,7 +242,7 @@ Boolean buz = Boolean.valueOf(false); // ...., just reference Boolean.FALSE; since="3.1" message="These nested if statements could be combined" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#CollapsibleIfStatements"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#collapsibleifstatements"> Sometimes two consecutive 'if' statements can be consolidated by separating their conditions with a boolean short-circuit operator. @@ -267,28 +263,28 @@ Sometimes two consecutive 'if' statements can be consolidated by separating thei - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#classcastexceptionwithtoarray"> When deriving an array of a specific class from your Collection, one should provide an array of the same class as the parameter of the toArray() method. Doing otherwise you will will result @@ -333,7 +329,7 @@ Integer[] b = (Integer [])c.toArray(new Integer[c.size()]); since="3.4" message="Avoid creating BigDecimal with a decimal (float/double) literal. Use a String literal" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#AvoidDecimalLiteralsInBigDecimalConstructor"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#avoiddecimalliteralsinbigdecimalconstructor"> One might assume that the result of "new BigDecimal(0.1)" is exactly equal to 0.1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. @@ -375,22 +371,22 @@ exactly equal to 0.1, as one would expect. Therefore, it is generally recommend + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#misplacednullcheck"> The null check here is misplaced. If the variable is null a NullPointerException will be thrown. Either the check is useless (the variable will never be "null") or it is incorrect. @@ -424,28 +420,28 @@ Either the check is useless (the variable will never be "null") or it is incorre Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment @@ -465,12 +461,12 @@ it contains methods that are not thread-safe. @@ -480,7 +476,7 @@ public class Bar { since="3.8" message="Method call on object which may be null" class="net.sourceforge.pmd.lang.java.rule.basic.BrokenNullCheckRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#BrokenNullCheck"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#brokennullcheck"> The null check is broken since it will throw a NullPointerException itself. It is likely that you used || instead of && or vice versa. @@ -490,11 +486,11 @@ It is likely that you used || instead of && or vice versa. @@ -504,7 +500,7 @@ public String bar(String string) { since="3.9" message="Don't create instances of already existing BigInteger and BigDecimal (ZERO, ONE, TEN)" class="net.sourceforge.pmd.lang.java.rule.basic.BigIntegerInstantiationRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#BigIntegerInstantiation"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#bigintegerinstantiation"> Don't create instances of already existing BigInteger (BigInteger.ZERO, BigInteger.ONE) and for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN) @@ -512,11 +508,11 @@ for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal 3 @@ -525,20 +521,20 @@ bi4 = new BigInteger(0); // reference BigInteger.ZERO instead since="3.9" message="Do not start a literal by 0 unless it's an octal value" class="net.sourceforge.pmd.lang.java.rule.basic.AvoidUsingOctalValuesRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#AvoidUsingOctalValues"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#avoidusingoctalvalues"> - + ]]> 3 - + @@ -546,32 +542,32 @@ k = i * j; // set k with 80 not 120 since="4.1" message="Do not hard code the IP address ${variableName}" class="net.sourceforge.pmd.lang.java.rule.basic.AvoidUsingHardCodedIPRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#AvoidUsingHardCodedIP"> - - + + - - 3 - + ]]> + + 3 + - - + - + ]]> + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#checkresultset"> - + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#extendsobject"> No need to explicitly extend Object. 4 @@ -651,18 +647,18 @@ int j = -~7; - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#checkskipresult"> The skip() method may skip a smaller number of bytes than requested. Check the returned value to find out if it was the case or not. 3 @@ -687,11 +683,11 @@ public class Foo { - + 25) { - break; - } + if (i*i > 25) { + break; + } } ]]> @@ -724,7 +720,7 @@ for (int i = 0; i < 10; i++) { since="4.3" message="Don't call Thread.run() explicitly, use Thread.start()" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#DontCallThreadRun"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#dontcallthreadrun"> Explicitly calling Thread.run() method will execute in the caller's thread of control. Instead, call Thread.start() for the intended behavior. @@ -763,7 +759,7 @@ new Thread().run(); // same violation since="4.3" message="Don't use floating point for loop indices. If you must use floating point, use double." class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#DontUseFloatTypeForLoopIndices"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#dontusefloattypeforloopindices"> Don't use floating point for loop indices. If you must use floating point, use double unless you're certain that float provides enough precision and you have a compelling @@ -802,7 +798,7 @@ public class Count { since="5.4.0" message="Ternary operators that can be simplified with || or &&" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#SimplifiedTernary"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_basic.html#simplifiedternary"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_braces.html#ifstmtsmustusebraces"> Avoid using if statements without using braces to surround the code block. If the code formatting or indentation is lost then it becomes difficult to separate the code being @@ -31,12 +31,11 @@ controlled from the rest. @@ -44,11 +43,11 @@ if (foo) { // preferred approach + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_braces.html#whileloopsmustusebraces"> Avoid using 'while' statements without using braces to surround the code block. If the code formatting or indentation is lost then it becomes difficult to separate the code being @@ -66,10 +65,10 @@ controlled from the rest. @@ -81,7 +80,7 @@ while (true) { // preferred approach since="0.2" message="Avoid using 'if...else' statements without curly braces" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/braces.html#IfElseStmtsMustUseBraces"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_braces.html#ifelsestmtsmustusebraces"> Avoid using if..else statements without using surrounding braces. If the code formatting or indentation is lost then it becomes difficult to separate the code being controlled @@ -104,7 +103,7 @@ from the rest. + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_braces.html#forloopsmustusebraces"> Avoid using 'for' statements without using curly braces. If the code formatting or indentation is lost then it becomes difficult to separate the code being controlled diff --git a/pmd-java/src/main/resources/rulesets/java/clone.xml b/pmd-java/src/main/resources/rulesets/java/clone.xml index 5f5915e8f9..01350d2b5d 100644 --- a/pmd-java/src/main/resources/rulesets/java/clone.xml +++ b/pmd-java/src/main/resources/rulesets/java/clone.xml @@ -9,11 +9,11 @@ The Clone Implementation ruleset contains a collection of rules that find questi + language="java" + since="1.4" + message="Object clone() should be implemented with super.clone()" + class="net.sourceforge.pmd.lang.rule.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_clone.html#propercloneimplementation"> Object clone() should be implemented with super.clone(). @@ -47,11 +47,11 @@ class Foo{ + language="java" + since="1.9" + message="clone() method should throw CloneNotSupportedException" + class="net.sourceforge.pmd.lang.rule.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_clone.html#clonethrowsclonenotsupportedexception"> The method clone() should throw a CloneNotSupportedException. @@ -76,22 +76,22 @@ and count(NameList/Name[contains + language="java" + since="1.9" + message="clone() method should be implemented only if implementing Cloneable interface" + class="net.sourceforge.pmd.lang.rule.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_clone.html#clonemethodmustimplementcloneable"> The method clone() should only be implemented if the class implements the Cloneable interface with the exception of a final method that only throws CloneNotSupportedException. @@ -112,7 +112,6 @@ and Block[count(BlockStatement)=1] /BlockStatement/Statement/ThrowStatement/Expression /PrimaryExpression/PrimaryPrefix/AllocationExpression /ClassOrInterfaceType[@Image = 'CloneNotSupportedException'])]] - ]]> @@ -134,7 +133,7 @@ public class MyClass { since="5.4.0" message="The return type of the clone() method must be the class name when implements Cloneable" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/clone.html#CloneMethodReturnTypeMustMatchClassName"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_clone.html#clonemethodreturntypemustmatchclassname"> If a class implements cloneable the return type of the method clone() must be the class name. That way, the caller of the clone method doesn't need to cast the returned clone to the correct type. @@ -178,7 +177,7 @@ public class Foo implements Cloneable { since="5.4.0" message="clone() method must be public if the class implements Cloneable" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/clone.html#CloneMethodMustBePublic"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_clone.html#clonemethodmustbepublic"> The java Manual says "By convention, classes that implement this interface should override Object.clone (which is protected) with a public method." @@ -189,10 +188,8 @@ Object.clone (which is protected) with a public method." diff --git a/pmd-java/src/main/resources/rulesets/java/codesize.xml b/pmd-java/src/main/resources/rulesets/java/codesize.xml index 6f109353bf..1eb9106450 100644 --- a/pmd-java/src/main/resources/rulesets/java/codesize.xml +++ b/pmd-java/src/main/resources/rulesets/java/codesize.xml @@ -13,7 +13,7 @@ The Code Size ruleset contains rules that find problems related to code size or since="3.9" message="The method {0}() has an NPath complexity of {1}" class="net.sourceforge.pmd.lang.java.rule.codesize.NPathComplexityRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#NPathComplexity"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#npathcomplexity"> The NPath complexity of a method is the number of acyclic execution paths through that method. A threshold of 200 is generally considered the point where measures should be taken to reduce @@ -22,44 +22,42 @@ complexity and increase readability. 3 r) { - doSomething(); - while (f < 5 ) { - anotherThing(); - f -= 27; - } - } else { - tryThis(); - } - } - } - if ( r - n > 45) { - while (doMagic()) { - findRabbits(); - } - } - try { - doSomethingDangerous(); - } catch (Exception ex) { - makeAmends(); - } finally { - dontDoItAgain(); - } - } +void bar() { // this is something more complex than it needs to be, + if (y) { // it should be broken down into smaller methods or functions + for (j = 0; j < m; j++) { + if (j > r) { + doSomething(); + while (f < 5 ) { + anotherThing(); + f -= 27; + } + } else { + tryThis(); + } + } + } + if ( r - n > 45) { + while (doMagic()) { + findRabbits(); + } + } + try { + doSomethingDangerous(); + } catch (Exception ex) { + makeAmends(); + } finally { + dontDoItAgain(); + } } - ]]> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#excessivemethodlength"> When methods are excessively long this usually indicates that the method is doing more than its name/signature might suggest. They also become challenging for others to digest since excessive @@ -70,22 +68,20 @@ Try to reduce the method length by creating helper methods and removing any copy - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#excessiveparameterlist"> Methods with numerous parameters are a challenge to maintain, especially if most of them share the same datatype. These situations usually denote the need for new objects to wrap the numerous parameters. @@ -93,16 +89,16 @@ same datatype. These situations usually denote the need for new objects to wrap 3 @@ -111,57 +107,54 @@ public void addPerson( // preferred approach + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#excessiveclasslength"> Excessive class file lengths are usually indications that the class may be burdened with excessive responsibilities that could be provided by external classes or functions. In breaking these methods -apart the code becomes more managable and ripe for reuse. +apart the code becomes more manageable and ripe for reuse. 3 - + - 3 - - 3 @@ -258,20 +249,18 @@ public class Foo { // This has a Cyclomatic Complexity = 12 - - 3 @@ -317,10 +306,10 @@ public class Foo { // This has a Cyclomatic Complexity = 9 + since="1.04" + message="This class has a bunch of public methods and attributes" + class="net.sourceforge.pmd.lang.java.rule.codesize.ExcessivePublicCountRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#excessivepubliccount"> Classes with large numbers of public methods and attributes require disproportionate testing efforts since combinational side effects grow rapidly and increase risk. Refactoring these classes into @@ -331,25 +320,25 @@ developed easily. + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#toomanyfields"> Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields, possibly through grouping related fields in new objects. For example, a class with individual @@ -358,7 +347,7 @@ city/state/zip fields could park them within a single Address field. 3 - + This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm, @@ -387,25 +377,25 @@ lines of code that are split are counted as one. - + This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm, @@ -415,24 +405,25 @@ lines of code that are split are counted as one. - + This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm, @@ -442,16 +433,16 @@ lines of code that are split are counted as one. @@ -459,16 +450,14 @@ public class Foo extends Bar { + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codesize.html#toomanymethods"> - +A class with too many methods is probably a good suspect for refactoring, in order to reduce its +complexity and find a way to have more fine grained objects. 3 diff --git a/pmd-java/src/main/resources/rulesets/java/comments.xml b/pmd-java/src/main/resources/rulesets/java/comments.xml index 42dad25e12..1a45408802 100755 --- a/pmd-java/src/main/resources/rulesets/java/comments.xml +++ b/pmd-java/src/main/resources/rulesets/java/comments.xml @@ -10,10 +10,10 @@ Rules intended to catch errors related to code comments + since="5.1" + message="Comment is required" + class="net.sourceforge.pmd.lang.java.rule.comments.CommentRequiredRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_comments.html#commentrequired"> Denotes whether comments are required (or unwanted) for specific language elements. @@ -23,17 +23,17 @@ Denotes whether comments are required (or unwanted) for specific language elemen /** * * -* @author George Bush +* @author Jon Doe */ ]]> + since="5.0" + message="Comment is too large" + class="net.sourceforge.pmd.lang.java.rule.comments.CommentSizeRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_comments.html#commentsize"> Determines whether the dimensions of non-header comments found are within the specified limits. @@ -42,7 +42,7 @@ Determines whether the dimensions of non-header comments found are within the sp + since="5.0" + message="Invalid words or phrases found" + class="net.sourceforge.pmd.lang.java.rule.comments.CommentContentRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_comments.html#commentcontent"> A rule for the politically correct... we don't want to offend anyone. 3 + since="5.4.0" + class="net.sourceforge.pmd.lang.java.rule.comments.CommentDefaultAccessModifierRule" + message="Missing commented default access modifier" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_comments.html#commentdefaultaccessmodifier"> To avoid mistakes if we want that a Method, Constructor, Field or Nested class have a default access modifier we must add a comment at the beginning of it's declaration. diff --git a/pmd-java/src/main/resources/rulesets/java/controversial.xml b/pmd-java/src/main/resources/rulesets/java/controversial.xml index d704db9ae3..1e7b42380d 100644 --- a/pmd-java/src/main/resources/rulesets/java/controversial.xml +++ b/pmd-java/src/main/resources/rulesets/java/controversial.xml @@ -11,14 +11,14 @@ They are held here to allow people to include them as they see fit within their + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#unnecessaryconstructor"> This rule detects when a constructor is not necessary; i.e., when there is only one constructor, -its public, has an empty body, and takes no arguments. +it's public, has an empty body, and takes no arguments. 3 @@ -46,10 +46,10 @@ public class Foo { + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#nullassignment"> Assigning a "null" to a variable (outside of its declaration) is usually bad form. Sometimes, this type of assignment is an indication that the programmer doesn't completely understand what is going on in the code. @@ -72,10 +72,10 @@ public void bar() { + since="1.0" + message="A method should have only one exit point, and that should be the last statement in the method" + class="net.sourceforge.pmd.lang.java.rule.controversial.OnlyOneReturnRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#onlyonereturn"> A method should have only one exit point, and that should be the last statement in the method. @@ -95,10 +95,10 @@ public class OneReturnOnly1 { + since="1.03" + message="Avoid assignments in operands" + class="net.sourceforge.pmd.lang.java.rule.controversial.AssignmentInOperandRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#assignmentinoperand"> Avoid assignments in operands; this can make code more complicated and harder to read. @@ -116,11 +116,11 @@ public void bar() { + language="java" + since="1.04" + message="Each class should declare at least one constructor" + class="net.sourceforge.pmd.lang.rule.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#atleastoneconstructor"> Each class should declare at least one constructor. @@ -153,10 +153,10 @@ public class Foo { + since="1.5" + message="Avoid importing anything from the 'sun.*' packages" + class="net.sourceforge.pmd.lang.java.rule.controversial.DontImportSunRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#dontimportsun"> Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. @@ -170,17 +170,17 @@ public class Foo {} + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#suspiciousoctalescape"> A suspicious octal escape sequence was found inside a String literal. The Java language specification (section 3.10.6) says an octal escape sequence inside a literal String shall consist of a backslash followed by: - OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit + OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit Any octal escape sequence followed by non-octal digits can be confusing, e.g. "\038" is interpreted as the octal escape sequence "\03" followed by @@ -198,11 +198,11 @@ public void foo() { + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#callsuperinconstructor"> It is a good practice to call super() in a constructor. If super() is not called but another constructor (such as an overloaded constructor) is called, this rule will not report it. @@ -238,11 +238,11 @@ public class Foo extends Bar{ + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#unnecessaryparentheses"> Sometimes expressions are wrapped in unnecessary parentheses, making them look like function calls. @@ -265,18 +265,18 @@ Sometimes expressions are wrapped in unnecessary parentheses, making them look l public class Foo { boolean bar() { return (true); - } + } } ]]> + language="java" + since="3.4" + message="Use explicit scoping instead of the default package private level" + class="net.sourceforge.pmd.lang.rule.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#defaultpackage"> Use explicit scoping instead of accidental usage of default package private level. The rule allows methods and fields annotated with Guava's @VisibleForTesting. @@ -300,11 +300,11 @@ or MethodDeclaration[@PackagePrivate='true'] - The dataflow analysis tracks local definitions, undefinitions and references to variables on different paths on the data flow. + message="Found ''{0}''-anomaly for variable ''{1}'' (lines ''{2}''-''{3}'')." + class="net.sourceforge.pmd.lang.java.rule.controversial.DataflowAnomalyAnalysisRule" + dfa="true" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#dataflowanomalyanalysis"> + The dataflow analysis tracks local definitions, undefinitions and references to variables on different paths on the data flow. From those informations there can be found various problems. 1. UR - Anomaly: There is a reference to a variable that was not defined before. This is a bug and leads to an error. @@ -324,16 +324,14 @@ public void foo() { - - - 3 + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#avoidfinallocalvariable"> + Avoid using final local variables, turn them into fields. + 3 - + - 1 @@ -398,29 +393,23 @@ public class UsingShort { - - + - 2 @@ -428,33 +417,30 @@ the volatile keyword should not be used for maintenance purpose and portability. - + - 2 @@ -469,7 +455,7 @@ public class SomeJNIClass { static { System.loadLibrary("nativelib"); - } + } public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException { System.loadLibrary("nativelib"); @@ -479,13 +465,12 @@ public class SomeJNIClass { - + - + message="Do not explicitly trigger a garbage collection." + class="net.sourceforge.pmd.lang.rule.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#donotcallgarbagecollectionexplicitly"> - 2 @@ -617,18 +600,15 @@ public class GCCall { - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#onedeclarationperline"> - 4 @@ -659,13 +639,12 @@ String name, - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#avoidprefixingmethodparameters"> - + Avoid using hard-coded literals in conditional statements. By declaring them as static variables or private members with descriptive names maintainability is enhanced. By default, the literals "-1" and "0" are ignored. @@ -762,11 +742,12 @@ public void checkRequests() { - + When you write a public method, you should be thinking in terms of an API. If your method is public, it means other class will use it, therefore, you want (or need) to offer a comprehensive and evolutive API. If you pass a lot of information @@ -790,17 +771,17 @@ your API. @@ -812,7 +793,7 @@ public class MyClass { since="4.2.6" message="If you run in Java5 or newer and have concurrent access, you should use the ConcurrentHashMap implementation" class="net.sourceforge.pmd.lang.rule.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/rules/java/controversial.html#UseConcurrentHashMap"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_controversial.html#useconcurrenthashmap"> Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can perform efficient map reads without blocking other threads. @@ -832,8 +813,8 @@ perform efficient map reads without blocking other threads. + since="1.04" + message="High amount of different objects as members denotes a high coupling" + class="net.sourceforge.pmd.lang.java.rule.coupling.CouplingBetweenObjectsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_coupling.html#couplingbetweenobjects"> This rule counts the number of unique attributes, local variables, and return types within an object. A number higher than the specified threshold can indicate a high degree of coupling. @@ -26,26 +26,26 @@ import org.Bar; import org.Bardo; public class Foo { - private Blah var1; - private Bar var2; - - //followed by many imports of unique objects - void ObjectC doWork() { - Bardo var55; - ObjectA var44; - ObjectZ var93; - return something; - } + private Blah var1; + private Bar var2; + + //followed by many imports of unique objects + void ObjectC doWork() { + Bardo var55; + ObjectA var44; + ObjectZ var93; + return something; + } } ]]> + since="1.04" + message="A high number of imports can indicate a high degree of coupling within an object." + class="net.sourceforge.pmd.lang.java.rule.coupling.ExcessiveImportsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_coupling.html#excessiveimports"> A high number of imports can indicate a high degree of coupling within an object. This rule counts the number of unique imports and reports a violation if the count is above the @@ -58,17 +58,17 @@ import blah.blah.Baz; import blah.blah.Bif; // 18 others from the same package elided public class Foo { - public void doWork() {} + public void doWork() {} } ]]> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_coupling.html#loosecoupling"> The use of implementation types as object references limits your ability to use alternate implementations in the future as requirements change. Whenever available, referencing objects @@ -77,28 +77,28 @@ by their interface types provides much more flexibility. 3 list = new ArrayList<>(); -public HashSet getFoo() { - return new HashSet(); +public HashSet getFoo() { + return new HashSet(); } - // preferred approach -private List list = new ArrayList(); +// preferred approach +private List list = new ArrayList<>(); -public Set getFoo() { - return new HashSet(); +public Set getFoo() { + return new HashSet(); } ]]> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_coupling.html#loosepackagecoupling"> Avoid using classes from the configured package hierarchy outside of the package hierarchy, except when using one of the configured allowed classes. @@ -111,26 +111,28 @@ package some.package; import some.other.package.subpackage.subsubpackage.DontUseThisClass; public class Bar { - DontUseThisClass boo = new DontUseThisClass(); + DontUseThisClass boo = new DontUseThisClass(); } ]]> - + language="java" + since="5.0" + message="Potential violation of Law of Demeter" + class="net.sourceforge.pmd.lang.java.rule.coupling.LawOfDemeterRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_coupling.html#lawofdemeter"> -The Law of Demeter is a simple rule, that says "only talk to friends". It helps to reduce coupling between classes or objects. +The Law of Demeter is a simple rule, that says "only talk to friends". It helps to reduce coupling between classes +or objects. + See also the references: -Andrew Hunt, David Thomas, and Ward Cunningham. The Pragmatic Programmer. From Journeyman to Master. Addison-Wesley Longman, Amsterdam, October 1999.; -K.J. Lieberherr and I.M. Holland. Assuring good style for object-oriented programs. Software, IEEE, 6(5):38–48, 1989.; -http://www.ccs.neu.edu/home/lieber/LoD.html; -http://en.wikipedia.org/wiki/Law_of_Demeter + +* Andrew Hunt, David Thomas, and Ward Cunningham. The Pragmatic Programmer. From Journeyman to Master. Addison-Wesley Longman, Amsterdam, October 1999.; +* K.J. Lieberherr and I.M. Holland. Assuring good style for object-oriented programs. Software, IEEE, 6(5):38–48, 1989.; +* <http://www.ccs.neu.edu/home/lieber/LoD.html> +* <http://en.wikipedia.org/wiki/Law_of_Demeter> 3 @@ -142,14 +144,14 @@ public class Foo { public void example(Bar b) { // this method call is ok, as b is a parameter of "example" 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();" c.doIt(); - + // this is also a violation, just expressed differently as a method chain without temporary variables. b.getC().doIt(); - + // a constructor call, not a method call. D d = new D(); // this method call is ok, because we have create the new instance of D locally. @@ -159,6 +161,5 @@ public class Foo { ]]> - - \ No newline at end of file + \ No newline at end of file diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java index d076e07a23..713dcb36d5 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java @@ -18,12 +18,14 @@ import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.StringTokenizer; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import org.apache.commons.io.FilenameUtils; import org.junit.BeforeClass; import org.junit.Test; import org.xml.sax.InputSource; @@ -115,8 +117,11 @@ public abstract class AbstractRuleSetFactoryTest { messages += "Rule " + fileName + "/" + rule.getName() + " is missing 'externalInfoURL' attribute" + PMD.EOL; } else { - String expectedExternalInfoURL = "https?://pmd.(sourceforge.net|github.io)/.+/rules/" - + fileName.replaceAll("rulesets/", "").replaceAll(".xml", "") + ".html#" + rule.getName(); + String expectedExternalInfoURL = "https?://pmd.(sourceforge.net|github.io)/.+/pmd_rules_" + + language.getTerseName() + "_" + + FilenameUtils.getBaseName(fileName) + + ".html#" + + rule.getName().toLowerCase(Locale.ROOT); if (rule.getExternalInfoUrl() == null || !rule.getExternalInfoUrl().matches(expectedExternalInfoURL)) { invalidExternalInfoURL++; diff --git a/pom.xml b/pom.xml index 897c97de60..244d17afce 100644 --- a/pom.xml +++ b/pom.xml @@ -266,7 +266,7 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code UTF-8 UTF-8 - http://pmd.sourceforge.net/snapshot/${project.artifactId} + http://pmd.sourceforge.net/snapshot -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} @@ -873,7 +873,7 @@ Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code pmd-release - https://pmd.github.io/pmd-${project.version}/${project.artifactId} + https://pmd.github.io/pmd-${project.version}