[java] Fix false positive for AppendCharacterWithChar and InefficientStringBuffering

Also make both rules use the rule chain.
This commit is contained in:
Andreas Dangel
2020-06-18 10:28:12 +02:00
parent b8e9ff19b2
commit 1e986ed793
4 changed files with 49 additions and 0 deletions

View File

@ -4,6 +4,7 @@
package net.sourceforge.pmd.lang.java.rule.performance;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
@ -26,6 +27,10 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
*/
public class AppendCharacterWithCharRule extends AbstractJavaRule {
public AppendCharacterWithCharRule() {
addRuleChainVisit(ASTLiteral.class);
}
@Override
public Object visit(ASTLiteral node, Object data) {
ASTBlockStatement bs = node.getFirstParentOfType(ASTBlockStatement.class);
@ -47,6 +52,10 @@ public class AppendCharacterWithCharRule extends AbstractJavaRule {
if (primaryExpression != null && !(primaryExpression.getNthParent(2) instanceof ASTArgumentList)) {
return data;
}
// ignore if this string literal is used as a constructor argument
if (primaryExpression != null && primaryExpression.getNthParent(4) instanceof ASTAllocationExpression) {
return data;
}
addViolation(data, node);
}

View File

@ -14,6 +14,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
@ -39,8 +40,17 @@ import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
*/
public class InefficientStringBufferingRule extends AbstractJavaRule {
public InefficientStringBufferingRule() {
addRuleChainVisit(ASTAdditiveExpression.class);
}
@Override
public Object visit(ASTAdditiveExpression node, Object data) {
if (node.getParent() instanceof ASTConditionalExpression) {
// ignore concats in ternary expressions
return data;
}
ASTBlockStatement bs = node.getFirstParentOfType(ASTBlockStatement.class);
if (bs == null) {
return data;

View File

@ -204,6 +204,20 @@ public class Foo {
StringBuilder sb = new StringBuilder().append("a");
sb = new StringBuilder().append("c");
}
}
]]></code>
</test-code>
<test-code>
<description>false positive with string as constructor arg in StringBuilder method chain</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private String name = "bar";
public String toString() {
StringBuilder sb = new StringBuilder("#").append("Foo").append('#').append(this.name);
return sb.toString();
}
}
]]></code>
</test-code>

View File

@ -434,6 +434,22 @@ public class Foo {
sb.append("local:" + local); // good
return sb.toString;
}
}
]]></code>
</test-code>
<test-code>
<description>false positive with ternary</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private int someInt = 1;
public String toString() {
StringBuilder sb = new StringBuilder("Foo{");
sb.append("someInt=").append(this.someInt < 0 ? "n/a" : this.someInt + "ms");
sb.append('}');
return sb.toString();
}
}
]]></code>
</test-code>