forked from phoedos/pmd
Implemented UseIndexOfChar
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4135 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -6,7 +6,7 @@ New rules:
|
||||
Basic ruleset: UselessOperationOnImmutable, MisplacedNullCheck, UnusedNullCheckInEquals
|
||||
Migration ruleset: IntegerInstantiation
|
||||
JUnit ruleset: UseAssertNullInsteadOfAssertTrue
|
||||
Strings ruleset: AppendCharacterWithChar, ConsecutiveLiteralAppends
|
||||
Strings ruleset: AppendCharacterWithChar, ConsecutiveLiteralAppends, UseIndexOfChar
|
||||
Design ruleset: AvoidConstantsInterface
|
||||
Optimizations ruleset: UseArraysAsList, AvoidArrayLoops, BooleanInversion
|
||||
Fixed bug 1277373 - InefficientStringBuffering now catches more cases.
|
||||
|
@ -27,6 +27,7 @@ public class AvoidReassigningParametersTest extends SimpleAggregatorTst {
|
||||
new TestDescriptor(TEST7, "assignment to array parameter slot", 0, rule),
|
||||
new TestDescriptor(TEST8, "throws a stacktrace", 1, rule),
|
||||
new TestDescriptor(TEST9, "postfix increment in array dereference is bad", 1, rule),
|
||||
// FIXME new TestDescriptor(TEST10, "assignment to array slot", 0, rule),
|
||||
});
|
||||
}
|
||||
|
||||
@ -99,4 +100,11 @@ public class AvoidReassigningParametersTest extends SimpleAggregatorTst {
|
||||
" y[x++] = 2;" + PMD.EOL +
|
||||
" }" + PMD.EOL +
|
||||
"}";
|
||||
|
||||
public static final String TEST10 =
|
||||
"public class Foo {" + PMD.EOL +
|
||||
" void foo(int x[]) {" + PMD.EOL +
|
||||
" x[2] = 2;" + PMD.EOL +
|
||||
" }" + PMD.EOL +
|
||||
"}";
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
package test.net.sourceforge.pmd.rules.strings;
|
||||
|
||||
import test.net.sourceforge.pmd.testframework.SimpleAggregatorTst;
|
||||
import test.net.sourceforge.pmd.testframework.TestDescriptor;
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.PMD;
|
||||
|
||||
public class UseIndexOfCharTest extends SimpleAggregatorTst {
|
||||
|
||||
private Rule rule;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
rule = findRule("rulesets/strings.xml", "UseIndexOfChar");
|
||||
}
|
||||
|
||||
public void testAll() {
|
||||
runTests(new TestDescriptor[] {
|
||||
new TestDescriptor(TEST1, "failure case", 1, rule),
|
||||
new TestDescriptor(TEST2, "using single quotes, OK", 0, rule),
|
||||
new TestDescriptor(TEST3, "indexOf multi-character literal, OK", 0, rule),
|
||||
});
|
||||
}
|
||||
|
||||
private static final String TEST1 =
|
||||
"public class Foo {" + PMD.EOL +
|
||||
" void bar() {" + PMD.EOL +
|
||||
" String x = \"hello\";" + PMD.EOL +
|
||||
" if (x.indexOf(\"o\") == -1) {}" + PMD.EOL +
|
||||
" }" + PMD.EOL +
|
||||
"}";
|
||||
|
||||
private static final String TEST2 =
|
||||
"public class Foo {" + PMD.EOL +
|
||||
" void bar() {" + PMD.EOL +
|
||||
" String x = \"hello\";" + PMD.EOL +
|
||||
" if (x.indexOf('o') == -1) {}" + PMD.EOL +
|
||||
" }" + PMD.EOL +
|
||||
"}";
|
||||
|
||||
private static final String TEST3 =
|
||||
"public class Foo {" + PMD.EOL +
|
||||
" void bar() {" + PMD.EOL +
|
||||
" String x = \"hello\";" + PMD.EOL +
|
||||
" if (x.indexOf(\"ello\") == -1) {}" + PMD.EOL +
|
||||
" }" + PMD.EOL +
|
||||
"}";
|
||||
|
||||
}
|
@ -6,8 +6,6 @@
|
||||
These are new rules that are still in progress
|
||||
</description>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
<rule name="UselessAssignment"
|
||||
message="This assignment to ''{0}'' is useless"
|
||||
|
@ -128,14 +128,16 @@ Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals()
|
||||
<priority>2</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class A {
|
||||
public class fooinner {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if(sb.toString().equals("")){
|
||||
// this is bad
|
||||
}
|
||||
}
|
||||
}
|
||||
public class Foo {
|
||||
void bar() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
// this is bad
|
||||
if(sb.toString().equals("")) {}
|
||||
// this is good
|
||||
if(sb.length() == 0) {}
|
||||
}
|
||||
}
|
||||
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
@ -191,5 +193,28 @@ public class Foo {
|
||||
</rule>
|
||||
|
||||
|
||||
<rule name="UseIndexOfChar"
|
||||
message="String.indexOf(char) is faster than String.indexOf(String)"
|
||||
class="net.sourceforge.pmd.rules.strings.UseIndexOfChar"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/strings.html#UseIndexOfChar">
|
||||
<description>
|
||||
Use String.indexOf(char) when checking for the index of a single character; it's faster.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
void bar() {
|
||||
String s = "hello world";
|
||||
// avoid this
|
||||
if (s.indexOf("d") {}
|
||||
// instead do this
|
||||
if (s.indexOf('d') {}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package net.sourceforge.pmd.rules.strings;
|
||||
|
||||
import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
|
||||
import net.sourceforge.pmd.ast.SimpleNode;
|
||||
import net.sourceforge.pmd.ast.ASTPrimaryExpression;
|
||||
import net.sourceforge.pmd.ast.Node;
|
||||
import net.sourceforge.pmd.ast.ASTLiteral;
|
||||
import net.sourceforge.pmd.symboltable.NameOccurrence;
|
||||
import net.sourceforge.pmd.AbstractRule;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class UseIndexOfChar extends AbstractRule {
|
||||
public Object visit(ASTVariableDeclaratorId node, Object data) {
|
||||
if (!node.getNameDeclaration().getTypeImage().equals("String")) {
|
||||
return data;
|
||||
}
|
||||
for (Iterator i = node.getUsages().iterator(); i.hasNext();) {
|
||||
NameOccurrence occ = (NameOccurrence) i.next();
|
||||
if (occ.getNameForWhichThisIsAQualifier() != null && occ.getNameForWhichThisIsAQualifier().getImage().indexOf("indexOf") != -1) {
|
||||
SimpleNode parent = (SimpleNode)occ.getLocation().jjtGetParent().jjtGetParent();
|
||||
if (parent instanceof ASTPrimaryExpression) {
|
||||
List literals = parent.findChildrenOfType(ASTLiteral.class);
|
||||
for (Iterator j = literals.iterator(); j.hasNext();) {
|
||||
ASTLiteral literal = (ASTLiteral)j.next();
|
||||
if (literal.getImage().length() == 3 && literal.getImage().charAt(0) == '\"') {
|
||||
addViolation(data, occ.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user