From 593226ce2abd1cde659a2ca98f11c12828526913 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 31 Oct 2017 15:58:35 +0100 Subject: [PATCH] [doc] Update generated ecmascript ruleset files --- docs/pages/pmd/rules/ecmascript.md | 49 ++- docs/pages/pmd/rules/ecmascript/basic.md | 378 ------------------ .../pmd/rules/ecmascript/bestpractices.md | 195 +++++++++ docs/pages/pmd/rules/ecmascript/braces.md | 137 ------- docs/pages/pmd/rules/ecmascript/codestyle.md | 365 +++++++++++++++++ .../pmd/rules/ecmascript/controversial.md | 34 -- docs/pages/pmd/rules/ecmascript/errorprone.md | 87 ++++ .../pages/pmd/rules/ecmascript/unnecessary.md | 107 ----- 8 files changed, 670 insertions(+), 682 deletions(-) delete mode 100644 docs/pages/pmd/rules/ecmascript/basic.md create mode 100644 docs/pages/pmd/rules/ecmascript/bestpractices.md delete mode 100644 docs/pages/pmd/rules/ecmascript/braces.md create mode 100644 docs/pages/pmd/rules/ecmascript/codestyle.md delete mode 100644 docs/pages/pmd/rules/ecmascript/controversial.md create mode 100644 docs/pages/pmd/rules/ecmascript/errorprone.md delete mode 100644 docs/pages/pmd/rules/ecmascript/unnecessary.md diff --git a/docs/pages/pmd/rules/ecmascript.md b/docs/pages/pmd/rules/ecmascript.md index 84bbba4703..aea2b60be7 100644 --- a/docs/pages/pmd/rules/ecmascript.md +++ b/docs/pages/pmd/rules/ecmascript.md @@ -5,33 +5,30 @@ folder: pmd/rules --- List of rulesets and rules contained in each ruleset. -* [Basic Ecmascript](pmd_rules_ecmascript_basic.html): Rules concerning basic ECMAScript guidelines. -* [Braces](pmd_rules_ecmascript_braces.html): The Braces Ruleset contains a collection of braces rules. -* [Controversial Ecmascript](pmd_rules_ecmascript_controversial.html): 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. -* [Unnecessary](pmd_rules_ecmascript_unnecessary.html): The Unnecessary Ruleset contains a collection of rules for unnecessary code. +* [Best Practices](pmd_rules_ecmascript_bestpractices.html): +* [Code Style](pmd_rules_ecmascript_codestyle.html): +* [Error Prone](pmd_rules_ecmascript_errorprone.html): -## Basic Ecmascript -* [AssignmentInOperand](pmd_rules_ecmascript_basic.html#assignmentinoperand): Avoid assignments in operands; this can make code more complicated and harder to read. This is s... -* [AvoidTrailingComma](pmd_rules_ecmascript_basic.html#avoidtrailingcomma): This rule helps improve code portability due to differences in browser treatment of trailing comm... -* [ConsistentReturn](pmd_rules_ecmascript_basic.html#consistentreturn): ECMAScript does provide for return types on functions, and therefore there is no solid rule as to... -* [EqualComparison](pmd_rules_ecmascript_basic.html#equalcomparison): Using == in condition may lead to unexpected results, as the variables are automatically casted t... -* [GlobalVariable](pmd_rules_ecmascript_basic.html#globalvariable): This rule helps to avoid using accidently global variables by simply missing the "var" declaratio... -* [InnaccurateNumericLiteral](pmd_rules_ecmascript_basic.html#innaccuratenumericliteral): The numeric literal will have at different value at runtime, which can happen if you provide too ... -* [ScopeForInVariable](pmd_rules_ecmascript_basic.html#scopeforinvariable): A for-in loop in which the variable name is not explicitly scoped to the enclosing scope with the... -* [UnreachableCode](pmd_rules_ecmascript_basic.html#unreachablecode): A 'return', 'break', 'continue', or 'throw' statement should be the last in a block. Statements a... -* [UseBaseWithParseInt](pmd_rules_ecmascript_basic.html#usebasewithparseint): This rule checks for usages of parseInt. While the second parameter is optional and usually defau... +## Best Practices +* [AvoidWithStatement](pmd_rules_ecmascript_bestpractices.html#avoidwithstatement): Avoid using with - it's bad news +* [ConsistentReturn](pmd_rules_ecmascript_bestpractices.html#consistentreturn): ECMAScript does provide for return types on functions, and therefore there is no solid rule as to... +* [GlobalVariable](pmd_rules_ecmascript_bestpractices.html#globalvariable): This rule helps to avoid using accidently global variables by simply missing the "var" declaratio... +* [ScopeForInVariable](pmd_rules_ecmascript_bestpractices.html#scopeforinvariable): A for-in loop in which the variable name is not explicitly scoped to the enclosing scope with the... +* [UseBaseWithParseInt](pmd_rules_ecmascript_bestpractices.html#usebasewithparseint): This rule checks for usages of parseInt. While the second parameter is optional and usually defau... -## Braces -* [ForLoopsMustUseBraces](pmd_rules_ecmascript_braces.html#forloopsmustusebraces): Avoid using 'for' statements without using curly braces. -* [IfElseStmtsMustUseBraces](pmd_rules_ecmascript_braces.html#ifelsestmtsmustusebraces): Avoid using if..else statements without using curly braces. -* [IfStmtsMustUseBraces](pmd_rules_ecmascript_braces.html#ifstmtsmustusebraces): Avoid using if statements without using curly braces. -* [WhileLoopsMustUseBraces](pmd_rules_ecmascript_braces.html#whileloopsmustusebraces): Avoid using 'while' statements without using curly braces. +## Code Style +* [AssignmentInOperand](pmd_rules_ecmascript_codestyle.html#assignmentinoperand): Avoid assignments in operands; this can make code more complicated and harder to read. This is s... +* [AvoidTrailingComma](pmd_rules_ecmascript_codestyle.html#avoidtrailingcomma): This rule helps improve code portability due to differences in browser treatment of trailing comm... +* [ForLoopsMustUseBraces](pmd_rules_ecmascript_codestyle.html#forloopsmustusebraces): Avoid using 'for' statements without using curly braces. +* [IfElseStmtsMustUseBraces](pmd_rules_ecmascript_codestyle.html#ifelsestmtsmustusebraces): Avoid using if..else statements without using curly braces. +* [IfStmtsMustUseBraces](pmd_rules_ecmascript_codestyle.html#ifstmtsmustusebraces): Avoid using if statements without using curly braces. +* [NoElseReturn](pmd_rules_ecmascript_codestyle.html#noelsereturn): The else block in a if-else-construct is unnecessary if the 'if' block contains a return.Then the... +* [UnnecessaryBlock](pmd_rules_ecmascript_codestyle.html#unnecessaryblock): An unnecessary Block is present. Such Blocks are often used in other languages tointroduce a new... +* [UnnecessaryParentheses](pmd_rules_ecmascript_codestyle.html#unnecessaryparentheses): Unnecessary parentheses should be removed. +* [UnreachableCode](pmd_rules_ecmascript_codestyle.html#unreachablecode): A 'return', 'break', 'continue', or 'throw' statement should be the last in a block. Statements a... +* [WhileLoopsMustUseBraces](pmd_rules_ecmascript_codestyle.html#whileloopsmustusebraces): Avoid using 'while' statements without using curly braces. -## Controversial Ecmascript -* [AvoidWithStatement](pmd_rules_ecmascript_controversial.html#avoidwithstatement): Avoid using with - it's bad news - -## Unnecessary -* [NoElseReturn](pmd_rules_ecmascript_unnecessary.html#noelsereturn): The else block in a if-else-construct is unnecessary if the 'if' block contains a return.Then the... -* [UnnecessaryBlock](pmd_rules_ecmascript_unnecessary.html#unnecessaryblock): An unnecessary Block is present. Such Blocks are often used in other languages tointroduce a new... -* [UnnecessaryParentheses](pmd_rules_ecmascript_unnecessary.html#unnecessaryparentheses): Unnecessary parentheses should be removed. +## Error Prone +* [EqualComparison](pmd_rules_ecmascript_errorprone.html#equalcomparison): Using == in condition may lead to unexpected results, as the variables are automatically casted t... +* [InnaccurateNumericLiteral](pmd_rules_ecmascript_errorprone.html#innaccuratenumericliteral): The numeric literal will have a different value at runtime, which can happen if you provide too m... diff --git a/docs/pages/pmd/rules/ecmascript/basic.md b/docs/pages/pmd/rules/ecmascript/basic.md deleted file mode 100644 index 9663b6c9d0..0000000000 --- a/docs/pages/pmd/rules/ecmascript/basic.md +++ /dev/null @@ -1,378 +0,0 @@ ---- -title: Basic Ecmascript -summary: Rules concerning basic ECMAScript guidelines. -permalink: pmd_rules_ecmascript_basic.html -folder: pmd/rules/ecmascript -sidebaractiveurl: /pmd_rules_ecmascript.html -editmepath: ../pmd-javascript/src/main/resources/rulesets/ecmascript/basic.xml -keywords: Basic Ecmascript, AssignmentInOperand, UnreachableCode, InnaccurateNumericLiteral, ConsistentReturn, ScopeForInVariable, EqualComparison, GlobalVariable, AvoidTrailingComma, UseBaseWithParseInt ---- -## AssignmentInOperand - -**Since:** PMD 5.0 - -**Priority:** Medium High (2) - -Avoid assignments in operands; this can make code more complicated and harder to read. This is sometime -indicative of the bug where the assignment operator '=' was used instead of the equality operator '=='. - -``` -//IfStatement[$allowIf = "false"]/child::node()[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] -| - //WhileLoop[$allowWhile = "false"]/child::node()[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] -| - //DoLoop[$allowWhile = "false"]/child::node()[2]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] -| - //ForLoop[$allowFor = "false"]/child::node()[2]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] -| - //ConditionalExpression[$allowTernary = "false"]/child::node()[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] -| - //ConditionalExpression[$allowTernaryResults = "false"]/child::node()[position() = 2 or position() = 3]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] -``` - -**Example(s):** - -``` javascript -var x = 2; -// Bad -if ((x = getX()) == 3) { - alert('3!'); -} - -function getX() { - return 3; -} -``` - -**This rule has the following properties:** - -|Name|Default Value|Description| -|----|-------------|-----------| -|allowIf|false|Allow assignment within the conditional expression of an if statement| -|allowFor|false|Allow assignment within the conditional expression of a for statement| -|allowWhile|false|Allow assignment within the conditional expression of a while statement| -|allowTernary|false|Allow assignment within the conditional expression of a ternary operator| -|allowTernaryResults|false|Allow assignment within the result expressions of a ternary operator| -|allowIncrementDecrement|false|Allow increment or decrement operators within the conditional expression of an if, for, or while statement| - -**Use this rule by referencing it:** -``` xml - -``` - -## AvoidTrailingComma - -**Since:** PMD 5.1 - -**Priority:** High (1) - -This rule helps improve code portability due to differences in browser treatment of trailing commas in object or array literals. - -``` -//ObjectLiteral[$allowObjectLiteral = "false" and @TrailingComma = 'true'] -| -//ArrayLiteral[$allowArrayLiteral = "false" and @TrailingComma = 'true'] -``` - -**Example(s):** - -``` javascript -function(arg) { - var obj1 = { a : 1 }; // Ok - var arr1 = [ 1, 2 ]; // Ok - - var obj2 = { a : 1, }; // Syntax error in some browsers! - var arr2 = [ 1, 2, ]; // Length 2 or 3 depending on the browser! -} -``` - -**This rule has the following properties:** - -|Name|Default Value|Description| -|----|-------------|-----------| -|allowObjectLiteral|false|Allow a trailing comma within an object literal| -|allowArrayLiteral|false|Allow a trailing comma within an array literal| - -**Use this rule by referencing it:** -``` xml - -``` - -## ConsistentReturn - -**Since:** PMD 5.0 - -**Priority:** Medium High (2) - -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. - -**This rule is defined by the following Java class:** [net.sourceforge.pmd.lang.ecmascript.rule.basic.ConsistentReturnRule](https://github.com/pmd/pmd/blob/master/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/rule/basic/ConsistentReturnRule.java) - -**Example(s):** - -``` javascript -// Ok -function foo() { - if (condition1) { - return true; - } - return false; -} - -// Bad -function bar() { - if (condition1) { - return; - } - return false; -} -``` - -**This rule has the following properties:** - -|Name|Default Value|Description| -|----|-------------|-----------| -|rhinoLanguageVersion|VERSION_DEFAULT|Specifies the Rhino Language Version to use for parsing. Defaults to Rhino default.| -|recordingLocalJsDocComments|true|Specifies that JsDoc comments are produced in the AST.| -|recordingComments|true|Specifies that comments are produced in the AST.| - -**Use this rule by referencing it:** -``` xml - -``` - -## EqualComparison - -**Since:** PMD 5.0 - -**Priority:** Medium (3) - -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. - -``` -//InfixExpression[(@Image = "==" or @Image = "!=") - and - (child::KeywordLiteral[@Image = "true" or @Image = "false"] - or - child::NumberLiteral) -] -``` - -**Example(s):** - -``` javascript -// Ok -if (someVar === true) { - ... -} -// Ok -if (someVar !== 3) { - ... -} -// Bad -if (someVar == true) { - ... -} -// Bad -if (someVar != 3) { - ... -} -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## GlobalVariable - -**Since:** PMD 5.0 - -**Priority:** High (1) - -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. - -``` -//Assignment[Name/@GlobalName = 'true'] -``` - -**Example(s):** - -``` javascript -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. -} -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## InnaccurateNumericLiteral - -**Since:** PMD 5.0 - -**Priority:** Medium High (2) - -The numeric literal will have at 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. - -``` -//NumberLiteral[ - @Image != @Number - and translate(@Image, "e", "E") != @Number - and concat(@Image, ".0") != @Number - and @Image != substring-before(translate(@Number, ".", ""), "E")] -``` - -**Example(s):** - -``` javascript -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 -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## ScopeForInVariable - -**Since:** PMD 5.0 - -**Priority:** High (1) - -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'. - -``` -//ForInLoop[not(child::VariableDeclaration)]/Name[1] -``` - -**Example(s):** - -``` javascript -// 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'! -} -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## UnreachableCode - -**Since:** PMD 5.0 - -**Priority:** High (1) - -A 'return', 'break', 'continue', or 'throw' statement should be the last in a block. Statements after these -will never execute. This is a bug, or extremely poor style. - -``` -//ReturnStatement[following-sibling::node()] -| - //ContinueStatement[following-sibling::node()] -| - //BreakStatement[following-sibling::node()] -| - //ThrowStatement[following-sibling::node()] -``` - -**Example(s):** - -``` javascript -// Ok -function foo() { - return 1; -} -// Bad -function bar() { - var x = 1; - return x; - x = 2; -} -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## UseBaseWithParseInt - -**Since:** PMD 5.0.1 - -**Priority:** High (1) - -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) - -``` -//FunctionCall/Name[ - @Image = 'parseInt' - and - count(../*) < 3 -] -``` - -**Example(s):** - -``` javascript -parseInt("010"); // unclear, could be interpreted as 10 or 7 (with a base of 7) - -parseInt("10", 10); // good -``` - -**Use this rule by referencing it:** -``` xml - -``` - diff --git a/docs/pages/pmd/rules/ecmascript/bestpractices.md b/docs/pages/pmd/rules/ecmascript/bestpractices.md new file mode 100644 index 0000000000..d4cd1f0aaf --- /dev/null +++ b/docs/pages/pmd/rules/ecmascript/bestpractices.md @@ -0,0 +1,195 @@ +--- +title: Best Practices +summary: +permalink: pmd_rules_ecmascript_bestpractices.html +folder: pmd/rules/ecmascript +sidebaractiveurl: /pmd_rules_ecmascript.html +editmepath: ../pmd-javascript/src/main/resources/category/ecmascript/bestpractices.xml +keywords: Best Practices, AvoidWithStatement, ConsistentReturn, GlobalVariable, ScopeForInVariable, UseBaseWithParseInt +--- +## AvoidWithStatement + +**Since:** PMD 5.0.1 + +**Priority:** High (1) + +Avoid using with - it's bad news + +``` +//WithStatement +``` + +**Example(s):** + +``` javascript +with (object) { + property = 3; // Might be on object, might be on window: who knows. +} +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## ConsistentReturn + +**Since:** PMD 5.0 + +**Priority:** Medium High (2) + +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. + +**This rule is defined by the following Java class:** [net.sourceforge.pmd.lang.ecmascript.rule.bestpractices.ConsistentReturnRule](https://github.com/pmd/pmd/blob/master/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnRule.java) + +**Example(s):** + +``` javascript +// Ok +function foo() { + if (condition1) { + return true; + } + return false; +} + +// Bad +function bar() { + if (condition1) { + return; + } + return false; +} +``` + +**This rule has the following properties:** + +|Name|Default Value|Description| +|----|-------------|-----------| +|rhinoLanguageVersion|VERSION_DEFAULT|Specifies the Rhino Language Version to use for parsing. Defaults to Rhino default.| +|recordingLocalJsDocComments|true|Specifies that JsDoc comments are produced in the AST.| +|recordingComments|true|Specifies that comments are produced in the AST.| + +**Use this rule by referencing it:** +``` xml + +``` + +## GlobalVariable + +**Since:** PMD 5.0 + +**Priority:** High (1) + +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. + +``` +//Assignment[Name/@GlobalName = 'true'] +``` + +**Example(s):** + +``` javascript +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. +} +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## ScopeForInVariable + +**Since:** PMD 5.0 + +**Priority:** High (1) + +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'. + +``` +//ForInLoop[not(child::VariableDeclaration)]/Name[1] +``` + +**Example(s):** + +``` javascript +// 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'! +} +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## UseBaseWithParseInt + +**Since:** PMD 5.0.1 + +**Priority:** High (1) + +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) + +``` +//FunctionCall/Name[ + @Image = 'parseInt' + and + count(../*) < 3 +] +``` + +**Example(s):** + +``` javascript +parseInt("010"); // unclear, could be interpreted as 10 or 7 (with a base of 7) + +parseInt("10", 10); // good +``` + +**Use this rule by referencing it:** +``` xml + +``` + diff --git a/docs/pages/pmd/rules/ecmascript/braces.md b/docs/pages/pmd/rules/ecmascript/braces.md deleted file mode 100644 index 5f67d6dcf7..0000000000 --- a/docs/pages/pmd/rules/ecmascript/braces.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: Braces -summary: The Braces Ruleset contains a collection of braces rules. -permalink: pmd_rules_ecmascript_braces.html -folder: pmd/rules/ecmascript -sidebaractiveurl: /pmd_rules_ecmascript.html -editmepath: ../pmd-javascript/src/main/resources/rulesets/ecmascript/braces.xml -keywords: Braces, IfStmtsMustUseBraces, IfElseStmtsMustUseBraces, WhileLoopsMustUseBraces, ForLoopsMustUseBraces ---- -## ForLoopsMustUseBraces - -**Since:** PMD 5.0 - -**Priority:** Medium (3) - -Avoid using 'for' statements without using curly braces. - -``` -//ForLoop[not(child::Scope)] -| -//ForInLoop[not(child::Scope)] -``` - -**Example(s):** - -``` javascript -// Ok -for (var i = 0; i < 42; i++) { - foo(); -} - -// Bad -for (var i = 0; i < 42; i++) - foo(); -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## IfElseStmtsMustUseBraces - -**Since:** PMD 5.0 - -**Priority:** Medium (3) - -Avoid using if..else statements without using curly braces. - -``` -//ExpressionStatement[parent::IfStatement[@Else = "true"]] - [not(child::Scope)] - [not(child::IfStatement)] -``` - -**Example(s):** - -``` javascript -// Ok -if (foo) { - x++; -} else { - y++; -} - -// Bad -if (foo) - x++; -else - y++; -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## IfStmtsMustUseBraces - -**Since:** PMD 5.0 - -**Priority:** Medium (3) - -Avoid using if statements without using curly braces. - -``` -//IfStatement[@Else = "false" and not(child::Scope)] -``` - -**Example(s):** - -``` javascript -// Ok -if (foo) { - x++; -} - -// Bad -if (foo) - x++; -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## WhileLoopsMustUseBraces - -**Since:** PMD 5.0 - -**Priority:** Medium (3) - -Avoid using 'while' statements without using curly braces. - -``` -//WhileLoop[not(child::Scope)] -``` - -**Example(s):** - -``` javascript -// Ok -while (true) { - x++; -} - -// Bad -while (true) - x++; -``` - -**Use this rule by referencing it:** -``` xml - -``` - diff --git a/docs/pages/pmd/rules/ecmascript/codestyle.md b/docs/pages/pmd/rules/ecmascript/codestyle.md new file mode 100644 index 0000000000..9d0fcfb44f --- /dev/null +++ b/docs/pages/pmd/rules/ecmascript/codestyle.md @@ -0,0 +1,365 @@ +--- +title: Code Style +summary: +permalink: pmd_rules_ecmascript_codestyle.html +folder: pmd/rules/ecmascript +sidebaractiveurl: /pmd_rules_ecmascript.html +editmepath: ../pmd-javascript/src/main/resources/category/ecmascript/codestyle.xml +keywords: Code Style, AssignmentInOperand, AvoidTrailingComma, ForLoopsMustUseBraces, IfElseStmtsMustUseBraces, IfStmtsMustUseBraces, NoElseReturn, UnnecessaryBlock, UnnecessaryParentheses, UnreachableCode, WhileLoopsMustUseBraces +--- +## AssignmentInOperand + +**Since:** PMD 5.0 + +**Priority:** Medium High (2) + +Avoid assignments in operands; this can make code more complicated and harder to read. This is sometime +indicative of the bug where the assignment operator '=' was used instead of the equality operator '=='. + +``` +//IfStatement[$allowIf = "false"]/child::node()[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] +| + //WhileLoop[$allowWhile = "false"]/child::node()[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] +| + //DoLoop[$allowWhile = "false"]/child::node()[2]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] +| + //ForLoop[$allowFor = "false"]/child::node()[2]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] +| + //ConditionalExpression[$allowTernary = "false"]/child::node()[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] +| + //ConditionalExpression[$allowTernaryResults = "false"]/child::node()[position() = 2 or position() = 3]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]] +``` + +**Example(s):** + +``` javascript +var x = 2; +// Bad +if ((x = getX()) == 3) { + alert('3!'); +} + +function getX() { + return 3; +} +``` + +**This rule has the following properties:** + +|Name|Default Value|Description| +|----|-------------|-----------| +|allowIf|false|Allow assignment within the conditional expression of an if statement| +|allowFor|false|Allow assignment within the conditional expression of a for statement| +|allowWhile|false|Allow assignment within the conditional expression of a while statement| +|allowTernary|false|Allow assignment within the conditional expression of a ternary operator| +|allowTernaryResults|false|Allow assignment within the result expressions of a ternary operator| +|allowIncrementDecrement|false|Allow increment or decrement operators within the conditional expression of an if, for, or while statement| + +**Use this rule by referencing it:** +``` xml + +``` + +## AvoidTrailingComma + +**Since:** PMD 5.1 + +**Priority:** High (1) + +This rule helps improve code portability due to differences in browser treatment of trailing commas in object or array literals. + +``` +//ObjectLiteral[$allowObjectLiteral = "false" and @TrailingComma = 'true'] +| +//ArrayLiteral[$allowArrayLiteral = "false" and @TrailingComma = 'true'] +``` + +**Example(s):** + +``` javascript +function(arg) { + var obj1 = { a : 1 }; // Ok + var arr1 = [ 1, 2 ]; // Ok + + var obj2 = { a : 1, }; // Syntax error in some browsers! + var arr2 = [ 1, 2, ]; // Length 2 or 3 depending on the browser! +} +``` + +**This rule has the following properties:** + +|Name|Default Value|Description| +|----|-------------|-----------| +|allowObjectLiteral|false|Allow a trailing comma within an object literal| +|allowArrayLiteral|false|Allow a trailing comma within an array literal| + +**Use this rule by referencing it:** +``` xml + +``` + +## ForLoopsMustUseBraces + +**Since:** PMD 5.0 + +**Priority:** Medium (3) + +Avoid using 'for' statements without using curly braces. + +``` +//ForLoop[not(child::Scope)] +| +//ForInLoop[not(child::Scope)] +``` + +**Example(s):** + +``` javascript +// Ok +for (var i = 0; i < 42; i++) { + foo(); +} + +// Bad +for (var i = 0; i < 42; i++) + foo(); +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## IfElseStmtsMustUseBraces + +**Since:** PMD 5.0 + +**Priority:** Medium (3) + +Avoid using if..else statements without using curly braces. + +``` +//ExpressionStatement[parent::IfStatement[@Else = "true"]] + [not(child::Scope)] + [not(child::IfStatement)] +``` + +**Example(s):** + +``` javascript +// Ok +if (foo) { + x++; +} else { + y++; +} + +// Bad +if (foo) + x++; +else + y++; +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## IfStmtsMustUseBraces + +**Since:** PMD 5.0 + +**Priority:** Medium (3) + +Avoid using if statements without using curly braces. + +``` +//IfStatement[@Else = "false" and not(child::Scope)] +``` + +**Example(s):** + +``` javascript +// Ok +if (foo) { + x++; +} + +// Bad +if (foo) + x++; +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## NoElseReturn + +**Since:** PMD 5.5.0 + +**Priority:** Medium (3) + +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: + +``` +//IfStatement[@Else="true"][Scope[1]/ReturnStatement] +``` + +**Example(s):** + +``` javascript +// Bad: +if (x) { + return y; +} else { + return z; +} + +// Good: +if (x) { + return y; +} +return z; +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## UnnecessaryBlock + +**Since:** PMD 5.0 + +**Priority:** Medium (3) + +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. + +``` +//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)] +``` + +**Example(s):** + +``` javascript +if (foo) { + // Ok +} +if (bar) { + { + // Bad + } +} +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## UnnecessaryParentheses + +**Since:** PMD 5.0 + +**Priority:** Medium Low (4) + +Unnecessary parentheses should be removed. + +``` +//ParenthesizedExpression/ParenthesizedExpression +``` + +**Example(s):** + +``` javascript +var x = 1; // Ok +var y = (1 + 1); // Ok +var z = ((1 + 1)); // Bad +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## UnreachableCode + +**Since:** PMD 5.0 + +**Priority:** High (1) + +A 'return', 'break', 'continue', or 'throw' statement should be the last in a block. Statements after these +will never execute. This is a bug, or extremely poor style. + +``` +//ReturnStatement[following-sibling::node()] +| + //ContinueStatement[following-sibling::node()] +| + //BreakStatement[following-sibling::node()] +| + //ThrowStatement[following-sibling::node()] +``` + +**Example(s):** + +``` javascript +// Ok +function foo() { + return 1; +} +// Bad +function bar() { + var x = 1; + return x; + x = 2; +} +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## WhileLoopsMustUseBraces + +**Since:** PMD 5.0 + +**Priority:** Medium (3) + +Avoid using 'while' statements without using curly braces. + +``` +//WhileLoop[not(child::Scope)] +``` + +**Example(s):** + +``` javascript +// Ok +while (true) { + x++; +} + +// Bad +while (true) + x++; +``` + +**Use this rule by referencing it:** +``` xml + +``` + diff --git a/docs/pages/pmd/rules/ecmascript/controversial.md b/docs/pages/pmd/rules/ecmascript/controversial.md deleted file mode 100644 index b73ea9d35b..0000000000 --- a/docs/pages/pmd/rules/ecmascript/controversial.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Controversial Ecmascript -summary: 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. -permalink: pmd_rules_ecmascript_controversial.html -folder: pmd/rules/ecmascript -sidebaractiveurl: /pmd_rules_ecmascript.html -editmepath: ../pmd-javascript/src/main/resources/rulesets/ecmascript/controversial.xml -keywords: Controversial Ecmascript, AvoidWithStatement ---- -## AvoidWithStatement - -**Since:** PMD 5.0.1 - -**Priority:** High (1) - -Avoid using with - it's bad news - -``` -//WithStatement -``` - -**Example(s):** - -``` javascript -with (object) { - property = 3; // Might be on object, might be on window: who knows. -} -``` - -**Use this rule by referencing it:** -``` xml - -``` - diff --git a/docs/pages/pmd/rules/ecmascript/errorprone.md b/docs/pages/pmd/rules/ecmascript/errorprone.md new file mode 100644 index 0000000000..6c5a48604d --- /dev/null +++ b/docs/pages/pmd/rules/ecmascript/errorprone.md @@ -0,0 +1,87 @@ +--- +title: Error Prone +summary: +permalink: pmd_rules_ecmascript_errorprone.html +folder: pmd/rules/ecmascript +sidebaractiveurl: /pmd_rules_ecmascript.html +editmepath: ../pmd-javascript/src/main/resources/category/ecmascript/errorprone.xml +keywords: Error Prone, EqualComparison, InnaccurateNumericLiteral +--- +## EqualComparison + +**Since:** PMD 5.0 + +**Priority:** Medium (3) + +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. + +``` +//InfixExpression[(@Image = "==" or @Image = "!=") + and + (child::KeywordLiteral[@Image = "true" or @Image = "false"] + or + child::NumberLiteral) +] +``` + +**Example(s):** + +``` javascript +// Ok +if (someVar === true) { + ... +} +// Ok +if (someVar !== 3) { + ... +} +// Bad +if (someVar == true) { + ... +} +// Bad +if (someVar != 3) { + ... +} +``` + +**Use this rule by referencing it:** +``` xml + +``` + +## InnaccurateNumericLiteral + +**Since:** PMD 5.0 + +**Priority:** Medium High (2) + +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. + +``` +//NumberLiteral[ + @Image != @Number + and translate(@Image, "e", "E") != @Number + and concat(@Image, ".0") != @Number + and @Image != substring-before(translate(@Number, ".", ""), "E")] +``` + +**Example(s):** + +``` javascript +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 +``` + +**Use this rule by referencing it:** +``` xml + +``` + diff --git a/docs/pages/pmd/rules/ecmascript/unnecessary.md b/docs/pages/pmd/rules/ecmascript/unnecessary.md deleted file mode 100644 index 6c5c0f5ec0..0000000000 --- a/docs/pages/pmd/rules/ecmascript/unnecessary.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Unnecessary -summary: The Unnecessary Ruleset contains a collection of rules for unnecessary code. -permalink: pmd_rules_ecmascript_unnecessary.html -folder: pmd/rules/ecmascript -sidebaractiveurl: /pmd_rules_ecmascript.html -editmepath: ../pmd-javascript/src/main/resources/rulesets/ecmascript/unnecessary.xml -keywords: Unnecessary, UnnecessaryParentheses, UnnecessaryBlock, NoElseReturn ---- -## NoElseReturn - -**Since:** PMD 5.5.0 - -**Priority:** Medium (3) - -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: - -``` -//IfStatement[@Else="true"][Scope[1]/ReturnStatement] -``` - -**Example(s):** - -``` javascript -// Bad: -if (x) { - return y; -} else { - return z; -} - -// Good: -if (x) { - return y; -} -return z; -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## UnnecessaryBlock - -**Since:** PMD 5.0 - -**Priority:** Medium (3) - -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. - -``` -//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)] -``` - -**Example(s):** - -``` javascript -if (foo) { - // Ok -} -if (bar) { - { - // Bad - } -} -``` - -**Use this rule by referencing it:** -``` xml - -``` - -## UnnecessaryParentheses - -**Since:** PMD 5.0 - -**Priority:** Medium Low (4) - -Unnecessary parentheses should be removed. - -``` -//ParenthesizedExpression/ParenthesizedExpression -``` - -**Example(s):** - -``` javascript -var x = 1; // Ok -var y = (1 + 1); // Ok -var z = ((1 + 1)); // Bad -``` - -**Use this rule by referencing it:** -``` xml - -``` -