Merge branch 'master' into pmd/7.0.x
This commit is contained in:
@ -11,6 +11,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.mozilla.javascript.ScriptRuntime;
|
||||
import org.mozilla.javascript.ast.ArrayComprehension;
|
||||
import org.mozilla.javascript.ast.ArrayComprehensionLoop;
|
||||
import org.mozilla.javascript.ast.ArrayLiteral;
|
||||
@ -220,13 +221,18 @@ public final class EcmascriptTreeBuilder implements NodeVisitor {
|
||||
TrailingCommaNode trailingCommaNode = (TrailingCommaNode) node;
|
||||
int nodeStart = node.getNode().getAbsolutePosition();
|
||||
int nodeEnd = nodeStart + node.getNode().getLength() - 1;
|
||||
|
||||
// This will fetch the localized message
|
||||
// See https://github.com/pmd/pmd/issues/384
|
||||
String trailingCommaLocalizedMessage = ScriptRuntime.getMessage0("msg.extra.trailing.comma");
|
||||
|
||||
for (ParseProblem parseProblem : parseProblems) {
|
||||
|
||||
// The node overlaps the comma (i.e. end of the problem)?
|
||||
int problemStart = parseProblem.getFileOffset();
|
||||
int commaPosition = problemStart + parseProblem.getLength() - 1;
|
||||
if (nodeStart <= commaPosition && commaPosition <= nodeEnd) {
|
||||
if ("Trailing comma is not legal in an ECMA-262 object initializer"
|
||||
.equals(parseProblem.getMessage())) {
|
||||
if (trailingCommaLocalizedMessage.equals(parseProblem.getMessage())) {
|
||||
// Report on the shortest code block containing the
|
||||
// problem (i.e. inner most code in nested structures).
|
||||
EcmascriptNode<?> currentNode = (EcmascriptNode<?>) parseProblemToNode.get(parseProblem);
|
||||
|
@ -18,6 +18,7 @@ Rules which enforce generally accepted best practices.
|
||||
<description>Avoid using with - it's bad news</description>
|
||||
<priority>1</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
@ -79,10 +80,11 @@ Global variables can lead to side-effects that are hard to debug.
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//Assignment[Name/@GlobalName = 'true']
|
||||
//Assignment[Name/@GlobalName = true()]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -116,6 +118,7 @@ is better to explicitly scope the variable name to the nearest enclosing scope w
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<[1]/descendant-or-self::node()[self::Assignment or self::UnaryExpression[$allowIncrementDecrement = "false" and (@Image = "--" or @Image = "++")]]
|
||||
//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 = "++")]]
|
||||
//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 = "++")]]
|
||||
//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 = "++")]]
|
||||
//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[$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 = "++")]]
|
||||
//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 = "++")]]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -72,6 +73,7 @@ Avoid using 'for' statements without using curly braces.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
@ -107,10 +109,11 @@ Avoid using if..else statements without using curly braces.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ExpressionStatement[parent::IfStatement[@Else = "true"]]
|
||||
//ExpressionStatement[parent::IfStatement[@Else = true()]]
|
||||
[not(child::Scope)]
|
||||
[not(child::IfStatement)]
|
||||
]]>
|
||||
@ -146,10 +149,11 @@ Avoid using if statements without using curly braces.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//IfStatement[@Else = "false" and not(child::Scope)]
|
||||
//IfStatement[@Else = false() and not(child::Scope)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -182,10 +186,11 @@ See also: <http://eslint.org/docs/rules/no-else-return>
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//IfStatement[@Else="true"][Scope[1]/ReturnStatement]
|
||||
//IfStatement[@Else=true()][Scope[1]/ReturnStatement]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -221,6 +226,7 @@ be misleading. Considering removing this unnecessary Block.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
@ -256,6 +262,7 @@ if (bar) {
|
||||
<description>Unnecessary parentheses should be removed.</description>
|
||||
<priority>4</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
@ -285,6 +292,7 @@ will never execute. This is a bug, or extremely poor style.
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
@ -326,6 +334,7 @@ Avoid using 'while' statements without using curly braces.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
|
@ -20,12 +20,13 @@ This rule helps improve code portability due to differences in browser treatment
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ObjectLiteral[$allowObjectLiteral = "false" and @TrailingComma = 'true']
|
||||
//ObjectLiteral[$allowObjectLiteral = false() and @TrailingComma = true()]
|
||||
|
|
||||
//ArrayLiteral[$allowArrayLiteral = "false" and @TrailingComma = 'true']
|
||||
//ArrayLiteral[$allowArrayLiteral = false() and @TrailingComma = true()]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
@ -57,14 +58,14 @@ same type. The === operator avoids the casting.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//InfixExpression[(@Image = "==" or @Image = "!=")
|
||||
//InfixExpression[
|
||||
(@Image = "==" or @Image = "!=")
|
||||
and
|
||||
(child::KeywordLiteral[@Image = "true" or @Image = "false"]
|
||||
or
|
||||
child::NumberLiteral)
|
||||
(KeywordLiteral[@Image='true' or @Image = 'false'] or NumberLiteral)
|
||||
]
|
||||
]]>
|
||||
</value>
|
||||
@ -104,10 +105,11 @@ precision in a floating point number. This may result in numeric calculations b
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//NumberLiteral[@NormalizedImage != @Number]
|
||||
//NumberLiteral[@NormalizedImage != string(@Number)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.ecmascript.ast;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
/**
|
||||
* A JUnit rule to change the system locale during a test.
|
||||
*/
|
||||
public class DefaultLocale implements TestRule {
|
||||
|
||||
private boolean statementIsExecuting = false;
|
||||
private Locale loc = Locale.getDefault();
|
||||
|
||||
/** Set the locale value (overwrites previously set value). */
|
||||
public void set(Locale locale) {
|
||||
if (statementIsExecuting) {
|
||||
Locale.setDefault(locale);
|
||||
} else {
|
||||
this.loc = locale;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
return new EnvironmentVariablesStatement(base);
|
||||
}
|
||||
|
||||
private class EnvironmentVariablesStatement extends Statement {
|
||||
|
||||
final Statement baseStatement;
|
||||
|
||||
EnvironmentVariablesStatement(Statement baseStatement) {
|
||||
this.baseStatement = baseStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
Locale prev = Locale.getDefault();
|
||||
statementIsExecuting = true;
|
||||
try {
|
||||
Locale.setDefault(loc);
|
||||
baseStatement.evaluate();
|
||||
} finally {
|
||||
statementIsExecuting = false;
|
||||
Locale.setDefault(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.ecmascript.ast;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TrailingCommaTest extends EcmascriptParserTestBase {
|
||||
|
||||
@Rule
|
||||
public DefaultLocale defaultLocale = new DefaultLocale();
|
||||
|
||||
|
||||
@Test
|
||||
public void testTrailingCommaDefaultLocale() {
|
||||
testTrailingComma();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrailingCommaFrFr() {
|
||||
defaultLocale.set(Locale.FRANCE);
|
||||
testTrailingComma();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrailingCommaRootLocale() {
|
||||
defaultLocale.set(Locale.ROOT);
|
||||
testTrailingComma();
|
||||
}
|
||||
|
||||
public void testTrailingComma() {
|
||||
ASTAstRoot node = js.parse("x = {a : 1, };\n");
|
||||
ASTObjectLiteral fn = node.getFirstDescendantOfType(ASTObjectLiteral.class);
|
||||
Assert.assertTrue(fn.isTrailingComma());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user