diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b626a0b762..cabc0d7b83 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,8 @@ This is a {{ site.pmd.release_type }} release. * [#5222](https://github.com/pmd/pmd/issues/5222): \[core] RuleReference/RuleSetWriter don't handle changed default property values correctly * java * [#5190](https://github.com/pmd/pmd/issues/5190): \[java] NPE in type inference +* java-codestyle + * [#5046](https://github.com/pmd/pmd/issues/5046): \[java] LocalVariableCouldBeFinal false positive with try/catch * java-errorprone * [#5068](https://github.com/pmd/pmd/issues/5068): \[java] MissingStaticMethodInNonInstantiatableClass: false positive with builder pattern * [#5207](https://github.com/pmd/pmd/issues/5207): \[java] CheckSkipResult: false positve for a private method `void skip(int)` in a subclass of FilterInputStream diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java index c16c1a34ed..183cd71fd0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java @@ -636,7 +636,16 @@ public final class DataflowPass { SpanInfo exceptionalState = null; int i = 0; for (ASTCatchClause catchClause : node.getCatchClauses()) { - SpanInfo current = acceptOpt(catchClause, catchSpans.get(i)); + /* + Note: here we absorb the end state of the body, which is not necessary. + We do that to conform to the language's definition of "effective-finality", + which is more conservative than needed. Doing this fixes FPs in LocalVariableCouldBeFinal + at the cost of some FNs in UnusedAssignment. + */ + SpanInfo catchSpan = catchSpans.get(i); + catchSpan.absorb(bodyState); + + SpanInfo current = acceptOpt(catchClause, catchSpan); exceptionalState = current.absorb(exceptionalState); i++; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/AllDataflowRuleTests.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/AllDataflowRuleTests.java new file mode 100644 index 0000000000..a0e8159ddc --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/AllDataflowRuleTests.java @@ -0,0 +1,32 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule; + + +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +import net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedAssignmentTest; +import net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableCouldBeFinalTest; +import net.sourceforge.pmd.lang.java.rule.design.AvoidThrowingNullPointerExceptionTest; +import net.sourceforge.pmd.lang.java.rule.design.ImmutableFieldTest; +import net.sourceforge.pmd.lang.java.rule.design.LawOfDemeterTest; +import net.sourceforge.pmd.lang.java.rule.design.SingularFieldTest; +import net.sourceforge.pmd.lang.java.rule.errorprone.ImplicitSwitchFallThroughTest; +import net.sourceforge.pmd.lang.java.rule.errorprone.InvalidLogMessageFormatTest; + +@Suite +@SelectClasses({ + LocalVariableCouldBeFinalTest.class, + ImmutableFieldTest.class, + UnusedAssignmentTest.class, + LawOfDemeterTest.class, + SingularFieldTest.class, + ImplicitSwitchFallThroughTest.class, + InvalidLogMessageFormatTest.class, + AvoidThrowingNullPointerExceptionTest.class +}) +public class AllDataflowRuleTests { +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentTest.java index 0401dd83ec..61f8a16b77 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; import net.sourceforge.pmd.test.PmdRuleTst; -class UnusedAssignmentTest extends PmdRuleTst { +public class UnusedAssignmentTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java index 5c49860210..d87bf490ac 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; import net.sourceforge.pmd.test.PmdRuleTst; -class LocalVariableCouldBeFinalTest extends PmdRuleTst { +public class LocalVariableCouldBeFinalTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java index c1b437ab41..e729824a6d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.design; import net.sourceforge.pmd.test.PmdRuleTst; -class AvoidThrowingNullPointerExceptionTest extends PmdRuleTst { +public class AvoidThrowingNullPointerExceptionTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java index eb0972d72b..7c614b7dcd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.design; import net.sourceforge.pmd.test.PmdRuleTst; -class ImmutableFieldTest extends PmdRuleTst { +public class ImmutableFieldTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java index b4e94a6e26..88e54418ac 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.design; import net.sourceforge.pmd.test.PmdRuleTst; -class LawOfDemeterTest extends PmdRuleTst { +public class LawOfDemeterTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java index 81835c7c5b..b550b06f85 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.design; import net.sourceforge.pmd.test.PmdRuleTst; -class SingularFieldTest extends PmdRuleTst { +public class SingularFieldTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java index 3a14a27009..71f0e03495 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; import net.sourceforge.pmd.test.PmdRuleTst; -class ImplicitSwitchFallThroughTest extends PmdRuleTst { +public class ImplicitSwitchFallThroughTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java index 933231b1bc..091595c70e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java @@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; import net.sourceforge.pmd.test.PmdRuleTst; -class InvalidLogMessageFormatTest extends PmdRuleTst { +public class InvalidLogMessageFormatTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml index 0d36b80ef7..5893fc117f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml @@ -1199,11 +1199,12 @@ public class Foo { Definitions in try block reach catch blocks through method calls - 2 - 4,7 + 1 + 4 The initializer for variable 'halfway' is never used (overwritten on line 7) - The value assigned to variable 'halfway' is never used + + Definitions in try block reach catch blocks through method calls 3 - 1 - 8 - - The value assigned to variable 'halfway' is never used - + + 0 + + + + + 5,7,9 The initializer for variable 'a' is never used (overwritten on lines 7, 9 and 11) - The value assigned to variable 'a' is never used (overwritten on line 11) + The value assigned to variable 'a' is never used (overwritten on lines 9 and 11) The value assigned to variable 'a' is never used (overwritten on line 11) + + + [java] LocalVariableCouldBeFinal false positive with try/catch #5046 + 0 + createFileWatcher() { + Optional optionalFileWatcher; // false positive in PMD 7.2.0, cannot be final + try { + optionalFileWatcher = Optional.of(new FileWatcher()); + } catch (final IOException e) { + optionalFileWatcher = Optional.empty(); + } + return optionalFileWatcher; + } + } ]]>