[java] ConsecutiveLiteralAppends and

InsufficientStringBufferDeclaration: FP with switch expressions

Fixes #3152
This commit is contained in:
Andreas Dangel committed 2021-03-04 10:20:21 +01:00
1 parent 5650b720b3
commit ca89cba25f
5 files changed
+83 -1

No files matched your search

+3
View File
@@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release.
### Fixed Issues
* java-performance
* [#3152](https://github.com/pmd/pmd/issues/3152): \[java] ConsecutiveLiteralAppends and InsufficientStringBufferDeclaration: FP with switch expressions
### API Changes
### External Contributions
@@ -28,6 +28,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabeledBlock;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabeledExpression;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.ast.ASTVariableInitializer;
@@ -80,6 +82,8 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule {
BLOCK_PARENTS.add(ASTCatchStatement.class);
BLOCK_PARENTS.add(ASTFinallyStatement.class);
BLOCK_PARENTS.add(ASTLambdaExpression.class);
BLOCK_PARENTS.add(ASTSwitchLabeledBlock.class);
BLOCK_PARENTS.add(ASTSwitchLabeledExpression.class);
}
private static final PropertyDescriptor<Integer> THRESHOLD_DESCRIPTOR
@@ -91,6 +95,7 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule {
public ConsecutiveLiteralAppendsRule() {
definePropertyDescriptor(THRESHOLD_DESCRIPTOR);
addRuleChainVisit(ASTVariableDeclaratorId.class);
}
@Override
@@ -25,6 +25,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabeledBlock;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabeledExpression;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
@@ -44,14 +46,20 @@ public class InsufficientStringBufferDeclarationRule extends AbstractJavaRule {
private static final Set<Class<? extends Node>> BLOCK_PARENTS;
static {
BLOCK_PARENTS = new HashSet<>(2);
BLOCK_PARENTS = new HashSet<>();
BLOCK_PARENTS.add(ASTIfStatement.class);
BLOCK_PARENTS.add(ASTSwitchStatement.class);
BLOCK_PARENTS.add(ASTSwitchLabeledBlock.class);
BLOCK_PARENTS.add(ASTSwitchLabeledExpression.class);
}
// as specified in StringBuffer and StringBuilder
public static final int DEFAULT_BUFFER_SIZE = 16;
public InsufficientStringBufferDeclarationRule() {
addRuleChainVisit(ASTVariableDeclaratorId.class);
}
@Override
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (node.getNameDeclaration() == null
@@ -1497,4 +1497,37 @@ public class Foo {
}
]]></code>
</test-code>
<test-code>
<description>[java] ConsecutiveLiteralAppends and InsufficientStringBufferDeclaration: FP with switch expressions #3152</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class FalsePositive {
public static String escapeHTML(String text) {
int length = text.length();
int index = findHTMLReservedChar(text);
if (index == length) return text;
var builder = new StringBuilder(length * 2); // Rule:InsufficientStringBufferDeclaration Priority:3 StringBuffer constructor is initialized with size 16, but has at least 29 characters appended..
for (int i = 0; i < index; i++) builder.append(text.charAt(i));
for (; index < length; index++) {
char ch = text.charAt(index);
switch (ch) {
case '<' -> { builder.append("&lt;"); } // Rule:ConsecutiveLiteralAppends Priority:3 StringBuffer (or StringBuilder).append is called 6 consecutive times with literals. Use a single append with a single combined String..
case '>' -> builder.append("&gt;");
case '"' -> builder.append("&quot;");
case '&' -> builder.append("&amp;");
case '\'' -> builder.append("&#39;");
case '/' -> builder.append("&#47;");
default -> builder.append(ch);
}
}
return builder.toString();
}
private static int findHTMLReservedChar(String text) {
return 0;
}
}
]]></code>
</test-code>
</test-data>
@@ -1068,4 +1068,37 @@ public class Test {
}
]]></code>
</test-code>
<test-code>
<description>[java] ConsecutiveLiteralAppends and InsufficientStringBufferDeclaration: FP with switch expressions #3152</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class FalsePositive {
public static String escapeHTML(String text) {
int length = text.length();
int index = findHTMLReservedChar(text);
if (index == length) return text;
var builder = new StringBuilder(length * 2); // Rule:InsufficientStringBufferDeclaration Priority:3 StringBuffer constructor is initialized with size 16, but has at least 29 characters appended..
for (int i = 0; i < index; i++) builder.append(text.charAt(i));
for (; index < length; index++) {
char ch = text.charAt(index);
switch (ch) {
case '<' -> { builder.append("&lt;"); } // Rule:ConsecutiveLiteralAppends Priority:3 StringBuffer (or StringBuilder).append is called 6 consecutive times with literals. Use a single append with a single combined String..
case '>' -> builder.append("&gt;");
case '"' -> builder.append("&quot;");
case '&' -> builder.append("&amp;");
case '\'' -> builder.append("&#39;");
case '/' -> builder.append("&#47;");
default -> builder.append(ch);
}
}
return builder.toString();
}
private static int findHTMLReservedChar(String text) {
return 0;
}
}
]]></code>
</test-code>
</test-data>