Performance Refactoring, XPath rules re-written as Java: AssignmentInOperand AvoidDollarSigns SuspiciousHashcodeMethodName UselessStringValueOf

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4733 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Xavier Le Vourch
2006-10-23 00:17:58 +00:00
parent e67a4521bc
commit b90fba9662
8 changed files with 138 additions and 52 deletions

View File

@ -29,6 +29,11 @@ undo/redo added to text areas in Designer.
Better 'create rule XML' panel in Designer.
use of entrySet to iterate over Maps.
1.6 added as a valid option for targetjdk.
Performance Refactoring, XPath rules re-written as Java:
AssignmentInOperand
AvoidDollarSigns
SuspiciousHashcodeMethodName
UselessStringValueOf
October 4, 2006 - 3.8:
New rules:

View File

@ -129,21 +129,11 @@ public class Bar {
<rule name="AssignmentInOperand"
message="Avoid assignments in operands"
class="net.sourceforge.pmd.rules.XPathRule"
class="net.sourceforge.pmd.rules.AssignmentInOperand"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#AssignmentInOperand">
<description>
Avoid assignments in operands; this can make code more complicated and harder to read.
</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
//*[name()='WhileStatement' or name()='IfStatement']
[Expression//AssignmentOperator]
]]>
</value>
</property>
</properties>
<priority>3</priority>
<example>
<![CDATA[

View File

@ -194,24 +194,11 @@ public abstract class Foo { // should be AbstractFoo
<rule name="AvoidDollarSigns"
message="Avoid using dollar signs in variable/method/class/interface names"
class="net.sourceforge.pmd.rules.XPathRule"
class="net.sourceforge.pmd.rules.naming.AvoidDollarSigns"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#AvoidDollarSigns">
<description>
Avoid using dollar signs in variable/method/class/interface names.
</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration[contains(@Image, '$')]
|
//VariableDeclaratorId[contains(@Image, '$')]
|
//MethodDeclarator[contains(@Image, '$')]
]]>
</value>
</property>
</properties>
<priority>3</priority>
<example>
<![CDATA[
@ -243,27 +230,12 @@ public class MyClass {
<rule name="SuspiciousHashcodeMethodName"
message="The method name and return type are suspiciously close to hashCode()"
class="net.sourceforge.pmd.rules.XPathRule"
class="net.sourceforge.pmd.rules.naming.SuspiciousHashcodeMethodName"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#SuspiciousHashcodeMethodName">
<description>
The method name and return type are suspiciously close to hashCode(), which
may mean you are intending to override the hashCode() method.
</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
//MethodDeclaration
[ResultType
//PrimitiveType
[@Image='int']
[//MethodDeclarator
[@Image='hashcode' or @Image='HashCode' or @Image='Hashcode']
[not(FormalParameters/*)]]]
]]>
</value>
</property>
</properties>
<priority>3</priority>
<example>
<![CDATA[

View File

@ -270,21 +270,11 @@ public class Foo {
<rule name="UselessStringValueOf"
message="No need to call String.valueOf to append to a string."
class="net.sourceforge.pmd.rules.XPathRule"
class="net.sourceforge.pmd.rules.strings.UselessStringValueOf"
externalInfoUrl="http://pmd.sourceforge.net/rules/strings.html#UselessStringValueOf">
<description>
Use valueOf() argument directly.
</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
//AdditiveExpression[@Image='+']
[PrimaryExpression[not (count(./preceding-sibling::*)=0)]/PrimaryPrefix/Name[@Image='String.valueOf']]
]]>
</value>
</property>
</properties>
<priority>3</priority>
<example>
<![CDATA[

View File

@ -0,0 +1,23 @@
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.ast.ASTAssignmentOperator;
import net.sourceforge.pmd.ast.ASTExpression;
import net.sourceforge.pmd.ast.ASTIfStatement;
import net.sourceforge.pmd.ast.ASTWhileStatement;
import net.sourceforge.pmd.ast.Node;
public class AssignmentInOperand extends AbstractRule {
public Object visit(ASTExpression node, Object data) {
Node parent = node.jjtGetParent();
if ((parent instanceof ASTWhileStatement || parent instanceof ASTIfStatement) &&
node.containsChildOfType(ASTAssignmentOperator.class))
{
addViolation(data, node);
return data;
}
return super.visit(node, data);
}
}

View File

@ -0,0 +1,34 @@
package net.sourceforge.pmd.rules.naming;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.ast.ASTMethodDeclarator;
import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
public class AvoidDollarSigns extends AbstractRule {
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
if (node.getImage().indexOf('$') != -1) {
addViolation(data, node);
return data;
}
return super.visit(node, data);
}
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (node.getImage().indexOf('$') != -1) {
addViolation(data, node);
return data;
}
return super.visit(node, data);
}
public Object visit(ASTMethodDeclarator node, Object data) {
if (node.getImage().indexOf('$') != -1) {
addViolation(data, node);
return data;
}
return super.visit(node, data);
}
}

View File

@ -0,0 +1,38 @@
package net.sourceforge.pmd.rules.naming;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.ast.ASTMethodDeclarator;
import net.sourceforge.pmd.ast.ASTPrimitiveType;
import net.sourceforge.pmd.ast.ASTResultType;
import net.sourceforge.pmd.ast.SimpleJavaNode;
public class SuspiciousHashcodeMethodName extends AbstractRule {
public Object visit(ASTMethodDeclaration node, Object data) {
/* original XPath rule was
//MethodDeclaration
[ResultType
//PrimitiveType
[@Image='int']
[//MethodDeclarator
[@Image='hashcode' or @Image='HashCode' or @Image='Hashcode']
[not(FormalParameters/*)]]]
*/
ASTResultType type = (ASTResultType) node.getFirstChildOfType(ASTResultType.class);
ASTMethodDeclarator decl = (ASTMethodDeclarator) node.getFirstChildOfType(ASTMethodDeclarator.class);
String name = decl.getImage();
if (name.equalsIgnoreCase("hashcode") && !name.equals("hashCode")
&& decl.jjtGetChild(0).jjtGetNumChildren() == 0
&& type.jjtGetNumChildren() != 0) {
SimpleJavaNode t = (SimpleJavaNode) type.jjtGetChild(0).jjtGetChild(0);
if (t instanceof ASTPrimitiveType && "int".equals(t.getImage())) {
addViolation(data, node);
return data;
}
}
return super.visit(node, data);
}
}

View File

@ -0,0 +1,34 @@
package net.sourceforge.pmd.rules.strings;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.ast.ASTAdditiveExpression;
import net.sourceforge.pmd.ast.ASTName;
import net.sourceforge.pmd.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
import net.sourceforge.pmd.ast.Node;
import net.sourceforge.pmd.ast.SimpleJavaNode;
public class UselessStringValueOf extends AbstractRule {
public Object visit(ASTPrimaryPrefix node, Object data) {
if (node.jjtGetNumChildren() == 0 || !node.jjtGetChild(0).getClass().equals(ASTName.class)) {
return super.visit(node, data);
}
String image = ((ASTName) node.jjtGetChild(0)).getImage();
if ("String.valueOf".equals(image)) {
Node parent = node.jjtGetParent();
SimpleJavaNode gp = (SimpleJavaNode) parent.jjtGetParent();
if (parent instanceof ASTPrimaryExpression &&
gp instanceof ASTAdditiveExpression &&
gp.jjtGetChild(0) != parent &&
"+".equals(gp.getImage())) {
super.addViolation(data, node);
return data;
}
}
return super.visit(node, data);
}
}