pmd: fix #1115 commentRequiredRule in pmd 5.1 is not working properly
This commit is contained in:
1 parent
9255e26c70
commit
98e27294f0
4 files changed
+130
-49
No files matched your search
@@ -1,6 +1,7 @@
|
||||
????? ??, 2013 - 5.1.0:
|
||||
|
||||
Fixed bug 1059: Change rule name "Use Singleton" should be "Use Utility class"
|
||||
Fixed bug 1115: commentRequiredRule in pmd 5.1 is not working properly
|
||||
|
||||
New EcmaScript rules and ruleset:
|
||||
Controversial ruleset, featuring
|
||||
|
||||
+76
-48
@@ -3,19 +3,21 @@
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.java.rule.comments;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessNode;
|
||||
import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessTypeNode;
|
||||
import net.sourceforge.pmd.lang.java.ast.Comment;
|
||||
import net.sourceforge.pmd.lang.java.ast.FormalComment;
|
||||
import net.sourceforge.pmd.lang.java.ast.MultiLineComment;
|
||||
@@ -37,7 +39,7 @@ public abstract class AbstractCommentRule extends AbstractJavaRule {
|
||||
|
||||
int atPos = comments.indexOf('@');
|
||||
if (atPos < 0)
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
|
||||
List<Integer> ints = new ArrayList<Integer>();
|
||||
ints.add(atPos);
|
||||
@@ -146,63 +148,89 @@ public abstract class AbstractCommentRule extends AbstractJavaRule {
|
||||
}
|
||||
|
||||
protected void assignCommentsToDeclarations(ASTCompilationUnit cUnit) {
|
||||
SortedMap<Integer, Object> itemsByLineNumber = orderedCommentsAndDeclarations(cUnit);
|
||||
SortedMap<Integer, Node> itemsByLineNumber = orderedCommentsAndDeclarations(cUnit);
|
||||
FormalComment lastComment = null;
|
||||
AbstractJavaAccessNode lastNode = null;
|
||||
|
||||
for (Entry<Integer, Node> entry : itemsByLineNumber.entrySet()) {
|
||||
Node value = entry.getValue();
|
||||
|
||||
for (Entry<Integer, Object> entry : itemsByLineNumber.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (lastComment == null) {
|
||||
if (value instanceof FormalComment) {
|
||||
lastComment = (FormalComment) value;
|
||||
} else {
|
||||
// else this is declaration without comment
|
||||
if (!(value instanceof AbstractJavaAccessTypeNode)) {
|
||||
lastNode = (AbstractJavaAccessNode) value;
|
||||
}
|
||||
}
|
||||
// else this is declaration without comment
|
||||
} else if (value instanceof AbstractJavaAccessNode) {
|
||||
AbstractJavaAccessNode node = (AbstractJavaAccessNode) value;
|
||||
node.comment(lastComment);
|
||||
lastComment = null;
|
||||
|
||||
// maybe the last comment is within the last node
|
||||
if (isCommentNotWithin(lastComment, lastNode) && isCommentBefore(lastComment, node)) {
|
||||
node.comment(lastComment);
|
||||
lastComment = null;
|
||||
}
|
||||
if (!(node instanceof AbstractJavaAccessTypeNode)) {
|
||||
lastNode = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @since
|
||||
* @param cUnit
|
||||
* @return bla
|
||||
*/
|
||||
protected SortedMap<Integer, Object> orderedCommentsAndDeclarations(
|
||||
ASTCompilationUnit cUnit) {
|
||||
private boolean isCommentNotWithin(FormalComment n1, Node n2) {
|
||||
if (n1 == null || n2 == null) {
|
||||
return true;
|
||||
}
|
||||
if ((n1.getEndLine() < n2.getEndLine())
|
||||
|| (n1.getEndLine() == n2.getEndLine() && n1.getEndColumn() < n2.getEndColumn())) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
SortedMap<Integer, Object> itemsByLineNumber = new TreeMap<Integer, Object>();
|
||||
|
||||
List<ASTClassOrInterfaceDeclaration> packageDecl = cUnit
|
||||
.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class);
|
||||
for (ASTClassOrInterfaceDeclaration decl : packageDecl) {
|
||||
itemsByLineNumber.put(decl.getBeginLine(), decl);
|
||||
}
|
||||
|
||||
for (Comment comment : cUnit.getComments()) {
|
||||
itemsByLineNumber.put(comment.getBeginLine(), comment);
|
||||
}
|
||||
|
||||
List<ASTFieldDeclaration> fields = cUnit
|
||||
.findDescendantsOfType(ASTFieldDeclaration.class);
|
||||
for (ASTFieldDeclaration fieldDecl : fields) {
|
||||
itemsByLineNumber.put(fieldDecl.getBeginLine(), fieldDecl);
|
||||
}
|
||||
|
||||
List<ASTMethodDeclaration> methods = cUnit
|
||||
.findDescendantsOfType(ASTMethodDeclaration.class);
|
||||
for (ASTMethodDeclaration methodDecl : methods) {
|
||||
itemsByLineNumber.put(methodDecl.getBeginLine(), methodDecl);
|
||||
}
|
||||
|
||||
List<ASTConstructorDeclaration> constructors = cUnit
|
||||
.findDescendantsOfType(ASTConstructorDeclaration.class);
|
||||
for (ASTConstructorDeclaration constructorDecl : constructors) {
|
||||
itemsByLineNumber.put(constructorDecl.getBeginLine(), constructorDecl);
|
||||
}
|
||||
|
||||
return itemsByLineNumber;
|
||||
private boolean isCommentBefore(FormalComment n1, Node n2) {
|
||||
if ((n1.getEndLine() < n2.getBeginLine())
|
||||
|| (n1.getEndLine() == n2.getBeginLine() && n1.getEndColumn() < n2.getBeginColumn())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @since
|
||||
* @param cUnit
|
||||
* @return bla
|
||||
*/
|
||||
protected SortedMap<Integer, Node> orderedCommentsAndDeclarations(ASTCompilationUnit cUnit) {
|
||||
|
||||
SortedMap<Integer, Node> itemsByLineNumber = new TreeMap<Integer, Node>();
|
||||
|
||||
List<ASTClassOrInterfaceDeclaration> packageDecl = cUnit
|
||||
.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class);
|
||||
addDeclarations(itemsByLineNumber, packageDecl);
|
||||
|
||||
addDeclarations(itemsByLineNumber, cUnit.getComments());
|
||||
|
||||
List<ASTFieldDeclaration> fields = cUnit.findDescendantsOfType(ASTFieldDeclaration.class);
|
||||
addDeclarations(itemsByLineNumber, fields);
|
||||
|
||||
List<ASTMethodDeclaration> methods = cUnit.findDescendantsOfType(ASTMethodDeclaration.class);
|
||||
addDeclarations(itemsByLineNumber, methods);
|
||||
|
||||
List<ASTConstructorDeclaration> constructors = cUnit.findDescendantsOfType(ASTConstructorDeclaration.class);
|
||||
addDeclarations(itemsByLineNumber, constructors);
|
||||
|
||||
return itemsByLineNumber;
|
||||
}
|
||||
|
||||
private void addDeclarations(SortedMap<Integer, Node> map, List<? extends Node> nodes) {
|
||||
for (Node node : nodes) {
|
||||
map.put((node.getBeginLine() << 16) + node.getBeginColumn(), node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import static org.junit.Assert.fail;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@@ -29,6 +30,7 @@ import net.sourceforge.pmd.RuleSetNotFoundException;
|
||||
import net.sourceforge.pmd.RuleSets;
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.renderers.TextRenderer;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -75,6 +77,7 @@ public abstract class RuleTst {
|
||||
Map<PropertyDescriptor<?>, Object> oldProperties = rule.getPropertiesByPropertyDescriptor();
|
||||
try {
|
||||
int res;
|
||||
Report report;
|
||||
try {
|
||||
// Set test specific properties onto the Rule
|
||||
if (test.getProperties() != null) {
|
||||
@@ -90,11 +93,13 @@ public abstract class RuleTst {
|
||||
}
|
||||
}
|
||||
|
||||
res = processUsingStringReader(test.getCode(), rule, test.getLanguageVersion()).size();
|
||||
report = processUsingStringReader(test.getCode(), rule, test.getLanguageVersion());
|
||||
res = report.size();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
throw new RuntimeException('"' + test.getDescription() + "\" failed", t);
|
||||
}
|
||||
printReport(test, report);
|
||||
assertEquals('"' + test.getDescription() + "\" resulted in wrong number of failures,",
|
||||
test.getNumberOfProblemsExpected(), res);
|
||||
} finally {
|
||||
@@ -107,6 +112,27 @@ public abstract class RuleTst {
|
||||
}
|
||||
}
|
||||
|
||||
private void printReport(TestDescriptor test, Report report) {
|
||||
if (test.getNumberOfProblemsExpected() != report.size()) {
|
||||
System.out.println("--------------------------------------------------------------");
|
||||
System.out.println("Test Failure: " + test.getDescription());
|
||||
System.out.println(" -> Expected " + test.getNumberOfProblemsExpected() + " problem(s), but "
|
||||
+ report.size() + " problem(s) found.");
|
||||
System.out.println();
|
||||
TextRenderer renderer = new TextRenderer();
|
||||
renderer.setWriter(new StringWriter());
|
||||
try {
|
||||
renderer.start();
|
||||
renderer.renderFileReport(report);
|
||||
renderer.end();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
System.out.println(renderer.getWriter().toString());
|
||||
System.out.println("--------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
private Report processUsingStringReader(String code, Rule rule,
|
||||
LanguageVersion languageVersion) throws PMDException {
|
||||
Report report = new Report();
|
||||
|
||||
+26
@@ -61,4 +61,30 @@ public class Foo {
|
||||
<rule-property name="protectedMethodCommentRequirement">Unwanted</rule-property>
|
||||
<code-ref id="with-all-comments"/>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>#1115 commentRequiredRule in pmd 5.1 is not working properly</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<code><![CDATA[
|
||||
/**
|
||||
* Test class
|
||||
*/
|
||||
public class Test {
|
||||
public void method1() {
|
||||
/**
|
||||
* comment here
|
||||
*/
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>#1115 commentRequiredRule in pmd 5.1 is not working properly - without new lines</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<code><![CDATA[
|
||||
/** Test class */ public class Test { public void method1() { /** comment here */ } public void method2() { } }
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
Reference in new issue
Block a user