Implemented UseIndexOfChar

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4135 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Tom Copeland
2006-01-11 22:04:15 +00:00
parent d9a56c328a
commit 8e4783d170
6 changed files with 127 additions and 11 deletions

View File

@ -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.

View File

@ -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 +
"}";
}

View File

@ -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 +
"}";
}

View File

@ -6,8 +6,6 @@
These are new rules that are still in progress
</description>
<!--
<rule name="UselessAssignment"
message="This assignment to ''{0}'' is useless"

View File

@ -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>

View File

@ -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;
}
}