forked from phoedos/pmd
Merge branch 'master' into issue-4928-emptycatchblock
This commit is contained in:
@ -21,6 +21,8 @@ This is a {{ site.pmd.release_type }} release.
|
||||
methods should be considered as valid verification methods. This allows to use custom mocking or assertion libraries.
|
||||
|
||||
### 🐛 Fixed Issues
|
||||
* core
|
||||
* [#494](https://github.com/pmd/pmd/issues/494): \[core] Adopt JApiCmp to enforce control over API changes
|
||||
* cli
|
||||
* [#4791](https://github.com/pmd/pmd/issues/4791): \[cli] Could not find or load main class
|
||||
* apex-errorprone
|
||||
@ -36,6 +38,7 @@ This is a {{ site.pmd.release_type }} release.
|
||||
* [#3694](https://github.com/pmd/pmd/issues/3694): \[java] SingularField ignores static variables
|
||||
* [#4873](https://github.com/pmd/pmd/issues/4873): \[java] AvoidCatchingGenericException: Can no longer suppress on the exception itself
|
||||
* java-errorprone
|
||||
* [#2056](https://github.com/pmd/pmd/issues/2056): \[java] CloseResource false-positive with URLClassLoader in cast expression
|
||||
* [#4928](https://github.com/pmd/pmd/issues/4928): \[java] EmptyCatchBlock false negative when allowCommentedBlocks=true
|
||||
* java-performance
|
||||
* [#3845](https://github.com/pmd/pmd/issues/3845): \[java] InsufficientStringBufferDeclaration should consider literal expression
|
||||
@ -46,6 +49,11 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### 🚨 API Changes
|
||||
|
||||
#### Deprecated methods
|
||||
|
||||
* {%jdoc java::lang.java.rule.design.SingularFieldRule#mayBeSingular(java::lang.java.ast.ModifierOwner) %} has been deprecated for
|
||||
removal. The method is only useful for the rule itself and shouldn't be used otherwise.
|
||||
|
||||
### ✨ External Contributions
|
||||
* [#4864](https://github.com/pmd/pmd/pull/4864): Fix #1084 \[Java] add extra assert method names to Junit rules - [Erwan Moutymbo](https://github.com/emouty) (@emouty)
|
||||
* [#4894](https://github.com/pmd/pmd/pull/4894): Fix #4791 Error caused by space in JDK path - [Scrates1](https://github.com/Scrates1) (@Scrates1)
|
||||
|
@ -30,6 +30,18 @@
|
||||
</offlineLinks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.ant.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -55,6 +55,20 @@
|
||||
<groupId>org.jetbrains.dokka</groupId>
|
||||
<artifactId>dokka-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.apex.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.apex.metrics.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.apex.rule.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -20,6 +20,21 @@
|
||||
<suppressionsLocation>pmd-cli-checkstyle-suppressions.xml</suppressionsLocation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.cli.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.cli.commands.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.cli.commands.mixins.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.cli.commands.typesupport.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -76,6 +76,26 @@
|
||||
<offlineLinks combine.self="override"></offlineLinks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.cache.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.cpd.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.ast.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.rule.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.rule.xpath.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.properties.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.renderers.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.util.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -16,6 +16,22 @@
|
||||
<java.version>8</java.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.doc.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>generate-rule-docs</id>
|
||||
|
@ -122,6 +122,26 @@
|
||||
<suppressionsLocation>pmd-java-checkstyle-suppressions.xml</suppressionsLocation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.java.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.ast.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.metrics.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.rule.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.rule.xpath.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.symbols.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.symbols.table.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.types.internal</exclude>
|
||||
<exclude>net.sourceforge.pmd.lang.java.types.ast.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast.internal;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity;
|
||||
import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.needsParentheses;
|
||||
import static net.sourceforge.pmd.util.AssertionUtil.shouldNotReachHere;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@ -18,6 +20,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
|
||||
@ -28,13 +31,15 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTIntersectionType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaParameterList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
|
||||
@ -45,6 +50,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTTypeArguments;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTUnionType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableId;
|
||||
@ -337,6 +343,76 @@ public final class PrettyPrintingUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTInfixExpression node, StringBuilder sb) {
|
||||
printWithParensIfNecessary(node.getLeftOperand(), sb, node);
|
||||
sb.append(' ');
|
||||
sb.append(node.getOperator());
|
||||
sb.append(' ');
|
||||
printWithParensIfNecessary(node.getRightOperand(), sb, node);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Void visit(ASTUnaryExpression node, StringBuilder sb) {
|
||||
sb.append(node.getOperator());
|
||||
printWithParensIfNecessary(node.getOperand(), sb, node);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void printWithParensIfNecessary(ASTExpression operand, StringBuilder sb, ASTExpression parent) {
|
||||
if (operand.isParenthesized() && needsParentheses(operand, parent) != Necessity.NEVER) {
|
||||
ppInParens(sb, operand);
|
||||
} else {
|
||||
operand.acceptVisitor(this, sb);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTConditionalExpression node, StringBuilder sb) {
|
||||
printWithParensIfNecessary(node.getCondition(), sb, node);
|
||||
sb.append(" ? ");
|
||||
printWithParensIfNecessary(node.getThenBranch(), sb, node);
|
||||
sb.append(" : ");
|
||||
printWithParensIfNecessary(node.getElseBranch(), sb, node);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTLambdaExpression node, StringBuilder sb) {
|
||||
node.getParameters().acceptVisitor(this, sb);
|
||||
sb.append(" -> ");
|
||||
ASTExpression exprBody = node.getExpression();
|
||||
if (exprBody != null) {
|
||||
exprBody.acceptVisitor(this, sb);
|
||||
} else {
|
||||
sb.append("{ ... }");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTLambdaParameterList node, StringBuilder sb) {
|
||||
if (node.size() == 1) {
|
||||
sb.append(node.get(0).getVarId().getName());
|
||||
return null;
|
||||
} else if (node.isEmpty()) {
|
||||
sb.append("()");
|
||||
return null;
|
||||
}
|
||||
|
||||
sb.append('(');
|
||||
sb.append(node.get(0).getVarId().getName());
|
||||
node.toStream().drop(1).forEach(it -> {
|
||||
sb.append(", ");
|
||||
sb.append(it.getVarId().getName());
|
||||
});
|
||||
sb.append(')');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTMethodCall node, StringBuilder sb) {
|
||||
addQualifier(node, sb);
|
||||
@ -379,26 +455,17 @@ public final class PrettyPrintingUtil {
|
||||
|
||||
@Override
|
||||
public Void visit(ASTMethodReference node, StringBuilder sb) {
|
||||
ppMaybeInParens(sb, node.getQualifier());
|
||||
printWithParensIfNecessary(node.getQualifier(), sb, node);
|
||||
sb.append("::");
|
||||
ppTypeArgs(sb, node.getExplicitTypeArguments());
|
||||
sb.append(node.getMethodName());
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ppMaybeInParens(StringBuilder sb, ASTExpression qualifier) {
|
||||
if (!(qualifier instanceof ASTPrimaryExpression)) {
|
||||
ppInParens(sb, qualifier);
|
||||
} else {
|
||||
qualifier.acceptVisitor(this, sb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addQualifier(QualifiableExpression node, StringBuilder data) {
|
||||
ASTExpression qualifier = node.getQualifier();
|
||||
if (qualifier != null) {
|
||||
ppMaybeInParens(data, qualifier);
|
||||
printWithParensIfNecessary(qualifier, data, node);
|
||||
data.append('.');
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ public final class UselessParenthesesRule extends AbstractJavaRulechainRule {
|
||||
}
|
||||
|
||||
|
||||
static Necessity needsParentheses(ASTExpression inner, JavaNode outer) {
|
||||
public static Necessity needsParentheses(ASTExpression inner, JavaNode outer) {
|
||||
// Note: as of jdk 15, PatternExpression cannot be parenthesized
|
||||
// TypeExpression may never be parenthesized either
|
||||
assert inner.isParenthesized() : inner + " is not parenthesized";
|
||||
@ -265,7 +265,7 @@ public final class UselessParenthesesRule extends AbstractJavaRulechainRule {
|
||||
}
|
||||
}
|
||||
|
||||
enum Necessity {
|
||||
public enum Necessity {
|
||||
ALWAYS,
|
||||
NEVER,
|
||||
CLARIFYING,
|
||||
|
@ -79,7 +79,7 @@ public class SingularFieldRule extends AbstractJavaRulechainRule {
|
||||
|
||||
DataflowResult dataflow = null;
|
||||
for (ASTFieldDeclaration fieldDecl : enclosingType.getDeclarations(ASTFieldDeclaration.class)) {
|
||||
if (!mayBeSingular(fieldDecl)
|
||||
if (!isPrivateNotFinal(fieldDecl)
|
||||
|| JavaAstUtils.hasAnyAnnotation(fieldDecl, getProperty(IGNORED_FIELD_ANNOTATIONS))) {
|
||||
continue;
|
||||
}
|
||||
@ -95,13 +95,23 @@ public class SingularFieldRule extends AbstractJavaRulechainRule {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean mayBeSingular(ModifierOwner varId) {
|
||||
/**
|
||||
* This method is only relevant for this rule. It will be removed in the future.
|
||||
*
|
||||
* @deprecated This method will be removed. Don't use it.
|
||||
*/
|
||||
@Deprecated //(since = "7.1.0", forRemoval = true)
|
||||
public static boolean mayBeSingular(ModifierOwner varId) {
|
||||
return isPrivateNotFinal(varId);
|
||||
}
|
||||
|
||||
private static boolean isPrivateNotFinal(ModifierOwner varId) {
|
||||
return varId.getEffectiveVisibility().isAtMost(Visibility.V_PRIVATE)
|
||||
// We ignore final variables for a reason:
|
||||
// - if they're static they are there to share a value and that is not a mistake
|
||||
// - if they're not static then if this rule matches, then so does FinalFieldCouldBeStatic,
|
||||
// and that rule has the better fix.
|
||||
&& !varId.hasModifiers(JModifier.FINAL);
|
||||
// We ignore final variables for a reason:
|
||||
// - if they're static they are there to share a value and that is not a mistake
|
||||
// - if they're not static then if this rule matches, then so does FinalFieldCouldBeStatic,
|
||||
// and that rule has the better fix.
|
||||
&& !varId.hasModifiers(JModifier.FINAL);
|
||||
}
|
||||
|
||||
private boolean isSingularField(ASTTypeDeclaration fieldOwner, ASTVariableId varId, DataflowResult dataflow) {
|
||||
|
@ -20,6 +20,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTBlock;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration;
|
||||
@ -340,8 +341,13 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
if (wrappedVarName != null) {
|
||||
ASTFormalParameters methodParams = method.getFormalParameters();
|
||||
for (ASTFormalParameter param : methodParams) {
|
||||
if ((isResourceTypeOrSubtype(param) || wrappedVarName.getParent() instanceof ASTVariableDeclarator
|
||||
|| wrappedVarName.getParent() instanceof ASTAssignmentExpression)
|
||||
// get the parent node where it's used (no casts)
|
||||
Node parentUse = wrappedVarName.getParent();
|
||||
if (parentUse instanceof ASTCastExpression) {
|
||||
parentUse = parentUse.getParent();
|
||||
}
|
||||
if ((isResourceTypeOrSubtype(param) || parentUse instanceof ASTVariableDeclarator
|
||||
|| parentUse instanceof ASTAssignmentExpression)
|
||||
&& JavaAstUtils.isReferenceToVar(wrappedVarName, param.getVarId().getSymbol())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -19,10 +19,15 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.BaseParserTest;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
|
||||
import net.sourceforge.pmd.util.StringUtil;
|
||||
|
||||
class PrettyPrintingUtilTest extends BaseParserTest {
|
||||
@ -47,42 +52,73 @@ class PrettyPrintingUtilTest extends BaseParserTest {
|
||||
|
||||
@Test
|
||||
void ppMethodCallArgsTooBig() {
|
||||
ASTCompilationUnit root = java.parse("class A { { this.foo(\"a long string\", 12, 12, 12, 12, 12); } }");
|
||||
@NonNull ASTMethodCall m = root.descendants(ASTMethodCall.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("this.foo(\"a long string\", 12...)"));
|
||||
testPrettyPrint("this.foo(\"a long string\", 12, 12, 12, 12, 12)",
|
||||
ASTMethodCall.class, "this.foo(\"a long string\", 12...)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppMethodCallOnCast() {
|
||||
ASTCompilationUnit root = java.parse("class A { { ((Object) this).foo(12); } }");
|
||||
@NonNull ASTMethodCall m = root.descendants(ASTMethodCall.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("((Object) this).foo(12)"));
|
||||
testPrettyPrintIdentity("((Object) this).foo(12)", ASTMethodCall.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppMethodRef() {
|
||||
ASTCompilationUnit root = java.parse("class A { { foo(ASTW::meth); } }");
|
||||
@NonNull ASTMethodReference m = root.descendants(ASTMethodReference.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("ASTW::meth"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppCtorCall() {
|
||||
ASTCompilationUnit root = java.parse("class A { { new Foo(1); } }");
|
||||
@NonNull ASTConstructorCall m = root.descendants(ASTConstructorCall.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("new Foo(1)"));
|
||||
testPrettyPrintIdentity("ASTW::meth", ASTMethodReference.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppMethodRefWithTyArgs() {
|
||||
ASTCompilationUnit root = java.parse("class A { { foo(ASTW::<String>meth); } }");
|
||||
@NonNull ASTMethodReference m = root.descendants(ASTMethodReference.class).firstOrThrow();
|
||||
testPrettyPrint("foo(ASTW::<String>meth)", ASTMethodReference.class,
|
||||
"ASTW::<String>meth");
|
||||
}
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("ASTW::<String>meth"));
|
||||
@Test
|
||||
void ppCtorCall() {
|
||||
testPrettyPrintIdentity("new Foo(1)", ASTConstructorCall.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppUnary() {
|
||||
testPrettyPrintIdentity("-+4", ASTUnaryExpression.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void ppConditional() {
|
||||
testPrettyPrintIdentity("true ? false : 1", ASTConditionalExpression.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppInfix() {
|
||||
// note: removes unnecessary parens
|
||||
testPrettyPrint("(1+2)+2", ASTInfixExpression.class, "1 + 2 + 2");
|
||||
testPrettyPrint("(1+2)*2", ASTInfixExpression.class, "(1 + 2) * 2");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
void ppLambdaExpr() {
|
||||
testPrettyPrintIdentity("(a, b) -> new Foo()", ASTLambdaExpression.class);
|
||||
testPrettyPrintIdentity("() -> new Foo()", ASTLambdaExpression.class);
|
||||
testPrettyPrintIdentity("x -> new Foo()", ASTLambdaExpression.class);
|
||||
testPrettyPrint("(x) -> new Foo()", ASTLambdaExpression.class, "x -> new Foo()");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppLambdaBlock() {
|
||||
testPrettyPrint("(a, b) -> {return new Foo(); }", ASTLambdaExpression.class,
|
||||
"(a, b) -> { ... }");
|
||||
}
|
||||
|
||||
private <T extends ASTExpression> void testPrettyPrint(String expr, Class<T> nodeTy, String expected) {
|
||||
ASTCompilationUnit root = java.parse("class A { { Object x = " + expr + "; } }");
|
||||
@NonNull T node = root.descendants(nodeTy).firstOrThrow();
|
||||
assertThat(prettyPrint(node), contentEquals(expected));
|
||||
}
|
||||
|
||||
private <T extends ASTExpression> void testPrettyPrintIdentity(String expr, Class<T> nodeTy) {
|
||||
testPrettyPrint(expr, nodeTy, expr);
|
||||
}
|
||||
|
||||
private static Matcher<CharSequence> contentEquals(String str) {
|
||||
|
@ -2026,6 +2026,24 @@ public class LocalVariableTypeInference {
|
||||
var list = new ArrayList<String>(); // infers ArrayList<String>
|
||||
var stream = list.stream(); // infers Stream<String>, is never closed
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Parameters don't need to be closed even if casted #2056</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class CastedParameter {
|
||||
|
||||
public void checkValidity(ClassLoader auxclassPathClassLoader) {
|
||||
if (auxclassPathClassLoader instanceof URLClassLoader) {
|
||||
final URLClassLoader urlClassLoader = (URLClassLoader) auxclassPathClassLoader;
|
||||
// doesn't need to be closed, it's still a paramter…
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
@ -63,6 +63,18 @@
|
||||
</delimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.kotlin.rule.xpath.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -76,6 +76,18 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.modelica.resolver.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -79,6 +79,18 @@
|
||||
<suppressionsLocation>pmd-plsql-checkstyle-suppressions.xml</suppressionsLocation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.plsql.ast.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -123,6 +123,18 @@
|
||||
</offlineLinks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.scala.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
@ -74,6 +74,18 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.visualforce.rule.security.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
@ -33,6 +33,18 @@
|
||||
<escapeString>\</escapeString>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<excludes combine.children="append">
|
||||
<exclude>net.sourceforge.pmd.lang.xml.ast.internal</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
31
pom.xml
31
pom.xml
@ -624,6 +624,31 @@
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
<version>0.20.0</version>
|
||||
<configuration>
|
||||
<parameter>
|
||||
<breakBuildBasedOnSemanticVersioning>true</breakBuildBasedOnSemanticVersioning>
|
||||
<onlyModified>true</onlyModified>
|
||||
<excludes>
|
||||
<exclude>@net.sourceforge.pmd.annotation.Experimental</exclude>
|
||||
<exclude>@net.sourceforge.pmd.annotation.InternalApi</exclude>
|
||||
</excludes>
|
||||
</parameter>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>japicmp</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>cmp</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
@ -728,6 +753,11 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Enable japicmp for all modules by default -->
|
||||
<plugin>
|
||||
<groupId>com.github.siom79.japicmp</groupId>
|
||||
<artifactId>japicmp-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@ -1183,6 +1213,7 @@
|
||||
<cpd.skip>true</cpd.skip>
|
||||
<cyclonedx.skip>true</cyclonedx.skip>
|
||||
<dokka.skip>true</dokka.skip>
|
||||
<japicmp.skip>true</japicmp.skip>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
|
Reference in New Issue
Block a user