[javascript] Reorganize rules into categories

This commit is contained in:
Andreas Dangel
2017-10-31 15:32:50 +01:00
parent c466179c2a
commit b2f8cc094c
17 changed files with 788 additions and 660 deletions

View File

@ -0,0 +1,195 @@
<?xml version="1.0"?>
<ruleset name="Best Practices"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
<rule name="AvoidWithStatement"
message="Avoid using with - it's bad news"
language="ecmascript"
since="5.0.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_controversial.html#avoidwithstatement">
<description>Avoid using with - it's bad news</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//WithStatement
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
with (object) {
property = 3; // Might be on object, might be on window: who knows.
}
]]>
</example>
</rule>
<rule name="ConsistentReturn"
since="5.0"
message="A function should not mix 'return' statements with and without a result."
class="net.sourceforge.pmd.lang.ecmascript.rule.basic.ConsistentReturnRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_bestpractices.html#consistentreturn">
<description>
ECMAScript does provide for return types on functions, and therefore there is no solid rule as to their usage.
However, when a function does use returns they should all have a value, or all with no value. Mixed return
usage is likely a bug, or at best poor style.
</description>
<priority>2</priority>
<example>
<![CDATA[
// Ok
function foo() {
if (condition1) {
return true;
}
return false;
}
// Bad
function bar() {
if (condition1) {
return;
}
return false;
}
]]>
</example>
</rule>
<rule name="GlobalVariable"
message="Avoid using global variables"
language="ecmascript"
since="5.0"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_bestpractices.html#globalvariable">
<description>
This rule helps to avoid using accidently global variables by simply missing the "var" declaration.
Global variables can lead to side-effects that are hard to debug.
</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Assignment[Name/@GlobalName = 'true']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
function(arg) {
notDeclaredVariable = 1; // this will create a global variable and trigger the rule
var someVar = 1; // this is a local variable, that's ok
window.otherGlobal = 2; // this will not trigger the rule, although it is a global variable.
}
]]>
</example>
</rule>
<rule name="ScopeForInVariable"
language="ecmascript"
since="5.0"
message="The for-in loop variable ''{0}'' should be explicitly scoped with 'var' to avoid pollution."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_bestpractices.html#scopeforinvariable">
<description>
A for-in loop in which the variable name is not explicitly scoped to the enclosing scope with the 'var' keyword can
refer to a variable in an enclosing scope outside the nearest enclosing scope. This will overwrite the
existing value of the variable in the outer scope when the body of the for-in is evaluated. When the for-in loop
has finished, the variable will contain the last value used in the for-in, and the original value from before
the for-in loop will be gone. Since the for-in variable name is most likely intended to be a temporary name, it
is better to explicitly scope the variable name to the nearest enclosing scope with 'var'.
</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ForInLoop[not(child::VariableDeclaration)]/Name[1]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Ok
function foo() {
var p = 'clean';
function() {
var obj = { dirty: 'dirty' };
for (var p in obj) { // Use 'var' here.
obj[p] = obj[p];
}
return x;
}();
// 'p' still has value of 'clean'.
}
// Bad
function bar() {
var p = 'clean';
function() {
var obj = { dirty: 'dirty' };
for (p in obj) { // Oh no, missing 'var' here!
obj[p] = obj[p];
}
return x;
}();
// 'p' is trashed and has value of 'dirty'!
}
]]>
</example>
</rule>
<rule name="UseBaseWithParseInt"
message="Always provide a base when using parseInt() functions"
language="ecmascript"
since="5.0.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_bestpractices.html#usebasewithparseint">
<description>
This rule checks for usages of parseInt. While the second parameter is optional and usually defaults
to 10 (base/radix is 10 for a decimal number), different implementations may behave differently.
It also improves readability, if the base is given.
See also: [parseInt()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt)
</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//FunctionCall/Name[
@Image = 'parseInt'
and
count(../*) < 3
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
parseInt("010"); // unclear, could be interpreted as 10 or 7 (with a base of 7)
parseInt("10", 10); // good
]]>
</example>
</rule>
</ruleset>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="Design"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
</ruleset>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="Documentation"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
</ruleset>

View File

@ -0,0 +1,96 @@
<?xml version="1.0"?>
<ruleset name="Error Prone"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
<rule name="EqualComparison"
language="ecmascript"
since="5.0"
message="Use '==='/'!==' to compare with true/false or Numbers"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_errorprone.html#equalcomparison">
<description>
Using == in condition may lead to unexpected results, as the variables are automatically casted to be of the
same type. The === operator avoids the casting.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//InfixExpression[(@Image = "==" or @Image = "!=")
and
(child::KeywordLiteral[@Image = "true" or @Image = "false"]
or
child::NumberLiteral)
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Ok
if (someVar === true) {
...
}
// Ok
if (someVar !== 3) {
...
}
// Bad
if (someVar == true) {
...
}
// Bad
if (someVar != 3) {
...
}
]]>
</example>
</rule>
<rule name="InnaccurateNumericLiteral"
language="ecmascript"
since="5.0"
message="The numeric literal ''{0}'' will have at different value at runtime."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_errorprone.html#innaccuratenumericliteral">
<description>
The numeric literal will have a different value at runtime, which can happen if you provide too much
precision in a floating point number. This may result in numeric calculations being in error.
</description>
<priority>2</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//NumberLiteral[
@Image != @Number
and translate(@Image, "e", "E") != @Number
and concat(@Image, ".0") != @Number
and @Image != substring-before(translate(@Number, ".", ""), "E")]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
var a = 9; // Ok
var b = 999999999999999; // Ok
var c = 999999999999999999999; // Not good
var w = 1.12e-4; // Ok
var x = 1.12; // Ok
var y = 1.1234567890123; // Ok
var z = 1.12345678901234567; // Not good
]]>
</example>
</rule>
</ruleset>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="Multithreading"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
</ruleset>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="Performance"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
</ruleset>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="Security"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
</description>
</ruleset>

View File

@ -1,151 +1,16 @@
<?xml version="1.0"?>
<ruleset name="Braces"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
The Braces Ruleset contains a collection of braces rules.
</description>
<rule name="IfStmtsMustUseBraces"
language="ecmascript"
since="5.0"
message="Avoid using if statements without curly braces"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_braces.html#ifstmtsmustusebraces">
<description>
Avoid using if statements without using curly braces.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//IfStatement[@Else = "false" and not(child::Scope)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Ok
if (foo) {
x++;
}
// Bad
if (foo)
x++;
]]>
</example>
</rule>
<rule name="IfElseStmtsMustUseBraces"
language="ecmascript"
since="5.0"
message="Avoid using 'if...else' statements without curly braces"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_braces.html#ifelsestmtsmustusebraces">
<description>
Avoid using if..else statements without using curly braces.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ExpressionStatement[parent::IfStatement[@Else = "true"]]
[not(child::Scope)]
[not(child::IfStatement)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Ok
if (foo) {
x++;
} else {
y++;
}
// Bad
if (foo)
x++;
else
y++;
]]>
</example>
</rule>
<rule name="WhileLoopsMustUseBraces"
language="ecmascript"
since="5.0"
message="Avoid using 'while' statements without curly braces"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_braces.html#whileloopsmustusebraces">
<description>
Avoid using 'while' statements without using curly braces.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//WhileLoop[not(child::Scope)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Ok
while (true) {
x++;
}
// Bad
while (true)
x++;
]]>
</example>
</rule>
<rule name="ForLoopsMustUseBraces"
language="ecmascript"
since="5.0"
message="Avoid using 'for' statements without curly braces"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_braces.html#forloopsmustusebraces">
<description>
Avoid using 'for' statements without using curly braces.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ForLoop[not(child::Scope)]
|
//ForInLoop[not(child::Scope)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Ok
for (var i = 0; i < 42; i++) {
foo();
}
// Bad
for (var i = 0; i < 42; i++)
foo();
]]>
</example>
</rule>
<rule ref="category/ecmascript/codestyle.xml/ForLoopsMustUseBraces" deprecated="true" />
<rule ref="category/ecmascript/codestyle.xml/IfElseStmtsMustUseBraces" deprecated="true" />
<rule ref="category/ecmascript/codestyle.xml/IfStmtsMustUseBraces" deprecated="true" />
<rule ref="category/ecmascript/codestyle.xml/WhileLoopsMustUseBraces" deprecated="true" />
</ruleset>

View File

@ -1,39 +1,15 @@
<?xml version="1.0"?>
<ruleset name="Controversial Ecmascript"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
<description>
The Controversial ruleset contains rules that, for whatever reason, are considered controversial.
They are held here to allow people to include them as they see fit within their custom rulesets.
</description>
</description>
<rule name="AvoidWithStatement"
message="Avoid using with - it's bad news"
language="ecmascript"
since="5.0.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_controversial.html#avoidwithstatement">
<description>Avoid using with - it's bad news</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//WithStatement
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
with (object) {
property = 3; // Might be on object, might be on window: who knows.
}
]]>
</example>
</rule>
<rule ref="category/ecmascript/bestpractices.xml/AvoidWithStatement" deprecated="true" />
</ruleset>

View File

@ -3,7 +3,15 @@
#
rulesets.filenames=\
rulesets/ecmascript/basic.xml,\
rulesets/ecmascript/braces.xml,\
rulesets/ecmascript/controversial.xml,\
rulesets/ecmascript/unnecessary.xml
category/ecmascript/bestpractices.xml,\
category/ecmascript/codestyle.xml,\
category/ecmascript/errorprone.xml
#
#empty categories:
#
#category/ecmascript/design.xml,
#category/ecmascript/documentation.xml,
#category/ecmascript/multithreading.xml,
#category/ecmascript/performance.xml,
#category/ecmascript/security.xml,

View File

@ -1,116 +1,15 @@
<?xml version="1.0"?>
<ruleset name="Unnecessary"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
The Unnecessary Ruleset contains a collection of rules for unnecessary code.
</description>
<rule name="UnnecessaryParentheses"
language="ecmascript"
since="5.0"
message="Unnecessary parentheses."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_unnecessary.html#unnecessaryparentheses">
<description>Unnecessary parentheses should be removed.</description>
<priority>4</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ParenthesizedExpression/ParenthesizedExpression
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
var x = 1; // Ok
var y = (1 + 1); // Ok
var z = ((1 + 1)); // Bad
]]>
</example>
</rule>
<rule name="UnnecessaryBlock"
language="ecmascript"
since="5.0"
message="Unnecessary block."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_unnecessary.html#unnecessaryblock">
<description>
An unnecessary Block is present. Such Blocks are often used in other languages to
introduce a new variable scope. Blocks do not behave like this in ECMAScipt, and using them can
be misleading. Considering removing this unnecessary Block.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Block[not(parent::FunctionNode or parent::IfStatement or parent::ForLoop or parent::ForInLoop
or parent::WhileLoop or parent::DoLoop or parent::TryStatement or parent::CatchClause)]
|
//Scope[not(parent::FunctionNode or parent::IfStatement or parent::ForLoop or parent::ForInLoop
or parent::WhileLoop or parent::DoLoop or parent::TryStatement or parent::CatchClause)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
if (foo) {
// Ok
}
if (bar) {
{
// Bad
}
}
]]>
</example>
</rule>
<rule name="NoElseReturn"
language="ecmascript"
since="5.5.0"
message="The else block is unnecessary"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_unnecessary.html#noelsereturn">
<description>
The else block in a if-else-construct is unnecessary if the `if` block contains a return.
Then the content of the else block can be put outside.
See also: &lt;http://eslint.org/docs/rules/no-else-return>
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//IfStatement[@Else="true"][Scope[1]/ReturnStatement]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Bad:
if (x) {
return y;
} else {
return z;
}
// Good:
if (x) {
return y;
}
return z;
]]>
</example>
</rule>
<rule ref="category/ecmascript/codestyle.xml/NoElseReturn" deprecated="true" />
<rule ref="category/ecmascript/codestyle.xml/UnnecessaryBlock" deprecated="true" />
<rule ref="category/ecmascript/codestyle.xml/UnnecessaryParentheses" deprecated="true" />
</ruleset>

View File

@ -8,7 +8,7 @@ import net.sourceforge.pmd.testframework.SimpleAggregatorTst;
public class BasicRulesTest extends SimpleAggregatorTst {
private static final String RULESET = "ecmascript-basic";
private static final String RULESET = "rulesets/ecmascript/basic.xml";
@Override
public void setUp() {

View File

@ -8,7 +8,7 @@ import net.sourceforge.pmd.testframework.SimpleAggregatorTst;
public class BracesRulesTest extends SimpleAggregatorTst {
private static final String RULESET = "ecmascript-braces";
private static final String RULESET = "rulesets/ecmascript/braces.xml";
@Override
public void setUp() {

View File

@ -8,7 +8,7 @@ import net.sourceforge.pmd.testframework.SimpleAggregatorTst;
public class ControversialRulesTest extends SimpleAggregatorTst {
private static final String RULESET = "ecmascript-controversial";
private static final String RULESET = "rulesets/ecmascript/controversial.xml";
@Override
public void setUp() {

View File

@ -8,7 +8,7 @@ import net.sourceforge.pmd.testframework.SimpleAggregatorTst;
public class UnnecessaryRulesTest extends SimpleAggregatorTst {
private static final String RULESET = "ecmascript-unnecessary";
private static final String RULESET = "rulesets/ecmascript/unnecessary.xml";
@Override
public void setUp() {