diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 280b91ed9e..f93fb611c4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -47,13 +47,22 @@ On both scenarios, disabling the cache takes precedence over setting a cache loc #### New Rules -* The new Java rule `MissingOverride` (category `bestpractices`) detects overridden and implemented methods, - which are not marked with the `@Override` annotation. Annotating overridden methods with `@Override` ensures - at compile time that the method really overrides one, which helps refactoring and clarifies intent. +* The new Java rule [`MissingOverride`](pmd_rules_java_bestpractices.html#missingoverride) + (category `bestpractices`) detects overridden and implemented methods, which are not marked with the + `@Override` annotation. Annotating overridden methods with `@Override` ensures at compile time that + the method really overrides one, which helps refactoring and clarifies intent. -* The new Java rule `UnnecessaryAnnotationValueElement` (category `codestyle`) detects annotations with a single - element (`value`) that explicitely names it. That is, doing `@SuppressWarnings(value = "unchecked")` would be - flagged in favor of `@SuppressWarnings("unchecked")`. +* The new Java rule [`UnnecessaryAnnotationValueElement`](pmd_rules_java_codestyle.html#unnecessaryannotationvalueelement) + (category `codestyle`) detects annotations with a single element (`value`) that explicitely names it. + That is, doing `@SuppressWarnings(value = "unchecked")` would be flagged in favor of + `@SuppressWarnings("unchecked")`. + +* The new Java rule [`ControlStatementBraces`](pmd_rules_java_codestyle.html#controlstatementbraces) + (category `codestyle`) enforces the presence of braces on control statements where they are optional. + Properties allow to customize which statements are required to have braces. This rule replaces the now + deprecated rules `WhileLoopMustUseBraces`, `ForLoopMustUseBraces`, `IfStmtMustUseBraces`, and + `IfElseStmtMustUseBraces`. More than covering the use cases of those rules, this rule also supports + `do ... while` statements and `case` labels of `switch` statements (disabled by default). #### Modified Rules @@ -68,6 +77,10 @@ On both scenarios, disabling the cache takes precedence over setting a cache loc that allows to configure annotations that imply the method should be ignored. By default `@java.lang.Deprecated` is ignored. +#### Deprecated Rules + +* The Java rules `WhileLoopMustUseBraces`, `ForLoopMustUseBraces`, `IfStmtMustUseBraces`, and `IfElseStmtMustUseBraces` + are deprecated. They will be replaced by the new rule `ControlStatementBraces`, in the category `codestyle`. ### Fixed Issues @@ -77,6 +90,7 @@ On both scenarios, disabling the cache takes precedence over setting a cache loc * [#907](https://github.com/pmd/pmd/issues/907): \[java] UnusedPrivateField false-positive with @FXML * [#963](https://github.com/pmd/pmd/issues/965): \[java] ArrayIsStoredDirectly not triggered from variadic functions * java-codestyle + * [#974](https://github.com/pmd/pmd/issues/974): \[java] Merge *StmtMustUseBraces rules * [#983](https://github.com/pmd/pmd/issues/983): \[java] Detect annotations with single value element * java-design * [#832](https://github.com/pmd/pmd/issues/832): \[java] AvoidThrowingNullPointerException documentation suggestion diff --git a/pmd-core/src/main/resources/rulesets/releases/620.xml b/pmd-core/src/main/resources/rulesets/releases/620.xml index 70c17e4422..5a4a3a3613 100644 --- a/pmd-core/src/main/resources/rulesets/releases/620.xml +++ b/pmd-core/src/main/resources/rulesets/releases/620.xml @@ -10,5 +10,6 @@ This ruleset contains links to rules that are new in PMD v6.2.0 + diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 80ecbf4194..f51b6d1750 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -453,6 +453,64 @@ boolean bar(int x, int y) { + + + Enforce a policy for braces on control statements. It is recommended to use braces on 'if ... else' + statements and loop statements, even if they are optional. This usually makes the code clearer, and + helps prepare the future when you need to add another statement. That said, this rule lets you control + which statements are required to have braces via properties. + + From 6.2.0 on, this rule supersedes WhileLoopMustUseBraces, ForLoopMustUseBraces, IfStmtMustUseBraces, + and IfElseStmtMustUseBraces. + + 3 + + + + + + + + + + + + 1 + or (some $stmt (: in only the block statements until the next label :) + in following-sibling::BlockStatement except following-sibling::SwitchLabel[1]/following-sibling::BlockStatement + satisfies not($stmt/Statement/Block))] + ]]> + + + + + + + @@ -732,6 +791,7 @@ public interface GenericDao { @@ -770,6 +830,7 @@ if (foo) @@ -1745,6 +1806,7 @@ public class Foo { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java index 7183137beb..3441a46052 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CodeStyleRulesTest.java @@ -28,6 +28,7 @@ public class CodeStyleRulesTest extends SimpleAggregatorTst { addRule(RULESET, "ClassNamingConventions"); addRule(RULESET, "CommentDefaultAccessModifier"); addRule(RULESET, "ConfusingTernary"); + addRule(RULESET, "ControlStatementBraces"); addRule(RULESET, "DefaultPackage"); addRule(RULESET, "DontImportJavaLang"); addRule(RULESET, "DuplicateImports"); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ControlStatementBraces.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ControlStatementBraces.xml new file mode 100644 index 0000000000..571e99cf2a --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ControlStatementBraces.xml @@ -0,0 +1,404 @@ + + + + While, no braces + 1 + + + + + While, no braces, allowed + false + 0 + + + + + While, with braces + 0 + + + + + Empty while + 1 + + + + + Empty while, allowed + true + 0 + + + + + For, no braces + 1 + + + + + For, no braces, allowed + false + 0 + + + + + For, with braces + 0 + + + + + Empty for + 1 + + + + + Empty for, allowed + true + 0 + + + + + Do while, no braces + 1 + + + + + Do while, no braces, allowed + false + 0 + + + + + Do while, with braces + 0 + + + + + Empty Do while + 1 + + + + + Empty Do while, allowed + true + 0 + + + + + If else, no braces + 2 + + + + + If else, no braces, allowed + false + 0 + + + + + If else, braces on if + 1 + + + + + If else, braces on else + 1 + + + + + If chain, partial braces + 2 + 5,10 + + + + + + Case, no braces, allowed + 0 + + + + + Case, no braces + true + 2 + 6,9 + + + + + Case, dangling unbraced statement + true + 1 + 6 + + + + + Case, dangling unbraced statement + true + 1 + 6 + + + + +