forked from phoedos/pmd
New DynamicXPathRule class to speed up XPath based rules by providing a base type for the XPath expression.
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4862 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -47,6 +47,7 @@ use of entrySet to iterate over Maps.
|
||||
1.6 added as a valid option for targetjdk.
|
||||
PMD now allows rules to use Type Resolution. This was referenced in patch 1257259.
|
||||
Renderers use less memory when generating reports.
|
||||
New DynamicXPathRule class to speed up XPath based rules by providing a base type for the XPath expression.
|
||||
Performance Refactoring, XPath rules re-written as Java:
|
||||
AssignmentInOperand
|
||||
AvoidDollarSigns
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="IfStatement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#IfStmtsMustUseBraces">
|
||||
<description>
|
||||
Avoid using if statements without using curly braces.
|
||||
@ -20,7 +21,7 @@ Avoid using if statements without using curly braces.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//IfStatement[count(*) < 3][not(Statement/Block)]
|
||||
.[count(*) < 3][not(Statement/Block)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -41,7 +42,8 @@ Avoid using if statements without using curly braces.
|
||||
|
||||
<rule name="WhileLoopsMustUseBraces"
|
||||
message="Avoid using 'while' statements without curly braces"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="WhileStatement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#WhileLoopsMustUseBraces">
|
||||
<description>
|
||||
Avoid using 'while' statements without using curly braces.
|
||||
@ -50,7 +52,7 @@ Avoid using 'while' statements without using curly braces.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//WhileStatement[not(Statement/Block)]
|
||||
.[not(Statement/Block)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -69,7 +71,8 @@ public void doSomething() {
|
||||
|
||||
<rule name="IfElseStmtsMustUseBraces"
|
||||
message="Avoid using 'if...else' statements without curly braces"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Statement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#IfElseStmtsMustUseBraces">
|
||||
<description>
|
||||
Avoid using if..else statements without using curly braces.
|
||||
@ -78,7 +81,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)]
|
||||
@ -105,7 +108,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ForStatement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/braces.html#ForLoopsMustUseBraces">
|
||||
<description>
|
||||
Avoid using 'for' statements without using curly braces.
|
||||
@ -114,7 +118,7 @@ Avoid using 'for' statements without using curly braces.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ForStatement[not(Statement/Block)]
|
||||
.[not(Statement/Block)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
|
@ -11,7 +11,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclarator"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/clone.html#ProperCloneImplementation">
|
||||
<description>
|
||||
Object clone() should be implemented with super.clone().
|
||||
@ -20,7 +21,7 @@ Object clone() should be implemented with super.clone().
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration//MethodDeclarator
|
||||
.
|
||||
[@Image = 'clone']
|
||||
[count(FormalParameters/*) = 0]
|
||||
[count(../Block//*[
|
||||
@ -48,7 +49,8 @@ class Foo{
|
||||
|
||||
<rule name="CloneThrowsCloneNotSupportedException"
|
||||
message="clone() method should throw CloneNotSupportedException"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/clone.html#CloneThrowsCloneNotSupportedException">
|
||||
<description>
|
||||
The method clone() should throw a CloneNotSupportedException.
|
||||
@ -57,7 +59,7 @@ The method clone() should throw a CloneNotSupportedException.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
.//MethodDeclaration
|
||||
.
|
||||
[
|
||||
MethodDeclarator/@Image = 'clone'
|
||||
and count(MethodDeclarator/FormalParameters/*) = 0
|
||||
@ -86,7 +88,8 @@ and count(NameList/Name[contains
|
||||
|
||||
<rule name="CloneMethodMustImplementCloneable"
|
||||
message="clone() method should be implemented only if implementing Cloneable interface"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
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.
|
||||
@ -95,7 +98,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
|
||||
|
@ -15,7 +15,8 @@ most people really dislike :-)
|
||||
|
||||
<rule name="UnnecessaryConstructor"
|
||||
message="Avoid unnecessary constructors - the compiler will generate these for you"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceBody"
|
||||
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,
|
||||
@ -25,8 +26,7 @@ it's public, has an empty body, and takes no arguments.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration
|
||||
/ClassOrInterfaceBody[count(ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)=1]
|
||||
.[count(ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)=1]
|
||||
/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration
|
||||
[@Public='true']
|
||||
[not(FormalParameters/*)]
|
||||
@ -154,7 +154,8 @@ public class Foo {
|
||||
|
||||
<rule name="AtLeastOneConstructor"
|
||||
message="Each class should declare at least one constructor"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#AtLeastOneConstructor">
|
||||
<description>
|
||||
Each class should declare at least one constructor.
|
||||
@ -163,7 +164,7 @@ Each class should declare at least one constructor.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration
|
||||
.
|
||||
[not(ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration)]
|
||||
[@Interface='false']
|
||||
]]>
|
||||
@ -227,7 +228,8 @@ public class Foo {
|
||||
|
||||
<rule name="CallSuperInConstructor"
|
||||
message="It is a good practice to call super() in a constructor"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
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
|
||||
@ -237,7 +239,7 @@ It is a good practice to call super() in a constructor. If super() is not called
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration[ count (ExtendsList/*) > 0 ]
|
||||
.[ count (ExtendsList/*) > 0 ]
|
||||
/ClassOrInterfaceBody
|
||||
/ClassOrInterfaceBodyDeclaration
|
||||
/ConstructorDeclaration[ count (.//ExplicitConstructorInvocation)=0 ]
|
||||
@ -265,7 +267,8 @@ public class Foo extends Bar{
|
||||
|
||||
<rule name="UnnecessaryParentheses"
|
||||
message="This statement may have some unnecessary parentheses"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ReturnStatement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#UnnecessaryParentheses">
|
||||
<description>
|
||||
Sometimes expressions are wrapped in unnecessary parentheses,
|
||||
@ -275,7 +278,7 @@ making them look like a function call.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ReturnStatement
|
||||
.
|
||||
/Expression
|
||||
/PrimaryExpression
|
||||
/PrimaryPrefix
|
||||
@ -319,7 +322,8 @@ public class Foo {
|
||||
|
||||
<rule name="DefaultPackage"
|
||||
message="Use explicit scoping instead of the default package private level"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#DefaultPackage">
|
||||
<description>
|
||||
Use explicit scoping instead of the default package private level.
|
||||
@ -327,7 +331,7 @@ Use explicit scoping instead of the default package private level.
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value><![CDATA[
|
||||
//ClassOrInterfaceDeclaration[@Interface='false']
|
||||
.[@Interface='false']
|
||||
/ClassOrInterfaceBody
|
||||
/ClassOrInterfaceBodyDeclaration
|
||||
/FieldDeclaration[@PackagePrivate='true']
|
||||
@ -340,7 +344,8 @@ Use explicit scoping instead of the default package private level.
|
||||
|
||||
<rule name="BooleanInversion"
|
||||
message="Use bitwise inversion to invert boolean values"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="AssignmentOperator"
|
||||
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.
|
||||
@ -350,7 +355,7 @@ See http://www.javaspecialists.co.za/archive/newsletter.do?issue=042&locale=
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//AssignmentOperator[@Image="="]/../Expression/UnaryExpressionNotPlusMinus[@Image="!"]
|
||||
.[@Image="="]/../Expression/UnaryExpressionNotPlusMinus[@Image="!"]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,8 @@ These rules deal with different problems that can occur with finalizers.
|
||||
|
||||
<rule name="EmptyFinalizer"
|
||||
message="Avoid empty finalize methods"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#EmptyFinalizer">
|
||||
<description>
|
||||
If the finalize() method is empty, then it does not need to exist.
|
||||
@ -21,7 +22,7 @@ If the finalize() method is empty, then it does not need to exist.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
|
||||
.[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
|
||||
/Block[count(*)=0]
|
||||
]]>
|
||||
</value>
|
||||
@ -39,7 +40,8 @@ public class Foo {
|
||||
|
||||
<rule name="FinalizeOnlyCallsSuperFinalize"
|
||||
message="Finalize should do something besides just calling super.finalize()"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeOnlyCallsSuperFinalize">
|
||||
<description>
|
||||
If the finalize() is implemented, it should do something besides just calling
|
||||
@ -49,7 +51,7 @@ super.finalize().
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclaration[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
|
||||
.[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
|
||||
/Block[count(BlockStatement)=1]
|
||||
/BlockStatement[
|
||||
Statement/StatementExpression/PrimaryExpression
|
||||
@ -73,7 +75,8 @@ public class Foo {
|
||||
|
||||
<rule name="FinalizeOverloaded"
|
||||
message="Finalize methods should not be overloaded"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeOverloaded">
|
||||
<description>
|
||||
Methods named finalize() should not have parameters. It is
|
||||
@ -84,7 +87,7 @@ not be called by the VM.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclaration
|
||||
.
|
||||
/MethodDeclarator[@Image='finalize'][FormalParameters[count(*)>0]]
|
||||
]]>
|
||||
</value>
|
||||
@ -104,7 +107,8 @@ public class Foo {
|
||||
|
||||
<rule name="FinalizeDoesNotCallSuperFinalize"
|
||||
message="Last statement in finalize method should be a call to super.finalize()"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeDoesNotCallSuperFinalize">
|
||||
<description>
|
||||
If the finalize() is implemented, its last action should be to call super.finalize.
|
||||
@ -115,7 +119,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[
|
||||
//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
|
||||
.[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
|
||||
/Block
|
||||
/BlockStatement[last()]
|
||||
[not(Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image='finalize'])]
|
||||
@ -141,7 +145,8 @@ public class Foo {
|
||||
|
||||
<rule name="FinalizeShouldBeProtected"
|
||||
message="If you override finalize(), make it protected"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/finalizers.html#FinalizeShouldBeProtected">
|
||||
<description>
|
||||
If you override finalize(), make it protected. If you make
|
||||
@ -151,7 +156,7 @@ If you override finalize(), make it protected. If you make
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclaration[@Protected="false"]
|
||||
.[@Protected="false"]
|
||||
/MethodDeclarator[@Image="finalize"]
|
||||
[not(FormalParameters/*)]
|
||||
]]>
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
<rule name="UseProperClassLoader"
|
||||
message="In J2EE, getClassLoader() might not work as expected. Use Thread.currentThread().getContextClassLoader() instead."
|
||||
class="net.sourceforge.pmd.rules.XPathRule">
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimarySuffix">
|
||||
<description>
|
||||
In J2EE getClassLoader() might not work as expected. Use Thread.currentThread().getContextClassLoader() instead.
|
||||
</description>
|
||||
@ -16,7 +17,7 @@
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//PrimarySuffix[@Image='getClassLoader']
|
||||
.[@Image='getClassLoader']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -31,4 +32,4 @@ public class Foo {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
</ruleset>
|
||||
|
@ -49,7 +49,8 @@ provide getFoo and setFoo methods.
|
||||
|
||||
<rule name="MissingSerialVersionUID"
|
||||
message="Classes implementing Serializable should set a serialVersionUID"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/javabeans.html#MissingSerialVersionUID">
|
||||
<description>
|
||||
Classes that are serializable should provide a serialVersionUID field.
|
||||
@ -58,7 +59,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
|
||||
@ -84,4 +85,4 @@ public class Foo implements java.io.Serializable {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
</ruleset>
|
||||
|
@ -11,7 +11,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#JUnitStaticSuite">
|
||||
<description>
|
||||
The suite() method in a JUnit test needs to be both public and static.
|
||||
@ -20,7 +21,7 @@ The suite() method in a JUnit test needs to be both public and static.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclaration[not(@Static='true') or not(@Public='true')]
|
||||
.[not(@Static='true') or not(@Public='true')]
|
||||
[MethodDeclarator/@Image='suite']
|
||||
[MethodDeclarator/FormalParameters/@ParameterCount=0]
|
||||
]]>
|
||||
@ -42,7 +43,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclarator"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#JUnitSpelling">
|
||||
<description>
|
||||
Some JUnit framework methods are easy to misspell.
|
||||
@ -51,7 +53,7 @@ Some JUnit framework methods are easy to misspell.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclarator[(not(@Image = 'setUp')
|
||||
.[(not(@Image = 'setUp')
|
||||
and translate(@Image, 'SETuP', 'setUp') = 'setUp')
|
||||
or (not(@Image = 'tearDown')
|
||||
and translate(@Image, 'TEARdOWN', 'tearDown') = 'tearDown')]
|
||||
@ -144,7 +146,8 @@ public class CarTest {
|
||||
|
||||
<rule name="UnnecessaryBooleanAssertion"
|
||||
message="assertTrue(true) or similar statements are unnecessary"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="StatementExpression"
|
||||
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.
|
||||
@ -155,7 +158,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
|
||||
@ -190,7 +193,8 @@ public class SimpleTest extends TestCase {
|
||||
|
||||
<rule name="UseAssertEqualsInsteadOfAssertTrue"
|
||||
message="Use assertEquals(x, y) instead of assertTrue(x.equals(y))"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimaryExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UseAssertEqualsInsteadOfAssertTrue">
|
||||
<description>
|
||||
This rule detects JUnit assertions in object equality. These assertions
|
||||
@ -200,7 +204,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
|
||||
@ -226,7 +230,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimaryExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UseAssertSameInsteadOfAssertTrue">
|
||||
<description>
|
||||
This rule detects JUnit assertions in object references equality. These assertions
|
||||
@ -236,7 +241,7 @@ should be made by more specific methods, like assertSame, assertNotSame.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//PrimaryExpression [
|
||||
.[
|
||||
PrimaryPrefix/Name
|
||||
[@Image = 'assertTrue' or @Image = 'assertFalse']
|
||||
]
|
||||
@ -263,7 +268,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimaryExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#UseAssertNullInsteadOfAssertTrue">
|
||||
<description>
|
||||
This rule detects JUnit assertions in object references equality. These assertions
|
||||
@ -273,7 +279,7 @@ public class FooTest extends TestCase {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//PrimaryExpression[
|
||||
.[
|
||||
PrimaryPrefix/Name[@Image = 'assertTrue' or @Image = 'assertFalse']
|
||||
][
|
||||
PrimarySuffix/Arguments/ArgumentList[
|
||||
@ -302,7 +308,8 @@ public class FooTest extends TestCase {
|
||||
|
||||
<rule name="SimplifyBooleanAssertion"
|
||||
message="assertTrue(!expr) can be replaced by assertFalse(expr)"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="StatementExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/junit.html#SimplifyBooleanAssertion">
|
||||
<description>
|
||||
Avoid negation in an assertTrue or assertFalse test.
|
||||
@ -315,7 +322,7 @@ assertFalse(expr);
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//StatementExpression
|
||||
.
|
||||
[
|
||||
.//Name[@Image='assertTrue' or @Image='assertFalse']
|
||||
and
|
||||
|
@ -11,7 +11,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="CatchStatement"
|
||||
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.
|
||||
@ -19,7 +20,7 @@ To make sure the full stacktrace is printed out, use the logging statement with
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value><![CDATA[
|
||||
//CatchStatement/Block/BlockStatement/Statement/StatementExpression
|
||||
./Block/BlockStatement/Statement/StatementExpression
|
||||
/PrimaryExpression[PrimaryPrefix/Name[starts-with(@Image,
|
||||
concat(//ClassOrInterfaceBodyDeclaration/FieldDeclaration
|
||||
[Type//ClassOrInterfaceType[@Image='Log']]
|
||||
@ -46,7 +47,8 @@ public class Main {
|
||||
|
||||
<rule name="ProperLogger"
|
||||
message="Logger should be defined private static final and have the correct class"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceBodyDeclaration"
|
||||
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.
|
||||
@ -57,7 +59,7 @@ public class Main {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceBodyDeclaration[FieldDeclaration//ClassOrInterfaceType[@Image='Log']
|
||||
.[FieldDeclaration//ClassOrInterfaceType[@Image='Log']
|
||||
and
|
||||
not(FieldDeclaration[@Final='true'][@Static='true'][@Private='true'][//VariableDeclaratorId[@Image=$staticLoggerName]]
|
||||
//ArgumentList//ClassOrInterfaceType/@Image = ancestor::ClassOrInterfaceDeclaration/@Image)
|
||||
|
@ -32,7 +32,8 @@ class Foo{
|
||||
|
||||
<rule name="LoggerIsNotStaticFinal"
|
||||
message="The Logger variable declaration does not contain the static and final modifiers"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="VariableDeclarator"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-java.html#LoggerIsNotStaticFinal">
|
||||
<description>
|
||||
In most cases, the Logger can be declared static and final.
|
||||
@ -41,7 +42,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']
|
||||
@ -101,7 +102,8 @@ first -->
|
||||
|
||||
<rule name="SystemPrintln"
|
||||
message="System.out.print is used"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Name"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-java.html#SystemPrintln">
|
||||
<description>
|
||||
System.(out|err).print is used, consider using a logger.
|
||||
@ -110,7 +112,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')
|
||||
@ -136,7 +138,8 @@ class Foo{
|
||||
|
||||
<rule name="AvoidPrintStackTrace"
|
||||
message="Avoid printStackTrace(); use a logger call instead."
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimaryExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/logging-java.html#AvoidPrintStackTrace">
|
||||
<description>
|
||||
Avoid printStackTrace(); use a logger call instead.
|
||||
@ -145,7 +148,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))]]
|
||||
]]>
|
||||
|
@ -13,7 +13,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Type"
|
||||
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.
|
||||
@ -22,7 +23,7 @@ Contains rules about migrating from one JDK version to another. Don't use these
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//Type/ReferenceType/ClassOrInterfaceType[@Image='Vector']
|
||||
./ReferenceType/ClassOrInterfaceType[@Image='Vector']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -41,7 +42,8 @@ public class Foo {
|
||||
|
||||
<rule name="ReplaceHashtableWithMap"
|
||||
message="Consider replacing this Hashtable with the newer java.util.Map"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Type"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#ReplaceHashtableWithMap">
|
||||
<description>
|
||||
Consider replacing this Hashtable with the newer java.util.Map
|
||||
@ -50,7 +52,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//Type/ReferenceType/ClassOrInterfaceType[@Image='Hashtable']
|
||||
./ReferenceType/ClassOrInterfaceType[@Image='Hashtable']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -69,7 +71,8 @@ public class Foo {
|
||||
|
||||
<rule name="ReplaceEnumerationWithIterator"
|
||||
message="Consider replacing this Enumeration with the newer java.util.Iterator"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ImplementsList"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/migrating.html#ReplaceEnumerationWithIterator">
|
||||
<description>
|
||||
Consider replacing this Enumeration with the newer java.util.Iterator
|
||||
@ -78,7 +81,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ImplementsList/ClassOrInterfaceType[@Image='Enumeration']
|
||||
./ClassOrInterfaceType[@Image='Enumeration']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -101,14 +104,15 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="VariableDeclaratorId"
|
||||
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[
|
||||
//VariableDeclaratorId[@Image='enum']
|
||||
.[@Image='enum']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -127,14 +131,15 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="VariableDeclaratorId"
|
||||
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[
|
||||
//VariableDeclaratorId[@Image='assert']
|
||||
.[@Image='assert']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -153,13 +158,14 @@ public class Foo implements Enumeration {
|
||||
|
||||
<rule name="IntegerInstantiation"
|
||||
message="Avoid instantiating Integer objects. Call Integer.valueOf() instead."
|
||||
class="net.sourceforge.pmd.rules.XPathRule">
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimaryPrefix">
|
||||
<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'
|
||||
|
@ -12,7 +12,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="VariableDeclaratorId"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#ShortVariable">
|
||||
<description>
|
||||
Detects when a field, local, or parameter has a very short name.
|
||||
@ -21,7 +22,7 @@ Detects when a field, local, or parameter has a very short name.
|
||||
<property name="xpath" pluginname="true">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//VariableDeclaratorId[string-length(@Image) < 3]
|
||||
.[string-length(@Image) < 3]
|
||||
[not(ancestor::ForInit)]
|
||||
[not((ancestor::FormalParameter) and (ancestor::TryStatement))]
|
||||
]]>
|
||||
@ -46,7 +47,8 @@ public class Something {
|
||||
|
||||
<rule name="LongVariable"
|
||||
message="Avoid excessively long variable names like {0}"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="VariableDeclaratorId"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#LongVariable">
|
||||
<description>
|
||||
Detects when a field, formal or local variable is declared with a long name.
|
||||
@ -57,7 +59,7 @@ Detects when a field, formal or local variable is declared with a long name.
|
||||
<property name="xpath" pluginname="true">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//VariableDeclaratorId[string-length(@Image) > $minimum]
|
||||
.[string-length(@Image) > $minimum]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -79,7 +81,8 @@ public class Something {
|
||||
|
||||
<rule name="ShortMethodName"
|
||||
message="Avoid using short method names"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclarator"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#ShortMethodName">
|
||||
<description>
|
||||
Detects when very short method names are used.
|
||||
@ -89,7 +92,7 @@ Detects when very short method names are used.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclarator[string-length(@Image) < 3]
|
||||
.[string-length(@Image) < 3]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -167,7 +170,8 @@ public class Foo {}
|
||||
|
||||
<rule name="AbstractNaming"
|
||||
message="Abstract classes should be named 'AbstractXXX'"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#AbstractNaming">
|
||||
<description>
|
||||
Abstract classes should be named 'AbstractXXX'.
|
||||
@ -177,7 +181,7 @@ Abstract classes should be named 'AbstractXXX'.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration
|
||||
.
|
||||
[@Abstract='true' and @Interface='false']
|
||||
[not (starts-with(@Image,'Abstract'))]
|
||||
]]>
|
||||
@ -250,7 +254,8 @@ public class Foo {
|
||||
|
||||
<rule name="SuspiciousConstantFieldName"
|
||||
message="The field name indicates a constant but its modifiers do not"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#SuspiciousConstantFieldName">
|
||||
<description>
|
||||
A field name is all in uppercase characters, which in Sun's Java naming
|
||||
@ -260,7 +265,7 @@ conventions indicate a constant. However, the field is not final.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration[@Interface='false']
|
||||
.[@Interface='false']
|
||||
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/FieldDeclaration
|
||||
[@Final='false']
|
||||
[VariableDeclarator/VariableDeclaratorId[upper-case(@Image)=@Image]]
|
||||
@ -284,7 +289,8 @@ public class Foo {
|
||||
<rule
|
||||
name="SuspiciousEqualsMethodName"
|
||||
message="The method name and parameter number are suspiciously close to equals(Object)"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="MethodDeclarator"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#SuspiciousEqualsMethodName">
|
||||
<description>
|
||||
The method name and parameter number are suspiciously close to
|
||||
@ -295,7 +301,7 @@ method.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//MethodDeclarator [
|
||||
.[
|
||||
(
|
||||
@Image = 'equals'
|
||||
and count(FormalParameters/*) = 1
|
||||
@ -391,7 +397,8 @@ public class Foo {
|
||||
|
||||
<rule name="NoPackage"
|
||||
message="All classes and interfaces must belong to a named package"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="ClassOrInterfaceDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#NoPackage">
|
||||
<description>
|
||||
Detects when a class or interface does not have a package definition.
|
||||
@ -400,7 +407,7 @@ Detects when a class or interface does not have a package definition.
|
||||
<property name="xpath" pluginname="true">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration[count(preceding::PackageDeclaration) = 0]
|
||||
.[count(preceding::PackageDeclaration) = 0]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -417,7 +424,8 @@ public class ClassInDefaultPackage {
|
||||
|
||||
<rule name="PackageCase"
|
||||
message="Package name contains upper case characters"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PackageDeclaration"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#PackageCase">
|
||||
<description>
|
||||
Detects when a package definition contains upper case characters.
|
||||
@ -426,7 +434,7 @@ public class ClassInDefaultPackage {
|
||||
<property name="xpath" pluginname="true">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//PackageDeclaration/Name[lower-case(@Image)!=@Image]
|
||||
./Name[lower-case(@Image)!=@Image]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -443,7 +451,8 @@ public class SomeClass {
|
||||
|
||||
<rule name="MisleadingVariableName"
|
||||
message="Avoid naming non-fields with the prefix 'm_'"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="VariableDeclaratorId"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#MisleadingVariableName">
|
||||
<description>
|
||||
Detects when a non-field has a name starting with 'm_'. This usually
|
||||
@ -453,7 +462,7 @@ indicates a field and thus is confusing.
|
||||
<property name="xpath" pluginname="true">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//VariableDeclaratorId
|
||||
.
|
||||
[starts-with(@Image, 'm_')]
|
||||
[not (../../../FieldDeclaration)]
|
||||
]]>
|
||||
|
@ -70,7 +70,8 @@ public class Something {
|
||||
|
||||
<rule name="UseArrayListInsteadOfVector"
|
||||
message="Use ArrayList instead of Vector"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="AllocationExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#UseArrayListInsteadOfVector">
|
||||
<description>
|
||||
ArrayList is a much better Collection implementation than Vector.
|
||||
@ -79,7 +80,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>
|
||||
@ -101,7 +102,8 @@ 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.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="PrimaryExpression"
|
||||
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.
|
||||
@ -110,7 +112,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
|
||||
@ -164,7 +166,8 @@ public class Foo {
|
||||
|
||||
<rule name="UseArraysAsList"
|
||||
message="Use asList instead of tight loops"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Statement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#UseArraysAsList">
|
||||
<description>
|
||||
The class java.util.Arrays has a "asList" method that
|
||||
@ -176,7 +179,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//Statement[
|
||||
.[
|
||||
(ForStatement) and (count(.//IfStatement)=0)
|
||||
]
|
||||
//StatementExpression[
|
||||
@ -228,7 +231,8 @@ public class Foo {
|
||||
|
||||
<rule name="AvoidArrayLoops"
|
||||
message="System.arrayCopy is more efficient"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Statement"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/optimizations.html#AvoidArrayLoops">
|
||||
<description>
|
||||
Instead of copying data between two arrays, use
|
||||
@ -238,7 +242,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//Statement[(ForStatement or WhileStatement) and
|
||||
.[(ForStatement or WhileStatement) and
|
||||
count(*//AssignmentOperator[@Image = '='])=1
|
||||
and
|
||||
*/Statement
|
||||
|
@ -12,7 +12,8 @@ These are new rules that are still in progress.
|
||||
|
||||
<rule name="AvoidUsingOctalValues"
|
||||
message="Do not start a literal by 0 unless it's an octal value"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="Literal"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/basic.html#AvoidUsingOctalValues">
|
||||
<description>
|
||||
Integers literals should not start with zero.
|
||||
@ -24,7 +25,7 @@ interprated as an octal.
|
||||
<value>
|
||||
<![CDATA[
|
||||
|
||||
//Literal
|
||||
.
|
||||
[(starts-with(@Image, 0))]
|
||||
[not(substring(@Image, 2, 1) = 'x')]
|
||||
[not(substring(@Image, 2, 1) = 'L')]
|
||||
|
@ -79,7 +79,8 @@ public class Foo {
|
||||
|
||||
<rule name="AvoidCatchingNPE"
|
||||
message="Avoid catching NullPointerException; consider removing the cause of the NPE."
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="CatchStatement"
|
||||
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.
|
||||
@ -100,7 +101,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//CatchStatement/FormalParameter/Type
|
||||
./FormalParameter/Type
|
||||
/ReferenceType/ClassOrInterfaceType[@Image='NullPointerException']
|
||||
]]>
|
||||
</value>
|
||||
@ -110,7 +111,8 @@ public class Foo {
|
||||
|
||||
<rule name="AvoidThrowingRawExceptionTypes"
|
||||
message="Avoid throwing raw exception types."
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="AllocationExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/strictexception.html#AvoidThrowingRawExceptionTypes">
|
||||
<description>
|
||||
Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable,
|
||||
@ -130,7 +132,7 @@ public void bar() throws Exception {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//AllocationExpression
|
||||
.
|
||||
/ClassOrInterfaceType[
|
||||
@Image='Throwable' or
|
||||
@Image='Exception' or
|
||||
@ -144,7 +146,8 @@ public void bar() throws Exception {
|
||||
|
||||
<rule name="AvoidThrowingNullPointerException"
|
||||
message="Avoid throwing null pointer exceptions."
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="AllocationExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/strictexception.html#AvoidThrowingNullPointerException">
|
||||
<description>
|
||||
Avoid throwing a NullPointerException - it's confusing because most people will assume that the
|
||||
@ -165,7 +168,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//AllocationExpression/ClassOrInterfaceType[@Image='NullPointerException']
|
||||
./ClassOrInterfaceType[@Image='NullPointerException']
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -174,7 +177,8 @@ 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.XPathRule">
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="CatchStatement">
|
||||
<description>
|
||||
Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.
|
||||
</description>
|
||||
@ -195,7 +199,7 @@ public class Foo {
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//CatchStatement[FormalParameter
|
||||
.[FormalParameter
|
||||
/VariableDeclaratorId/@Image = Block/BlockStatement/Statement
|
||||
/ThrowStatement/Expression/PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix/Name/@Image
|
||||
and count(Block/BlockStatement/Statement) =1]
|
||||
|
@ -291,7 +291,8 @@ public String convert(int i) {
|
||||
|
||||
<rule name="StringBufferInstantiationWithChar"
|
||||
message="Do not instantiate a StringBuffer with a char"
|
||||
class="net.sourceforge.pmd.rules.XPathRule"
|
||||
class="net.sourceforge.pmd.rules.DynamicXPathRule"
|
||||
type="AllocationExpression"
|
||||
externalInfoUrl="http://pmd.sourceforge.net/rules/strings.html#StringBufferInstantiationWithChar">
|
||||
<description>
|
||||
StringBuffer sb = new StringBuffer('c'); The
|
||||
@ -302,7 +303,7 @@ StringBuffer size.
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//AllocationExpression/ClassOrInterfaceType
|
||||
./ClassOrInterfaceType
|
||||
[@Image='StringBuffer']
|
||||
/../Arguments/ArgumentList/Expression/PrimaryExpression
|
||||
/PrimaryPrefix/
|
||||
|
@ -21,6 +21,8 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.sourceforge.pmd.rules.DynamicXPathRule;
|
||||
|
||||
// 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
|
||||
|
||||
@ -280,7 +282,14 @@ public class RuleSetFactory {
|
||||
Element ruleElement = (Element) ruleNode;
|
||||
|
||||
String attribute = ruleElement.getAttribute("class");
|
||||
Rule rule = (Rule) classLoader.loadClass(attribute).newInstance();
|
||||
Class c;
|
||||
if (attribute.equals("net.sourceforge.pmd.rules.DynamicXPathRule")) {
|
||||
String type = ruleElement.getAttribute("type");
|
||||
c = DynamicXPathRule.loadClass(classLoader, type);
|
||||
} else {
|
||||
c = classLoader.loadClass(attribute);
|
||||
}
|
||||
Rule rule = (Rule) c.newInstance();
|
||||
|
||||
rule.setName(ruleElement.getAttribute("name"));
|
||||
rule.setMessage(ruleElement.getAttribute("message"));
|
||||
|
142
pmd/src/net/sourceforge/pmd/rules/DynamicXPathRule.java
Normal file
142
pmd/src/net/sourceforge/pmd/rules/DynamicXPathRule.java
Normal file
@ -0,0 +1,142 @@
|
||||
package net.sourceforge.pmd.rules;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.sourceforge.pmd.AbstractRule;
|
||||
import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
|
||||
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;
|
||||
import org.jaxen.XPath;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class DynamicXPathRule extends AbstractRule implements Opcodes {
|
||||
|
||||
protected DynamicXPathRule() {
|
||||
}
|
||||
|
||||
private static HashMap classes = new HashMap();
|
||||
|
||||
public static synchronized Class loadClass(ClassLoader classloader, String type) {
|
||||
Class c = (Class) classes.get(type);
|
||||
if (c == null) {
|
||||
byte bytecode[] = buildClass(type);
|
||||
c = new ByteArrayClassLoader(classloader).loadClass(bytecode);
|
||||
|
||||
classes.put(type, c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private static class ByteArrayClassLoader extends ClassLoader {
|
||||
ByteArrayClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
Class loadClass(byte[] data) {
|
||||
return defineClass(null, data, 0, data.length, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] buildClass(String type) {
|
||||
String className = "net/sourceforge/pmd/rules/" + type + "XPathRule";
|
||||
String methodSig = "(Lnet/sourceforge/pmd/ast/AST" + type + ";Ljava/lang/Object;)Ljava/lang/Object;";
|
||||
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
MethodVisitor mv;
|
||||
|
||||
cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, className, null, "net/sourceforge/pmd/rules/DynamicXPathRule", null);
|
||||
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "net/sourceforge/pmd/rules/DynamicXPathRule", "<init>", "()V");
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitMaxs(1, 1);
|
||||
mv.visitEnd();
|
||||
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "visit", methodSig, null, null);
|
||||
mv.visitCode();
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitVarInsn(ALOAD, 2);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, className, "evaluate", "(Lnet/sourceforge/pmd/ast/Node;Ljava/lang/Object;)V");
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitVarInsn(ALOAD, 2);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "net/sourceforge/pmd/rules/DynamicXPathRule", "visit", methodSig);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitMaxs(3, 3);
|
||||
mv.visitEnd();
|
||||
|
||||
cw.visitEnd();
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
private XPath xpath;
|
||||
|
||||
private boolean regexpFunctionRegistered;
|
||||
|
||||
/**
|
||||
* Evaluate the AST with compilationUnit as root-node, against
|
||||
* the XPath expression found as property with name "xpath".
|
||||
* All matches are reported as violations.
|
||||
*
|
||||
* @param compilationUnit the Node that is the root of the AST to be checked
|
||||
* @param data
|
||||
*/
|
||||
public void evaluate(Node compilationUnit, Object data) {
|
||||
try {
|
||||
initializeXPathExpression();
|
||||
List results = xpath.selectNodes(compilationUnit);
|
||||
for (Iterator i = results.iterator(); i.hasNext();) {
|
||||
SimpleNode n = (SimpleNode) i.next();
|
||||
if (n instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) {
|
||||
addViolation(data, n, n.getImage());
|
||||
} else {
|
||||
addViolation(data, (SimpleNode) n, getMessage());
|
||||
}
|
||||
}
|
||||
} catch (JaxenException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeXPathExpression() throws JaxenException {
|
||||
if (xpath != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!regexpFunctionRegistered) {
|
||||
MatchesFunction.registerSelfInSimpleContext();
|
||||
regexpFunctionRegistered = true;
|
||||
}
|
||||
|
||||
xpath = new BaseXPath(getStringProperty("xpath"), new DocumentNavigator());
|
||||
if (properties.size() > 1) {
|
||||
SimpleVariableContext vc = new SimpleVariableContext();
|
||||
for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
|
||||
Entry e = (Entry) i.next();
|
||||
if (!"xpath".equals(e.getKey())) {
|
||||
vc.setVariableValue((String) e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
xpath.setVariableContext(vc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user