From 01de9ce450be11404b474f4b0bd7bcedef825cde Mon Sep 17 00:00:00 2001 From: XenoAmess Date: Mon, 24 Aug 2020 19:15:52 +0800 Subject: [PATCH 01/18] add github actions for a fast view of pr succeed/not. travis-ci is toooo slow. --- .github/dependabot.yml | 12 ++++++++++++ .github/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..0df1a8b49a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "daily" + target-branch: "master" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "master" + target-branch: "develop" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..7cd1b5799a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: Java CI + +on: [ push ] + +jobs: + build: + runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} + strategy: + matrix: + os: [ ubuntu-latest , windows-latest , macos-latest ] + java: [ 11 ] + experimental: [ false ] + + steps: + - uses: actions/checkout@v2.3.2 + - uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v1.4.0 + with: + java-version: ${{ matrix.java }} + - name: Build with mvnw + run: | + chmod 777 ./mvnw + ./mvnw clean install From fde23333a0eaa89c05408aa17399889dca46d670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 25 Aug 2020 16:25:01 +0200 Subject: [PATCH 02/18] Deprecate ruleviolation comparator --- .../src/main/java/net/sourceforge/pmd/Report.java | 6 +++--- .../main/java/net/sourceforge/pmd/RuleViolation.java | 10 ++++++++++ .../net/sourceforge/pmd/RuleViolationComparator.java | 12 ++++++++++++ .../sourceforge/pmd/RuleViolationComparatorTest.java | 2 +- .../java/net/sourceforge/pmd/RuleViolationTest.java | 7 ++++--- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/Report.java b/pmd-core/src/main/java/net/sourceforge/pmd/Report.java index 3d6cd2d45d..f0a75a7028 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/Report.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/Report.java @@ -345,7 +345,7 @@ public class Report implements Iterable { return; } - int index = Collections.binarySearch(violations, violation, RuleViolationComparator.INSTANCE); + int index = Collections.binarySearch(violations, violation, RuleViolation.DEFAULT_COMPARATOR); violations.add(index < 0 ? -index - 1 : index, violation); violationTree.addRuleViolation(violation); for (ThreadSafeReportListener listener : listeners) { @@ -405,7 +405,7 @@ public class Report implements Iterable { suppressedRuleViolations.addAll(r.suppressedRuleViolations); for (RuleViolation violation : r.getViolations()) { - int index = Collections.binarySearch(violations, violation, RuleViolationComparator.INSTANCE); + int index = Collections.binarySearch(violations, violation, RuleViolation.DEFAULT_COMPARATOR); violations.add(index < 0 ? -index - 1 : index, violation); violationTree.addRuleViolation(violation); } @@ -519,7 +519,7 @@ public class Report implements Iterable { * Returns an unmodifiable list of violations that have been * recorded until now. None of those violations were suppressed. * - *

The violations list is sorted with {@link RuleViolationComparator#INSTANCE}. + *

The violations list is sorted with {@link RuleViolation#DEFAULT_COMPARATOR}. */ public final List getViolations() { return Collections.unmodifiableList(violations); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolation.java index 5873d6e4db..b8359f6a7c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolation.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolation.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd; +import java.util.Comparator; + /** * A RuleViolation is created by a Rule when it identifies a violation of the * Rule constraints. RuleViolations are simple data holders that are collected @@ -16,6 +18,14 @@ package net.sourceforge.pmd; */ public interface RuleViolation { + /** + * A comparator for rule violations. This compares all exposed attributes + * of a violation, filename first. The remaining parameters are compared + * in an unspecified order. + */ + // TODO in java 8 this can be a chained Comparator.comparing call + Comparator DEFAULT_COMPARATOR = RuleViolationComparator.INSTANCE; + /** * Get the Rule which identified this violation. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolationComparator.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolationComparator.java index bbfa48ed07..bc1b1adf39 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolationComparator.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleViolationComparator.java @@ -17,7 +17,19 @@ import java.util.Comparator; *

  • End column
  • *
  • Rule name
  • * + * + * TODO why is begin line/begin column split?? would make more sense to use + * - filename + * - begin line + * - begin column + * - description + * - rule name + * - end line + * - end column + * + * @deprecated Use {@link RuleViolation#DEFAULT_COMPARATOR} */ +@Deprecated public final class RuleViolationComparator implements Comparator { public static final RuleViolationComparator INSTANCE = new RuleViolationComparator(); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java index e0643c0e01..c1f74cdf66 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationComparatorTest.java @@ -58,7 +58,7 @@ public class RuleViolationComparatorTest { Collections.shuffle(ruleViolations, random); // Sort - Collections.sort(ruleViolations, RuleViolationComparator.INSTANCE); + Collections.sort(ruleViolations, RuleViolation.DEFAULT_COMPARATOR); // Check int count = 0; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java index 9fd8554203..c6125da54c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleViolationTest.java @@ -8,6 +8,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; +import java.util.Comparator; import org.junit.Ignore; import org.junit.Test; @@ -53,7 +54,7 @@ public class RuleViolationTest { @Test public void testComparatorWithDifferentFilenames() { Rule rule = new MockRule("name", "desc", "msg", "rulesetname"); - RuleViolationComparator comp = RuleViolationComparator.INSTANCE; + Comparator comp = RuleViolation.DEFAULT_COMPARATOR; RuleContext ctx = new RuleContext(); ctx.setSourceCodeFile(new File("filename1")); DummyNode s = new DummyNode(1); @@ -72,7 +73,7 @@ public class RuleViolationTest { @Test public void testComparatorWithSameFileDifferentLines() { Rule rule = new MockRule("name", "desc", "msg", "rulesetname"); - RuleViolationComparator comp = RuleViolationComparator.INSTANCE; + Comparator comp = RuleViolation.DEFAULT_COMPARATOR; RuleContext ctx = new RuleContext(); ctx.setSourceCodeFile(new File("filename")); DummyNode s = new DummyNode(1); @@ -91,7 +92,7 @@ public class RuleViolationTest { @Test public void testComparatorWithSameFileSameLines() { Rule rule = new MockRule("name", "desc", "msg", "rulesetname"); - RuleViolationComparator comp = RuleViolationComparator.INSTANCE; + Comparator comp = RuleViolation.DEFAULT_COMPARATOR; RuleContext ctx = new RuleContext(); ctx.setSourceCodeFile(new File("filename")); DummyNode s = new DummyNode(1); From 31b75d3acbf872dcc04964e4d5b3dafd3c0903b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 25 Aug 2020 16:48:16 +0200 Subject: [PATCH 03/18] Update release notes --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index cc0ca22491..089377fc94 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -120,6 +120,7 @@ For the changes, see [PMD Designer Changelog](https://github.com/pmd/pmd-designe ##### For removal +* {% jdoc !!core::RuleViolationComparator %} * {% jdoc !!core::Rule#getParserOptions() %} * {% jdoc !!core::lang.Parser#getParserOptions() %} * {% jdoc core::lang.AbstractParser %} From 3a33092d22e8b76cb3d9315ac6627a2689b71015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 2 Sep 2020 16:45:19 +0200 Subject: [PATCH 04/18] Add test case --- .../bestpractices/xml/UnusedAssignment.xml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) 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 1f0d55cebc..c05ad0a40a 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 @@ -3159,4 +3159,29 @@ public class UnusedAssignmentNative { ]]> + + False positive with try in loop? #2759 + 0 + 0) { + a--; + try { + if (dummy) { + return somethingThatCanThrowRandomly(1); + } else { + return somethingThatCanThrowRandomly(2); + } + } catch (RuntimeException e) { + // retry + } + } + return 0; + } + } + ]]> + + From b0f924495b3d5a5ca5a46849cd238ab68f761558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 3 Sep 2020 12:10:26 +0200 Subject: [PATCH 05/18] Fix bug Problem was, isInTryBlock didn't ask for parent states, even though abruptCompletionByThrow does. --- .../rule/bestpractices/UnusedAssignmentRule.java | 12 +----------- .../java/rule/bestpractices/xml/UnusedAssignment.xml | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentRule.java index dad2aa5563..36713aa632 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedAssignmentRule.java @@ -895,11 +895,6 @@ public class UnusedAssignmentRule extends AbstractJavaRule { // For the record this has problems with call chains with side effects, like // a.foo(a = 2).bar(a = 3); - if (!state.isInTryBlock()) { - return; - } - // otherwise any method/ctor call may throw - // In 7.0, with the precise type/overload resolution, we // could only target methods that throw checked exceptions // (unless some catch block catches an unchecked exceptions) @@ -907,7 +902,7 @@ public class UnusedAssignmentRule extends AbstractJavaRule { if (child instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) child).isArguments() || child instanceof ASTPrimarySuffix && child.getNumChildren() > 0 && child.getChild(0) instanceof ASTAllocationExpression || child instanceof ASTPrimaryPrefix && child.getNumChildren() > 0 && child.getChild(0) instanceof ASTAllocationExpression) { - state.abruptCompletionByThrow(true); + state.abruptCompletionByThrow(true); // this is a noop if we're outside a try block that has catch/finally } } } @@ -1385,11 +1380,6 @@ public class UnusedAssignmentRule extends AbstractJavaRule { return this; } - private boolean isInTryBlock() { - // ignore resources, once they're initialized everything's fine in the block - return !myCatches.isEmpty() || myFinally != null; - } - SpanInfo absorb(SpanInfo other) { // Merge reaching defs of the other scope into this // This is used to join paths after the control flow has forked 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 c05ad0a40a..0dd7179c5e 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 @@ -3160,7 +3160,7 @@ public class UnusedAssignmentNative { - False positive with try in loop? #2759 + False positive with method that may throw in forked state (the if state) #2759 0 Date: Thu, 10 Sep 2020 12:24:03 +0200 Subject: [PATCH 06/18] Fix #2767 Problem was the stack is empty if the local var declaration is the first node of the compilation unit to be pushed. --- pmd-java/etc/grammar/Java.jjt | 6 ++++-- .../pmd/lang/java/ast/ParserCornersTest.java | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index cafd023dcf..0962322888 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1997,8 +1997,10 @@ void BlockStatement(): | { List annotationsAndChildren = new ArrayList(); - while (jjtree.peekNode() instanceof ASTAnnotation) { - annotationsAndChildren.add(jjtree.popNode()); + if (jjtree.nodeArity() > 0) { // peekNode would throw if the stack is empty + while (jjtree.peekNode() instanceof ASTAnnotation) { + annotationsAndChildren.add(jjtree.popNode()); + } } } LocalVariableDeclaration() diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index 83501273fd..4af25e38db 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -177,6 +177,16 @@ public class ParserCornersTest { java8.parseResource("GitHubBug207.java"); } + @Test + public void testGitHubBug2767() { + // PMD fails to parse an initializer block. + // PMD 6.26.0 parses this code just fine. + java.withDefaultVersion("15-preview") + .parse("class Foo {\n" + + " {final int I;}\n" + + "}\n"); + } + @Test public void testBug206() { java8.parse("public @interface Foo {" + "\n" From 46933e666d3caf5fe5a0b5c03801ac91fcf636c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 10 Sep 2020 12:39:32 +0200 Subject: [PATCH 07/18] Fix #2756, NPE in TypeTestUtil --- .../pmd/lang/java/types/TypeTestUtil.java | 16 +++++++++-- .../pmd/lang/java/types/TypeTestUtilTest.java | 28 +++++++++++++++++++ .../types/testdata/SomeClassWithAnon.java | 25 +++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/testdata/SomeClassWithAnon.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java index 873697e422..a2d187c631 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java @@ -106,7 +106,11 @@ public final class TypeTestUtil { final Class clazz = loadClassWithNodeClassloader(node, canonicalName); + if (clazz != null) { + if (clazz.getCanonicalName() == null) { + return false; // no canonical name, give up: we shouldn't be able to access them + } return clazz.isAssignableFrom(nodeType); } else { return fallbackIsA(node, canonicalName, true); @@ -174,8 +178,16 @@ public final class TypeTestUtil { } - return node.getType() == null ? fallbackIsA(node, canonicalName, false) - : node.getType().getCanonicalName().equals(canonicalName); + if (node.getType() == null) { + return fallbackIsA(node, canonicalName, false); + } + + String canoname = node.getType().getCanonicalName(); + if (canoname == null) { + // anonymous/local class, or class nested within one of those + return false; + } + return canoname.equals(canonicalName); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java index a04149a88c..d672afc702 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java @@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.java.types; import java.io.Serializable; import java.lang.annotation.Annotation; +import java.util.concurrent.Callable; import org.junit.Assert; import org.junit.Rule; @@ -13,6 +14,7 @@ import org.junit.Test; import org.junit.function.ThrowingRunnable; import org.junit.rules.ExpectedException; +import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression; import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration; @@ -20,6 +22,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.java.symboltable.BaseNonParserTest; +import net.sourceforge.pmd.lang.java.types.testdata.SomeClassWithAnon; public class TypeTestUtilTest extends BaseNonParserTest { @@ -74,6 +77,31 @@ public class TypeTestUtilTest extends BaseNonParserTest { assertIsA(klass, Object.class); } + @Test + public void testAnonClassTypeNPE() { + // #2756 + + ASTAllocationExpression anon = + java.parseClass(SomeClassWithAnon.class) + .getFirstDescendantOfType(ASTAllocationExpression.class); + + + Assert.assertNotNull("Type should be resolved", anon.getType()); + Assert.assertTrue("Anon class", anon.isAnonymousClass()); + Assert.assertTrue("Anon class", anon.getType().isAnonymousClass()); + Assert.assertTrue("Should be a Runnable", TypeTestUtil.isA(Runnable.class, anon)); + + // This is not a canonical name, so we give up early + Assert.assertFalse(TypeTestUtil.isA(SomeClassWithAnon.class.getName() + "$1", anon)); + Assert.assertFalse(TypeTestUtil.isExactlyA(SomeClassWithAnon.class.getName() + "$1", anon)); + + // this is the failure case: if the binary name doesn't match, we test the canoname, which was null + Assert.assertFalse(TypeTestUtil.isA(Callable.class, anon)); + Assert.assertFalse(TypeTestUtil.isA(Callable.class.getCanonicalName(), anon)); + Assert.assertFalse(TypeTestUtil.isExactlyA(Callable.class, anon)); + Assert.assertFalse(TypeTestUtil.isExactlyA(Callable.class.getCanonicalName(), anon)); + } + /** * If we don't have the annotation on the classpath, * we should resolve the full name via the import, if possible diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/testdata/SomeClassWithAnon.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/testdata/SomeClassWithAnon.java new file mode 100644 index 0000000000..09d2467f25 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/testdata/SomeClassWithAnon.java @@ -0,0 +1,25 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.types.testdata; + +/** + * #2756 + */ +public class SomeClassWithAnon { + + { + new Runnable() { + + @Override + public void run() { + + } + }; + + + } + + +} From fedea535b5ace867a413ef98ec6c0d2499bb9507 Mon Sep 17 00:00:00 2001 From: Nimit Date: Thu, 10 Sep 2020 19:19:43 -0700 Subject: [PATCH 08/18] issue-2738: Adding null check to avoid npe when switch case is default --- .../sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java index 94cbefb259..6a019966d9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java @@ -86,7 +86,10 @@ public class ASTSwitchStatement extends AbstractJavaNode implements Iterable Date: Fri, 11 Sep 2020 16:59:16 +0200 Subject: [PATCH 09/18] [java] Add test case for #2738 --- .../lang/java/ast/ASTSwitchStatementTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatementTest.java diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatementTest.java new file mode 100644 index 0000000000..5915a67c3d --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatementTest.java @@ -0,0 +1,21 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import org.junit.Assert; +import org.junit.Test; + +public class ASTSwitchStatementTest extends BaseParserTest { + + @Test + public void exhaustiveEnumSwitchWithDefault() { + ASTSwitchStatement switchStatement = getNodes(ASTSwitchStatement.class, + "import java.nio.file.AccessMode; class Foo { void bar(AccessMode m) {" + + "switch (m) { case READ: break; default: break; } } }") + .get(0); + Assert.assertFalse(switchStatement.isExhaustiveEnumSwitch()); // this should not throw a NPE... + Assert.assertTrue(switchStatement.hasDefaultCase()); + } +} From 7cea1d684cd17358f9ad006a3b3a708713085e80 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Sep 2020 17:02:40 +0200 Subject: [PATCH 10/18] [doc] Update release notes, fixes #2738, refs #2773 --- docs/pages/release_notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3910997c70..184a814521 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,7 +17,8 @@ This is a {{ site.pmd.release_type }} release. ### Fixed Issues * pmd-java - * [#2708](https://github.com/pmd/pmd/pull/2708): \[java] False positive FinalFieldCouldBeStatic when using lombok Builder.Default + * [#2708](https://github.com/pmd/pmd/issues/2708): \[java] False positive FinalFieldCouldBeStatic when using lombok Builder.Default + * [#2738](https://github.com/pmd/pmd/issues/2738): \[java] Custom rule with @ExhaustiveEnumSwitch throws NPE ### API Changes @@ -25,6 +26,7 @@ This is a {{ site.pmd.release_type }} release. ### External Contributions * [#2747](https://github.com/pmd/pmd/pull/2747): \[java] Don't trigger FinalFieldCouldBeStatic when field is annotated with lombok @Builder.Default - [Ollie Abbey](https://github.com/ollieabbey) +* [#2773](https://github.com/pmd/pmd/pull/2773): \[java] issue-2738: Adding null check to avoid npe when switch case is default - [Nimit Patel](https://github.com/nimit-patel) {% endtocmaker %} From 4f53b770458c55dc1c3b57a89cac99d18b1be33a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Sep 2020 17:40:04 +0200 Subject: [PATCH 11/18] [doc] Update release notes, fixes #2756 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3910997c70..b2dceefa1b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -18,6 +18,7 @@ This is a {{ site.pmd.release_type }} release. * pmd-java * [#2708](https://github.com/pmd/pmd/pull/2708): \[java] False positive FinalFieldCouldBeStatic when using lombok Builder.Default + * [#2756](https://github.com/pmd/pmd/issues/2756): \[java] TypeTestUtil fails with NPE for anonymous class ### API Changes From a13f88de5f6ffb0a05d74d41353e53f6f2568c64 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Sep 2020 17:51:36 +0200 Subject: [PATCH 12/18] [doc] Update release notes, fixes #2767 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3910997c70..f7b5ffba44 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -18,6 +18,7 @@ This is a {{ site.pmd.release_type }} release. * pmd-java * [#2708](https://github.com/pmd/pmd/pull/2708): \[java] False positive FinalFieldCouldBeStatic when using lombok Builder.Default + * [#2767](https://github.com/pmd/pmd/issues/2767): \[java] IndexOutOfBoundsException when parsing an initializer BlockStatement ### API Changes From 20d48caa6545dcce68e821de7b3f465a75f5f340 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Sep 2020 11:36:20 +0200 Subject: [PATCH 13/18] [doc] Update release notes, fixes #2759 --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b8f8783555..15b3b605ec 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release. ### Fixed Issues +* pmd-java + * [#2759](https://github.com/pmd/pmd/issues/2759): \[java] False positive in UnusedAssignment + ### API Changes ### External Contributions From d03960574721dac667da1adfb940b583638ddec8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Sep 2020 11:51:11 +0200 Subject: [PATCH 14/18] [doc] Mention replacement for deprecated RuleViolationComparator --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 708c858408..14e1adb41d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,7 +22,7 @@ This is a {{ site.pmd.release_type }} release. ##### For removal -* {% jdoc !!core::RuleViolationComparator %} +* {% jdoc !!core::RuleViolationComparator %}. Use {% jdoc !!core::RuleViolation#DEFAULT_COMPARATOR %} instead. ### External Contributions From 2093f6c82a8f60d5e9ebc453ea77e8530d2badd4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Sep 2020 12:13:04 +0200 Subject: [PATCH 15/18] [ci] dependabot: don't open PRs for maven dependencies We might enable this for PMD 7 later --- .github/dependabot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0df1a8b49a..b11b4799b5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,7 @@ updates: schedule: interval: "daily" target-branch: "master" + open-pull-requests-limit: 0 - package-ecosystem: "github-actions" directory: "/" schedule: From b247d616d971178ecf9d528309959db329a68652 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Sep 2020 12:13:28 +0200 Subject: [PATCH 16/18] [ci] github actions: Build on push and pull requests --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7cd1b5799a..c4c6346b0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ name: Java CI -on: [ push ] +on: [push, pull_request] jobs: build: @@ -26,5 +26,4 @@ jobs: java-version: ${{ matrix.java }} - name: Build with mvnw run: | - chmod 777 ./mvnw ./mvnw clean install From c3b5e1a5c1c79b66f3c7e85ff4ac34a0efce0138 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Sep 2020 12:13:44 +0200 Subject: [PATCH 17/18] [doc] Update release notes, refs #2735 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 472047cab8..9b277d38cb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -176,6 +176,7 @@ are deprecated as internal API. * [#2699](https://github.com/pmd/pmd/pull/2699): \[java] ProperCloneImplementation not valid for final class - [Mykhailo Palahuta](https://github.com/Drofff) * [#2700](https://github.com/pmd/pmd/pull/2700): \[java] Fix OnlyOneReturn code example - [Jan-Lukas Else](https://github.com/jlelse) * [#2722](https://github.com/pmd/pmd/pull/2722): \[doc] \[java] ImmutableField: extend description, fixes #2108 - [Mateusz Stefanski](https://github.com/mateusz-stefanski) +* [#2735](https://github.com/pmd/pmd/pull/2735): \[ci] Add github actions for a fast view of pr succeed/not - [XenoAmess](https://github.com/XenoAmess) {% endtocmaker %} From 352760c09c5f4fe56d2d4dfcc714faf744fc3c8b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Sep 2020 12:45:52 +0200 Subject: [PATCH 18/18] [ci] Fix dependabot schedule interval --- .github/dependabot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b11b4799b5..d674a5bc29 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,11 +3,11 @@ updates: - package-ecosystem: "maven" directory: "/" schedule: - interval: "daily" + interval: "weekly" target-branch: "master" open-pull-requests-limit: 0 - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "master" - target-branch: "develop" + interval: "weekly" + target-branch: "master"