pmd: fix #1045 //NOPMD not working (or not implemented) with ECMAscript

This commit is contained in:
Andreas Dangel
2014-02-02 22:37:15 +01:00
parent ec0471cebe
commit 93a46d17e7
5 changed files with 85 additions and 5 deletions

View File

@ -4,7 +4,6 @@
package net.sourceforge.pmd.lang.ecmascript;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.pmd.lang.AbstractParser;
@ -17,9 +16,11 @@ import net.sourceforge.pmd.lang.ast.ParseException;
* Adapter for the EcmascriptParser.
*/
public class Ecmascript3Parser extends AbstractParser {
private net.sourceforge.pmd.lang.ecmascript.ast.EcmascriptParser ecmascriptParser;
public Ecmascript3Parser(ParserOptions parserOptions) {
super(parserOptions);
ecmascriptParser = new net.sourceforge.pmd.lang.ecmascript.ast.EcmascriptParser((EcmascriptParserOptions)parserOptions);
}
@Override
@ -32,10 +33,10 @@ public class Ecmascript3Parser extends AbstractParser {
}
public Node parse(String fileName, Reader source) throws ParseException {
return new net.sourceforge.pmd.lang.ecmascript.ast.EcmascriptParser((EcmascriptParserOptions)parserOptions).parse(source);
return ecmascriptParser.parse(source);
}
public Map<Integer, String> getSuppressMap() {
return new HashMap<Integer, String>(); // FIXME
return ecmascriptParser.getSuppressMap();
}
}

View File

@ -6,7 +6,9 @@ package net.sourceforge.pmd.lang.ecmascript.ast;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.pmd.lang.ast.ParseException;
import net.sourceforge.pmd.lang.ecmascript.EcmascriptParserOptions;
@ -15,14 +17,21 @@ import org.apache.commons.io.IOUtils;
import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.ast.AstRoot;
import org.mozilla.javascript.ast.Comment;
import org.mozilla.javascript.ast.ErrorCollector;
import org.mozilla.javascript.ast.ParseProblem;
public class EcmascriptParser {
protected final EcmascriptParserOptions parserOptions;
private Map<Integer, String> suppressMap;
private String suppressMarker = "NOPMD"; // that's the default value
public EcmascriptParser(EcmascriptParserOptions parserOptions) {
this.parserOptions = parserOptions;
this.parserOptions = parserOptions;
if (parserOptions.getSuppressMarker() != null) {
suppressMarker = parserOptions.getSuppressMarker();
}
}
protected AstRoot parseEcmascript(final String sourceCode, final List<ParseProblem> parseProblems) throws ParseException {
@ -51,9 +60,26 @@ public class EcmascriptParser {
final String sourceCode = IOUtils.toString(reader);
final AstRoot astRoot = parseEcmascript(sourceCode, parseProblems);
final EcmascriptTreeBuilder treeBuilder = new EcmascriptTreeBuilder(sourceCode, parseProblems);
return treeBuilder.build(astRoot);
EcmascriptNode<AstRoot> tree = treeBuilder.build(astRoot);
suppressMap = new HashMap<Integer, String>();
if (astRoot.getComments() != null) {
for (Comment comment : astRoot.getComments()) {
int nopmd = comment.getValue().indexOf(suppressMarker);
if (nopmd > -1) {
String suppression = comment.getValue().substring(nopmd + suppressMarker.length());
EcmascriptNode<Comment> node = treeBuilder.build(comment);
suppressMap.put(node.getBeginLine(), suppression);
}
}
}
return tree;
} catch (IOException e) {
throw new ParseException(e);
}
}
public Map<Integer, String> getSuppressMap() {
return suppressMap;
}
}

View File

@ -58,6 +58,7 @@
* Fixed [bug 1141]: ECMAScript: getFinallyBlock() is buggy.
* Fixed [bug 1142]: ECMAScript: getCatchClause() is buggy.
* Fixed [bug 1144]: CPD encoding argument has no effect
* Fixed [bug 1045]: //NOPMD not working (or not implemented) with ECMAscript
* Fixed [bug 1146]: UseArrayListInsteadOfVector false positive when using own Vector class
* Fixed [bug 1147]: EmptyMethodInAbstractClassShouldBeAbstract false positives
* Fixed [bug 1150]: "EmptyExpression" for valid statements!
@ -85,6 +86,7 @@
[bug 1141]: https://sourceforge.net/p/pmd/bugs/1141
[bug 1142]: https://sourceforge.net/p/pmd/bugs/1142
[bug 1144]: https://sourceforge.net/p/pmd/bugs/1144
[bug 1045]: https://sourceforge.net/p/pmd/bugs/1045
[bug 1146]: https://sourceforge.net/p/pmd/bugs/1146
[bug 1147]: https://sourceforge.net/p/pmd/bugs/1147
[bug 1150]: https://sourceforge.net/p/pmd/bugs/1150

View File

@ -13,7 +13,11 @@ import java.util.Iterator;
import java.util.Map;
import junit.framework.JUnit4TestAdapter;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ecmascript.ast.ASTFunctionNode;
import net.sourceforge.pmd.lang.ecmascript.rule.AbstractEcmascriptRule;
import net.sourceforge.pmd.lang.ecmascript.rule.EcmascriptRuleViolationFactory;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.DummyJavaNode;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
@ -144,6 +148,23 @@ public class ReportTest extends RuleTst implements ReportListener {
assertEquals(1, rpt.getSuppressedRuleViolations().size());
}
@Test
public void testExclusionsInReportWithNOPMDEcmascript() throws Exception {
Report rpt = new Report();
Rule rule = new AbstractEcmascriptRule() {
@Override
public Object visit(ASTFunctionNode node, Object data) {
EcmascriptRuleViolationFactory.INSTANCE.addViolation((RuleContext)data, this, node, "Test", null);
return super.visit(node, data);
}
};
String code = "function(x) // NOPMD test suppress\n"
+ "{ x = 1; }";
runTestFromString(code, rule, rpt, Language.ECMASCRIPT.getDefaultVersion());
assertTrue(rpt.isEmpty());
assertEquals(1, rpt.getSuppressedRuleViolations().size());
}
private static final String TEST1 =
"public class Foo {}" + PMD.EOL;

View File

@ -7,6 +7,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -14,6 +16,8 @@ import java.util.List;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ecmascript.Ecmascript3Parser;
import net.sourceforge.pmd.lang.ecmascript.EcmascriptParserOptions;
import net.sourceforge.pmd.lang.ecmascript.rule.AbstractEcmascriptRule;
import org.junit.Test;
@ -145,4 +149,30 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase {
assertTrue(block.jjtGetChild(0) instanceof ASTExpressionStatement);
assertTrue(block.jjtGetChild(0).jjtGetChild(0) instanceof ASTAssignment);
}
/**
* https://sourceforge.net/p/pmd/bugs/1045/
* #1045 //NOPMD not working (or not implemented) with ECMAscript
*/
@Test
public void testSuppresionComment() {
Ecmascript3Parser parser = new Ecmascript3Parser(new EcmascriptParserOptions());
Reader sourceCode = new StringReader("function(x) {\n"
+ "x = x; //NOPMD I know what I'm doing\n"
+ "}\n");
parser.parse("foo", sourceCode);
assertEquals(" I know what I'm doing", parser.getSuppressMap().get(2));
assertEquals(1, parser.getSuppressMap().size());
EcmascriptParserOptions parserOptions = new EcmascriptParserOptions();
parserOptions.setSuppressMarker("FOOOO");
parser = new Ecmascript3Parser(parserOptions);
sourceCode = new StringReader("function(x) {\n"
+ "y = y; //NOPMD xyz\n"
+ "x = x; //FOOOO I know what I'm doing\n"
+ "}\n");
parser.parse("foo", sourceCode);
assertEquals(" I know what I'm doing", parser.getSuppressMap().get(3));
assertEquals(1, parser.getSuppressMap().size());
}
}