DynamicXPathRule is now generated automatically by parsing XPath expression and is transparent to rule writers (based on code by Ryan Gustafson)

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4887 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Xavier Le Vourch
2006-12-15 02:29:37 +00:00
parent 753bd13853
commit b24c8fe053
20 changed files with 243 additions and 306 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0"?>
<ruleset name="Basic JSF rules"
language="jsp"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,7 @@ The Braces Ruleset contains a collection of braces rules.
<rule name="IfStmtsMustUseBraces"
message="Avoid using if statements without curly braces"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="IfStatement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#IfStmtsMustUseBraces">
<description>
Avoid using if statements without using curly braces.
@ -21,7 +20,7 @@ Avoid using if statements without using curly braces.
<property name="xpath">
<value>
<![CDATA[
.[count(*) < 3][not(Statement/Block)]
//IfStatement[count(*) < 3][not(Statement/Block)]
]]>
</value>
</property>
@ -42,8 +41,7 @@ Avoid using if statements without using curly braces.
<rule name="WhileLoopsMustUseBraces"
message="Avoid using 'while' statements without curly braces"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="WhileStatement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#WhileLoopsMustUseBraces">
<description>
Avoid using 'while' statements without using curly braces.
@ -52,7 +50,7 @@ Avoid using 'while' statements without using curly braces.
<property name="xpath">
<value>
<![CDATA[
.[not(Statement/Block)]
//WhileStatement[not(Statement/Block)]
]]>
</value>
</property>
@ -71,8 +69,7 @@ public void doSomething() {
<rule name="IfElseStmtsMustUseBraces"
message="Avoid using 'if...else' statements without curly braces"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="Statement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#IfElseStmtsMustUseBraces">
<description>
Avoid using if..else statements without using curly braces.
@ -81,7 +78,7 @@ Avoid using if..else statements without using curly braces.
<property name="xpath">
<value>
<![CDATA[
.
//Statement
[parent::IfStatement[@Else='true']]
[not(child::Block)]
[not(child::IfStatement)]
@ -108,8 +105,7 @@ Avoid using if..else statements without using curly braces.
<rule name="ForLoopsMustUseBraces"
message="Avoid using 'for' statements without curly braces"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ForStatement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#ForLoopsMustUseBraces">
<description>
Avoid using 'for' statements without using curly braces.
@ -118,7 +114,7 @@ Avoid using 'for' statements without using curly braces.
<property name="xpath">
<value>
<![CDATA[
.[not(Statement/Block)]
//ForStatement[not(Statement/Block)]
]]>
</value>
</property>

View File

@ -11,8 +11,7 @@ The Clone Implementation ruleset contains a collection of rules that find questi
<rule name="ProperCloneImplementation"
message="Object clone() should be implemented with super.clone()"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclarator"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/clone.html#ProperCloneImplementation">
<description>
Object clone() should be implemented with super.clone().
@ -21,7 +20,7 @@ Object clone() should be implemented with super.clone().
<property name="xpath">
<value>
<![CDATA[
.
//MethodDeclarator
[@Image = 'clone']
[count(FormalParameters/*) = 0]
[count(../Block//*[
@ -49,8 +48,7 @@ class Foo{
<rule name="CloneThrowsCloneNotSupportedException"
message="clone() method should throw CloneNotSupportedException"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/clone.html#CloneThrowsCloneNotSupportedException">
<description>
The method clone() should throw a CloneNotSupportedException.
@ -59,7 +57,7 @@ The method clone() should throw a CloneNotSupportedException.
<property name="xpath">
<value>
<![CDATA[
.
//MethodDeclaration
[
MethodDeclarator/@Image = 'clone'
and count(MethodDeclarator/FormalParameters/*) = 0
@ -88,8 +86,7 @@ and count(NameList/Name[contains
<rule name="CloneMethodMustImplementCloneable"
message="clone() method should be implemented only if implementing Cloneable interface"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/clone.html#CloneMethodMustImplementCloneable">
<description>
The method clone() should only be implemented if the class implements the Cloneable interface with the exception of a final method that only throws CloneNotSupportedException.
@ -98,7 +95,7 @@ The method clone() should only be implemented if the class implements the Clonea
<property name="xpath">
<value>
<![CDATA[
.
//ClassOrInterfaceDeclaration
[not(./ImplementsList/ClassOrInterfaceType
[@Image='Cloneable'])]
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration

View File

@ -15,8 +15,7 @@ most people really dislike :-)
<rule name="UnnecessaryConstructor"
message="Avoid unnecessary constructors - the compiler will generate these for you"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceBody"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#UnnecessaryConstructor">
<description>
This rule detects when a constructor is not necessary; i.e., when there's only one constructor,
@ -26,7 +25,7 @@ it's public, has an empty body, and takes no arguments.
<property name="xpath">
<value>
<![CDATA[
.[count(ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)=1]
//ClassOrInterfaceBody[count(ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)=1]
/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration
[@Public='true']
[not(FormalParameters/*)]
@ -154,8 +153,7 @@ public class Foo {
<rule name="AtLeastOneConstructor"
message="Each class should declare at least one constructor"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#AtLeastOneConstructor">
<description>
Each class should declare at least one constructor.
@ -164,7 +162,7 @@ Each class should declare at least one constructor.
<property name="xpath">
<value>
<![CDATA[
.
//ClassOrInterfaceDeclaration
[not(ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)]
[@Interface='false']
]]>
@ -228,8 +226,7 @@ public class Foo {
<rule name="CallSuperInConstructor"
message="It is a good practice to call super() in a constructor"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#CallSuperInConstructor">
<description>
It is a good practice to call super() in a constructor. If super() is not called but
@ -239,7 +236,7 @@ It is a good practice to call super() in a constructor. If super() is not called
<property name="xpath">
<value>
<![CDATA[
.[ count (ExtendsList/*) > 0 ]
//ClassOrInterfaceDeclaration[ count (ExtendsList/*) > 0 ]
/ClassOrInterfaceBody
/ClassOrInterfaceBodyDeclaration
/ConstructorDeclaration[ count (.//ExplicitConstructorInvocation)=0 ]
@ -267,8 +264,7 @@ public class Foo extends Bar{
<rule name="UnnecessaryParentheses"
message="This statement may have some unnecessary parentheses"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ReturnStatement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#UnnecessaryParentheses">
<description>
Sometimes expressions are wrapped in unnecessary parentheses,
@ -278,7 +274,7 @@ making them look like a function call.
<property name="xpath">
<value>
<![CDATA[
.
//ReturnStatement
/Expression
/PrimaryExpression
/PrimaryPrefix
@ -322,8 +318,7 @@ public class Foo {
<rule name="DefaultPackage"
message="Use explicit scoping instead of the default package private level"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#DefaultPackage">
<description>
Use explicit scoping instead of the default package private level.
@ -331,7 +326,7 @@ Use explicit scoping instead of the default package private level.
<properties>
<property name="xpath">
<value><![CDATA[
.[@Interface='false']
//ClassOrInterfaceDeclaration[@Interface='false']
/ClassOrInterfaceBody
/ClassOrInterfaceBodyDeclaration
[
@ -346,8 +341,7 @@ or MethodDeclaration[@PackagePrivate='true']
<rule name="BooleanInversion"
message="Use bitwise inversion to invert boolean values"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="AssignmentOperator"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#BooleanInversion">
<description>
Use bitwise inversion to invert boolean values - it's the fastest way to do this.
@ -357,7 +351,7 @@ See http://www.javaspecialists.co.za/archive/newsletter.do?issue=042&amp;locale=
<property name="xpath">
<value>
<![CDATA[
.[@Image="="]/../Expression/UnaryExpressionNotPlusMinus[@Image="!"]
//AssignmentOperator[@Image="="]/../Expression/UnaryExpressionNotPlusMinus[@Image="!"]
]]>
</value>
</property>

File diff suppressed because it is too large Load Diff

View File

@ -12,8 +12,7 @@ These rules deal with different problems that can occur with finalizers.
<rule name="EmptyFinalizer"
message="Avoid empty finalize methods"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#EmptyFinalizer">
<description>
If the finalize() method is empty, then it does not need to exist.
@ -22,7 +21,7 @@ If the finalize() method is empty, then it does not need to exist.
<property name="xpath">
<value>
<![CDATA[
.[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
/Block[count(*)=0]
]]>
</value>
@ -40,8 +39,7 @@ public class Foo {
<rule name="FinalizeOnlyCallsSuperFinalize"
message="Finalize should do something besides just calling super.finalize()"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeOnlyCallsSuperFinalize">
<description>
If the finalize() is implemented, it should do something besides just calling
@ -51,7 +49,7 @@ super.finalize().
<property name="xpath">
<value>
<![CDATA[
.[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
//MethodDeclaration[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
/Block[count(BlockStatement)=1]
/BlockStatement[
Statement/StatementExpression/PrimaryExpression
@ -75,8 +73,7 @@ public class Foo {
<rule name="FinalizeOverloaded"
message="Finalize methods should not be overloaded"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeOverloaded">
<description>
Methods named finalize() should not have parameters. It is
@ -87,7 +84,7 @@ not be called by the VM.
<property name="xpath">
<value>
<![CDATA[
.
//MethodDeclaration
/MethodDeclarator[@Image='finalize'][FormalParameters[count(*)>0]]
]]>
</value>
@ -107,8 +104,7 @@ public class Foo {
<rule name="FinalizeDoesNotCallSuperFinalize"
message="Last statement in finalize method should be a call to super.finalize()"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeDoesNotCallSuperFinalize">
<description>
If the finalize() is implemented, its last action should be to call super.finalize.
@ -119,7 +115,7 @@ If the finalize() is implemented, its last action should be to call super.finali
<!-- in english: a method declaration of finalize(), with no arguments, containing
a block whose last statement is NOT a call to super.finalize -->
<![CDATA[
.[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
/Block
/BlockStatement[last()]
[not(Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image='finalize'])]
@ -145,8 +141,7 @@ public class Foo {
<rule name="FinalizeShouldBeProtected"
message="If you override finalize(), make it protected"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeShouldBeProtected">
<description>
If you override finalize(), make it protected. If you make
@ -156,7 +151,7 @@ If you override finalize(), make it protected. If you make
<property name="xpath">
<value>
<![CDATA[
.[@Protected="false"]
//MethodDeclaration[@Protected="false"]
/MethodDeclarator[@Image="finalize"]
[not(FormalParameters/*)]
]]>

View File

@ -8,8 +8,7 @@
<rule name="UseProperClassLoader"
message="In J2EE, getClassLoader() might not work as expected. Use Thread.currentThread().getContextClassLoader() instead."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimarySuffix">
class="net.sourceforge.pmd.rules.XPathRule">
<description>
In J2EE getClassLoader() might not work as expected. Use Thread.currentThread().getContextClassLoader() instead.
</description>
@ -17,7 +16,7 @@
<property name="xpath">
<value>
<![CDATA[
.[@Image='getClassLoader']
//PrimarySuffix[@Image='getClassLoader']
]]>
</value>
</property>

View File

@ -49,8 +49,7 @@ provide getFoo and setFoo methods.
<rule name="MissingSerialVersionUID"
message="Classes implementing Serializable should set a serialVersionUID"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/javabeans.html#MissingSerialVersionUID">
<description>
Classes that are serializable should provide a serialVersionUID field.
@ -59,7 +58,7 @@ Classes that are serializable should provide a serialVersionUID field.
<property name="xpath">
<value>
<![CDATA[
.
//ClassOrInterfaceDeclaration
[
count(ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration
/FieldDeclaration/VariableDeclarator/VariableDeclaratorId[@Image='serialVersionUID']) = 0

View File

@ -11,8 +11,7 @@ These rules deal with different problems that can occur with JUnit tests.
<rule name="JUnitStaticSuite"
message="You have a suite() method that is not both public and static, so JUnit won't call it to get your TestSuite. Is that what you wanted to do?"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#JUnitStaticSuite">
<description>
The suite() method in a JUnit test needs to be both public and static.
@ -21,7 +20,7 @@ The suite() method in a JUnit test needs to be both public and static.
<property name="xpath">
<value>
<![CDATA[
.[not(@Static='true') or not(@Public='true')]
//MethodDeclaration[not(@Static='true') or not(@Public='true')]
[MethodDeclarator/@Image='suite']
[MethodDeclarator/FormalParameters/@ParameterCount=0]
]]>
@ -43,8 +42,7 @@ public class Foo extends TestCase {
<rule name="JUnitSpelling"
message="You may have misspelled a JUnit framework method (setUp or tearDown)"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclarator"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#JUnitSpelling">
<description>
Some JUnit framework methods are easy to misspell.
@ -53,7 +51,7 @@ Some JUnit framework methods are easy to misspell.
<property name="xpath">
<value>
<![CDATA[
.[(not(@Image = 'setUp')
//MethodDeclarator[(not(@Image = 'setUp')
and translate(@Image, 'SETuP', 'setUp') = 'setUp')
or (not(@Image = 'tearDown')
and translate(@Image, 'TEARdOWN', 'tearDown') = 'tearDown')]
@ -146,8 +144,7 @@ public class CarTest {
<rule name="UnnecessaryBooleanAssertion"
message="assertTrue(true) or similar statements are unnecessary"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="StatementExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UnnecessaryBooleanAssertion">
<description>
A JUnit test assertion with a boolean literal is unnecessary since it always will eval to the same thing.
@ -158,7 +155,7 @@ statements like assertTrue(true) and assertFalse(false). If you just want a tes
<property name="xpath">
<value>
<![CDATA[
.
//StatementExpression
[
.//Name[@Image='assertTrue' or @Image='assertFalse']
and
@ -193,8 +190,7 @@ public class SimpleTest extends TestCase {
<rule name="UseAssertEqualsInsteadOfAssertTrue"
message="Use assertEquals(x, y) instead of assertTrue(x.equals(y))"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimaryExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UseAssertEqualsInsteadOfAssertTrue">
<description>
This rule detects JUnit assertions in object equality. These assertions
@ -204,7 +200,7 @@ should be made by more specific methods, like assertEquals.
<property name="xpath">
<value>
<![CDATA[
.[
//PrimaryExpression[
PrimaryPrefix/Name[@Image = 'assertTrue']
][
PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
@ -230,8 +226,7 @@ public class FooTest extends TestCase {
<rule name="UseAssertSameInsteadOfAssertTrue"
message="Use assertSame(x, y) instead of assertTrue(x==y), or assertNotSame(x,y) vs assertFalse(x==y)"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimaryExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UseAssertSameInsteadOfAssertTrue">
<description>
This rule detects JUnit assertions in object references equality. These assertions
@ -241,7 +236,7 @@ should be made by more specific methods, like assertSame, assertNotSame.
<property name="xpath">
<value>
<![CDATA[
.[
//PrimaryExpression[
PrimaryPrefix/Name
[@Image = 'assertTrue' or @Image = 'assertFalse']
]
@ -268,8 +263,7 @@ public class FooTest extends TestCase {
<rule name="UseAssertNullInsteadOfAssertTrue"
message="Use assertNull(x) instead of assertTrue(x==null), or assertNotNull(x) vs assertFalse(x==null)"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimaryExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UseAssertNullInsteadOfAssertTrue">
<description>
This rule detects JUnit assertions in object references equality. These assertions
@ -279,7 +273,7 @@ public class FooTest extends TestCase {
<property name="xpath">
<value>
<![CDATA[
.[
//PrimaryExpression[
PrimaryPrefix/Name[@Image = 'assertTrue' or @Image = 'assertFalse']
][
PrimarySuffix/Arguments/ArgumentList[
@ -308,8 +302,7 @@ public class FooTest extends TestCase {
<rule name="SimplifyBooleanAssertion"
message="assertTrue(!expr) can be replaced by assertFalse(expr)"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="StatementExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#SimplifyBooleanAssertion">
<description>
Avoid negation in an assertTrue or assertFalse test.
@ -322,7 +315,7 @@ assertFalse(expr);
<property name="xpath">
<value>
<![CDATA[
.
//StatementExpression
[
.//Name[@Image='assertTrue' or @Image='assertFalse']
and

View File

@ -11,8 +11,7 @@ The Jakarta Commons Logging ruleset contains a collection of rules that find que
<rule name="UseCorrectExceptionLogging"
message="Use the correct logging statement for logging exceptions"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="CatchStatement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-jakarta-commons.html#UseCorrectExceptionLogging">
<description>
To make sure the full stacktrace is printed out, use the logging statement with 2 arguments: a String and a Throwable.
@ -20,7 +19,7 @@ To make sure the full stacktrace is printed out, use the logging statement with
<properties>
<property name="xpath">
<value><![CDATA[
./Block/BlockStatement/Statement/StatementExpression
//CatchStatement/Block/BlockStatement/Statement/StatementExpression
/PrimaryExpression[PrimaryPrefix/Name[starts-with(@Image,
concat(//ClassOrInterfaceBodyDeclaration/FieldDeclaration
[Type//ClassOrInterfaceType[@Image='Log']]
@ -47,8 +46,7 @@ public class Main {
<rule name="ProperLogger"
message="Logger should be defined private static final and have the correct class"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceBodyDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-jakarta-commons.html#ProperLogger">
<description>
Logger should normally be defined private static final and have the correct class.
@ -59,7 +57,7 @@ public class Main {
<property name="xpath">
<value>
<![CDATA[
.[FieldDeclaration//ClassOrInterfaceType[@Image='Log']
//ClassOrInterfaceBodyDeclaration[FieldDeclaration//ClassOrInterfaceType[@Image='Log']
and
not(FieldDeclaration[@Final='true'][@Static='true'][@Private='true'][//VariableDeclaratorId[@Image=$staticLoggerName]]
//ArgumentList//ClassOrInterfaceType/@Image = ancestor::ClassOrInterfaceDeclaration/@Image)

View File

@ -32,8 +32,7 @@ class Foo{
<rule name="LoggerIsNotStaticFinal"
message="The Logger variable declaration does not contain the static and final modifiers"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="VariableDeclarator"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-java.html#LoggerIsNotStaticFinal">
<description>
In most cases, the Logger can be declared static and final.
@ -42,7 +41,7 @@ In most cases, the Logger can be declared static and final.
<property name="xpath">
<value>
<![CDATA[
.
//VariableDeclarator
[parent::FieldDeclaration]
[../Type/ReferenceType
/ClassOrInterfaceType[@Image='Logger']
@ -102,8 +101,7 @@ first -->
<rule name="SystemPrintln"
message="System.out.print is used"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="Name"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-java.html#SystemPrintln">
<description>
System.(out|err).print is used, consider using a logger.
@ -112,7 +110,7 @@ System.(out|err).print is used, consider using a logger.
<property name="xpath">
<value>
<![CDATA[
.[
//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
@ -138,8 +136,7 @@ class Foo{
<rule name="AvoidPrintStackTrace"
message="Avoid printStackTrace(); use a logger call instead."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimaryExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-java.html#AvoidPrintStackTrace">
<description>
Avoid printStackTrace(); use a logger call instead.
@ -148,7 +145,7 @@ Avoid printStackTrace(); use a logger call instead.
<property name="xpath">
<value>
<![CDATA[
.
//PrimaryExpression
[PrimaryPrefix/Name[contains(@Image,'printStackTrace')]]
[PrimarySuffix[not(boolean(Arguments/ArgumentList/Expression))]]
]]>

View File

@ -13,8 +13,7 @@ Contains rules about migrating from one JDK version to another. Don't use these
<rule name="ReplaceVectorWithList"
message="Consider replacing this Vector with the newer java.util.List"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="Type"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#ReplaceVectorWithList">
<description>
Consider replacing Vector usages with the newer java.util.ArrayList if expensive threadsafe operation is not required.
@ -23,7 +22,7 @@ Contains rules about migrating from one JDK version to another. Don't use these
<property name="xpath">
<value>
<![CDATA[
./ReferenceType/ClassOrInterfaceType[@Image='Vector']
//Type/ReferenceType/ClassOrInterfaceType[@Image='Vector']
]]>
</value>
</property>
@ -42,8 +41,7 @@ public class Foo {
<rule name="ReplaceHashtableWithMap"
message="Consider replacing this Hashtable with the newer java.util.Map"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="Type"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#ReplaceHashtableWithMap">
<description>
Consider replacing this Hashtable with the newer java.util.Map
@ -52,7 +50,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
./ReferenceType/ClassOrInterfaceType[@Image='Hashtable']
//Type/ReferenceType/ClassOrInterfaceType[@Image='Hashtable']
]]>
</value>
</property>
@ -71,8 +69,7 @@ public class Foo {
<rule name="ReplaceEnumerationWithIterator"
message="Consider replacing this Enumeration with the newer java.util.Iterator"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ImplementsList"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#ReplaceEnumerationWithIterator">
<description>
Consider replacing this Enumeration with the newer java.util.Iterator
@ -81,7 +78,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
./ClassOrInterfaceType[@Image='Enumeration']
//ImplementsList/ClassOrInterfaceType[@Image='Enumeration']
]]>
</value>
</property>
@ -104,15 +101,14 @@ public class Foo implements Enumeration {
<rule name="AvoidEnumAsIdentifier"
message="Avoid using enum as an identifier; it's a reserved word in JDK 1.5"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="VariableDeclaratorId"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#AvoidEnumAsIdentifier">
<description>Finds all places 'enum' is used as an identifier is used.</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
.[@Image='enum']
//VariableDeclaratorId[@Image='enum']
]]>
</value>
</property>
@ -131,15 +127,14 @@ public class Foo implements Enumeration {
<rule name="AvoidAssertAsIdentifier"
message="Avoid using assert as an identifier; it's a reserved word in JDK 1.4"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="VariableDeclaratorId"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#AvoidAssertAsIdentifier">
<description>Finds all places 'assert' is used as an identifier is used.</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
.[@Image='assert']
//VariableDeclaratorId[@Image='assert']
]]>
</value>
</property>
@ -158,14 +153,13 @@ public class Foo implements Enumeration {
<rule name="IntegerInstantiation"
message="Avoid instantiating Integer objects. Call Integer.valueOf() instead."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimaryPrefix">
class="net.sourceforge.pmd.rules.XPathRule">
<description>In JDK 1.5, calling new Integer() causes memory allocation. Integer.valueOf() is more memory friendly.</description>
<properties>
<property name="xpath">
<value>
<![CDATA[
.
//PrimaryPrefix
/AllocationExpression
[not (ArrayDimsAndInits)
and (ClassOrInterfaceType/@Image='Integer'

View File

@ -12,8 +12,7 @@ The Naming Ruleset contains a collection of rules about names - too long, too sh
<rule name="ShortVariable"
message="Avoid variables with short names like {0}"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="VariableDeclaratorId"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#ShortVariable">
<description>
Detects when a field, local, or parameter has a very short name.
@ -22,7 +21,7 @@ Detects when a field, local, or parameter has a very short name.
<property name="xpath" pluginname="true">
<value>
<![CDATA[
.[string-length(@Image) < 3]
//VariableDeclaratorId[string-length(@Image) < 3]
[not(ancestor::ForInit)]
[not((ancestor::FormalParameter) and (ancestor::TryStatement))]
]]>
@ -47,8 +46,7 @@ public class Something {
<rule name="LongVariable"
message="Avoid excessively long variable names like {0}"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="VariableDeclaratorId"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#LongVariable">
<description>
Detects when a field, formal or local variable is declared with a long name.
@ -59,7 +57,7 @@ Detects when a field, formal or local variable is declared with a long name.
<property name="xpath" pluginname="true">
<value>
<![CDATA[
.[string-length(@Image) > $minimum]
//VariableDeclaratorId[string-length(@Image) > $minimum]
]]>
</value>
</property>
@ -81,8 +79,7 @@ public class Something {
<rule name="ShortMethodName"
message="Avoid using short method names"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclarator"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#ShortMethodName">
<description>
Detects when very short method names are used.
@ -92,7 +89,7 @@ Detects when very short method names are used.
<property name="xpath">
<value>
<![CDATA[
.[string-length(@Image) < 3]
//MethodDeclarator[string-length(@Image) < 3]
]]>
</value>
</property>
@ -170,8 +167,7 @@ public class Foo {}
<rule name="AbstractNaming"
message="Abstract classes should be named 'AbstractXXX'"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#AbstractNaming">
<description>
Abstract classes should be named 'AbstractXXX'.
@ -181,7 +177,7 @@ Abstract classes should be named 'AbstractXXX'.
<property name="xpath">
<value>
<![CDATA[
.
//ClassOrInterfaceDeclaration
[@Abstract='true' and @Interface='false']
[not (starts-with(@Image,'Abstract'))]
]]>
@ -254,8 +250,7 @@ public class Foo {
<rule name="SuspiciousConstantFieldName"
message="The field name indicates a constant but its modifiers do not"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#SuspiciousConstantFieldName">
<description>
A field name is all in uppercase characters, which in Sun's Java naming
@ -265,7 +260,7 @@ conventions indicate a constant. However, the field is not final.
<property name="xpath">
<value>
<![CDATA[
.[@Interface='false']
//ClassOrInterfaceDeclaration[@Interface='false']
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/FieldDeclaration
[@Final='false']
[VariableDeclarator/VariableDeclaratorId[upper-case(@Image)=@Image]]
@ -289,8 +284,7 @@ public class Foo {
<rule
name="SuspiciousEqualsMethodName"
message="The method name and parameter number are suspiciously close to equals(Object)"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="MethodDeclarator"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#SuspiciousEqualsMethodName">
<description>
The method name and parameter number are suspiciously close to
@ -301,7 +295,7 @@ method.
<property name="xpath">
<value>
<![CDATA[
.[
//MethodDeclarator[
(
@Image = 'equals'
and count(FormalParameters/*) = 1
@ -397,8 +391,7 @@ public class Foo {
<rule name="NoPackage"
message="All classes and interfaces must belong to a named package"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="ClassOrInterfaceDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#NoPackage">
<description>
Detects when a class or interface does not have a package definition.
@ -407,7 +400,7 @@ Detects when a class or interface does not have a package definition.
<property name="xpath" pluginname="true">
<value>
<![CDATA[
.[count(preceding::PackageDeclaration) = 0]
//ClassOrInterfaceDeclaration[count(preceding::PackageDeclaration) = 0]
]]>
</value>
</property>
@ -424,8 +417,7 @@ public class ClassInDefaultPackage {
<rule name="PackageCase"
message="Package name contains upper case characters"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PackageDeclaration"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#PackageCase">
<description>
Detects when a package definition contains upper case characters.
@ -434,7 +426,7 @@ public class ClassInDefaultPackage {
<property name="xpath" pluginname="true">
<value>
<![CDATA[
./Name[lower-case(@Image)!=@Image]
//PackageDeclaration/Name[lower-case(@Image)!=@Image]
]]>
</value>
</property>
@ -451,8 +443,7 @@ public class SomeClass {
<rule name="MisleadingVariableName"
message="Avoid naming non-fields with the prefix 'm_'"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="VariableDeclaratorId"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#MisleadingVariableName">
<description>
Detects when a non-field has a name starting with 'm_'. This usually
@ -462,7 +453,7 @@ indicates a field and thus is confusing.
<property name="xpath" pluginname="true">
<value>
<![CDATA[
.
//VariableDeclaratorId
[starts-with(@Image, 'm_')]
[not (../../../FieldDeclaration)]
]]>

View File

@ -70,8 +70,7 @@ public class Something {
<rule name="UseArrayListInsteadOfVector"
message="Use ArrayList instead of Vector"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="AllocationExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#UseArrayListInsteadOfVector">
<description>
ArrayList is a much better Collection implementation than Vector.
@ -80,7 +79,7 @@ ArrayList is a much better Collection implementation than Vector.
<property name="xpath">
<value>
<![CDATA[
.
//AllocationExpression
/ClassOrInterfaceType[@Image='Vector' or @Image='java.util.Vector']
]]>
</value>
@ -102,8 +101,7 @@ public class SimpleTest extends TestCase {
<rule name="SimplifyStartsWith"
message="This call to String.startsWith can be rewritten using String.charAt(0)"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="PrimaryExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#SimplifyStartsWith">
<description>
Since it passes in a literal of length 1, this call to String.startsWith can be rewritten using String.charAt(0) to save some time.
@ -112,7 +110,7 @@ Since it passes in a literal of length 1, this call to String.startsWith can be
<property name="xpath">
<value>
<![CDATA[
.
//PrimaryExpression
[PrimaryPrefix/Name
[ends-with(@Image, '.startsWith')]]
[PrimarySuffix/Arguments/ArgumentList
@ -166,8 +164,7 @@ public class Foo {
<rule name="UseArraysAsList"
message="Use asList instead of tight loops"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="Statement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#UseArraysAsList">
<description>
The class java.util.Arrays has a "asList" method that
@ -179,7 +176,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
.[
//Statement[
(ForStatement) and (count(.//IfStatement)=0)
]
//StatementExpression[
@ -231,8 +228,7 @@ public class Foo {
<rule name="AvoidArrayLoops"
message="System.arrayCopy is more efficient"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="Statement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#AvoidArrayLoops">
<description>
Instead of copying data between two arrays, use
@ -242,7 +238,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
.[(ForStatement or WhileStatement) and
//Statement[(ForStatement or WhileStatement) and
count(*//AssignmentOperator[@Image = '='])=1
and
*/Statement

View File

@ -79,8 +79,7 @@ public class Foo {
<rule name="AvoidCatchingNPE"
message="Avoid catching NullPointerException; consider removing the cause of the NPE."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="CatchStatement"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/strictexception.html#AvoidCatchingNPE">
<description>
Code should never throw NPE under normal circumstances. A catch block may hide the original error, causing other more subtle errors in its wake.
@ -101,7 +100,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
./FormalParameter/Type
//CatchStatement/FormalParameter/Type
/ReferenceType/ClassOrInterfaceType[@Image='NullPointerException']
]]>
</value>
@ -111,8 +110,7 @@ public class Foo {
<rule name="AvoidThrowingRawExceptionTypes"
message="Avoid throwing raw exception types."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="AllocationExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/strictexception.html#AvoidThrowingRawExceptionTypes">
<description>
Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable,
@ -132,7 +130,7 @@ public void bar() throws Exception {
<property name="xpath">
<value>
<![CDATA[
.
//AllocationExpression
/ClassOrInterfaceType[
@Image='Throwable' or
@Image='Exception' or
@ -146,8 +144,7 @@ public void bar() throws Exception {
<rule name="AvoidThrowingNullPointerException"
message="Avoid throwing null pointer exceptions."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="AllocationExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/strictexception.html#AvoidThrowingNullPointerException">
<description>
Avoid throwing a NullPointerException - it's confusing because most people will assume that the
@ -168,7 +165,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
./ClassOrInterfaceType[@Image='NullPointerException']
//AllocationExpression/ClassOrInterfaceType[@Image='NullPointerException']
]]>
</value>
</property>
@ -177,8 +174,7 @@ public class Foo {
<rule name="AvoidRethrowingException"
message="A catch statement that catches an exception only to rethrow it should be avoided."
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="CatchStatement">
class="net.sourceforge.pmd.rules.XPathRule">
<description>
Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.
</description>
@ -199,7 +195,7 @@ public class Foo {
<property name="xpath">
<value>
<![CDATA[
.[FormalParameter
//CatchStatement[FormalParameter
/VariableDeclaratorId/@Image = Block/BlockStatement/Statement
/ThrowStatement/Expression/PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix/Name/@Image
and count(Block/BlockStatement/Statement) =1]

View File

@ -291,8 +291,7 @@ public String convert(int i) {
<rule name="StringBufferInstantiationWithChar"
message="Do not instantiate a StringBuffer with a char"
class="net.sourceforge.pmd.rules.DynamicXPathRule"
type="AllocationExpression"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/strings.html#StringBufferInstantiationWithChar">
<description>
StringBuffer sb = new StringBuffer('c'); The
@ -303,7 +302,7 @@ StringBuffer size.
<property name="xpath">
<value>
<![CDATA[
./ClassOrInterfaceType
//AllocationExpression/ClassOrInterfaceType
[@Image='StringBuffer']
/../Arguments/ArgumentList/Expression/PrimaryExpression
/PrimaryPrefix/

View File

@ -21,7 +21,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import net.sourceforge.pmd.rules.DynamicXPathRule;
import net.sourceforge.pmd.rules.XPathRule;
// Note that ruleset parsing may fail on JDK 1.6 beta
// due to this bug - http://www.netbeans.org/issues/show_bug.cgi?id=63257
@ -283,9 +283,20 @@ public class RuleSetFactory {
String attribute = ruleElement.getAttribute("class");
Class c;
if (attribute.equals("net.sourceforge.pmd.rules.DynamicXPathRule")) {
String type = ruleElement.getAttribute("type");
c = DynamicXPathRule.loadClass(classLoader, type);
if ((Language.JAVA.equals(ruleSet.getLanguage()) || ruleSet.getLanguage() == null) &&
attribute.equals("net.sourceforge.pmd.rules.XPathRule")) {
String xpath = null;
for (int i = 0; i < ruleElement.getChildNodes().getLength(); i++) {
Node node = ruleElement.getChildNodes().item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
if (node.getNodeName().equals("properties")) {
Properties p = new Properties();
parsePropertiesNode(p, node);
xpath = p.getProperty("xpath");
}
}
}
c = XPathRule.loadClass(classLoader, xpath, ruleElement.getAttribute("name"));
} else {
c = classLoader.loadClass(attribute);
}

View File

@ -125,7 +125,12 @@ public class DynamicXPathRule extends AbstractRule implements Opcodes {
regexpFunctionRegistered = true;
}
xpath = new BaseXPath(getStringProperty("xpath"), new DocumentNavigator());
String prop = getStringProperty("xpath");
String tail = prop.trim().replaceFirst("^//\\w+", "");
String subquery = '.' + tail.trim();
xpath = new BaseXPath(subquery, new DocumentNavigator());
if (properties.size() > 1) {
SimpleVariableContext vc = new SimpleVariableContext();
for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {

View File

@ -10,6 +10,7 @@ import net.sourceforge.pmd.ast.Node;
import net.sourceforge.pmd.ast.SimpleNode;
import net.sourceforge.pmd.jaxen.DocumentNavigator;
import net.sourceforge.pmd.jaxen.MatchesFunction;
import org.jaxen.BaseXPath;
import org.jaxen.JaxenException;
import org.jaxen.SimpleVariableContext;
@ -29,6 +30,25 @@ import java.util.Map.Entry;
*/
public class XPathRule extends CommonAbstractRule {
public static Class loadClass(ClassLoader classloader, String xpath, String name) {
if (xpath.indexOf('|') != -1) {
//System.err.println(name + " not a dynamic rule: " + xpath.trim().replaceAll("\n", ""));
return XPathRule.class;
}
String part = xpath.trim();
// Need to use DOTALL mode because of potential line terminators
if (!part.matches("(?s)//\\w+\\W.*")) {
//System.err.println(name + " not a dynamic rule: " + xpath.trim().replaceAll("\n", ""));
return XPathRule.class;
}
String tail = part.replaceFirst("^//\\w+", "");
String nodeName = part.substring(2, part.indexOf(tail));
return DynamicXPathRule.loadClass(classloader, nodeName);
}
private XPath xpath;
private boolean regexpFunctionRegistered;