[java] CommentRequired: Separate header comment from class comment and header top-level comment

Refs #1683
This commit is contained in:
snuyanzin
2019-12-17 12:30:05 +01:00
committed by Andreas Dangel
parent bc2f2d8f50
commit 88ff3f0628
3 changed files with 56 additions and 7 deletions
@@ -19,8 +19,10 @@ import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessNode;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessTypeNode;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaNode;
import net.sourceforge.pmd.lang.java.ast.Comment;
import net.sourceforge.pmd.lang.java.ast.CommentUtil;
import net.sourceforge.pmd.lang.java.ast.FormalComment;
@@ -64,17 +66,15 @@ public abstract class AbstractCommentRule extends AbstractJavaRule {
SortedMap<Integer, Node> itemsByLineNumber = orderedCommentsAndDeclarations(cUnit);
FormalComment lastComment = null;
AbstractJavaAccessNode lastNode = null;
AbstractJavaNode lastNode = null;
for (Entry<Integer, Node> entry : itemsByLineNumber.entrySet()) {
Node value = entry.getValue();
if (value instanceof AbstractJavaAccessNode) {
AbstractJavaAccessNode node = (AbstractJavaAccessNode) value;
if (value instanceof AbstractJavaAccessNode || value instanceof ASTPackageDeclaration) {
AbstractJavaNode node = (AbstractJavaNode) value;
// maybe the last comment is within the last node
if (lastComment != null && isCommentNotWithin(lastComment, lastNode, node)
&& isCommentBefore(lastComment, node)) {
if (lastComment != null && isCommentNotWithin(lastComment, lastNode, value)
&& isCommentBefore(lastComment, value)) {
node.comment(lastComment);
lastComment = null;
}
@@ -108,6 +108,8 @@ public abstract class AbstractCommentRule extends AbstractJavaRule {
protected SortedMap<Integer, Node> orderedCommentsAndDeclarations(ASTCompilationUnit cUnit) {
SortedMap<Integer, Node> itemsByLineNumber = new TreeMap<>();
addDeclarations(itemsByLineNumber, cUnit.findDescendantsOfType(ASTPackageDeclaration.class, true));
addDeclarations(itemsByLineNumber, cUnit.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class, true));
addDeclarations(itemsByLineNumber, cUnit.getComments());
@@ -20,6 +20,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessNode;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaNode;
import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature;
@@ -45,6 +46,8 @@ public class CommentRequiredRule extends AbstractCommentRule {
.defaultValue(CommentRequirement.Ignored).build();
private static final PropertyDescriptor<CommentRequirement> HEADER_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("headerCommentRequirement", "Header comments").build();
private static final PropertyDescriptor<CommentRequirement> CLASS_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("classCommentRequirement", "Class comments").build();
private static final PropertyDescriptor<CommentRequirement> FIELD_CMT_REQUIREMENT_DESCRIPTOR
= requirementPropertyBuilder("fieldCommentRequirement", "Field comments").build();
private static final PropertyDescriptor<CommentRequirement> PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR
@@ -64,6 +67,7 @@ public class CommentRequiredRule extends AbstractCommentRule {
public CommentRequiredRule() {
definePropertyDescriptor(OVERRIDE_CMT_DESCRIPTOR);
definePropertyDescriptor(ACCESSOR_CMT_DESCRIPTOR);
definePropertyDescriptor(CLASS_CMT_REQUIREMENT_DESCRIPTOR);
definePropertyDescriptor(HEADER_CMT_REQUIREMENT_DESCRIPTOR);
definePropertyDescriptor(FIELD_CMT_REQUIREMENT_DESCRIPTOR);
definePropertyDescriptor(PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR);
@@ -109,6 +113,13 @@ public class CommentRequiredRule extends AbstractCommentRule {
@Override
public Object visit(ASTClassOrInterfaceDeclaration decl, Object data) {
checkCommentMeetsRequirement(data, decl, CLASS_CMT_REQUIREMENT_DESCRIPTOR);
return super.visit(decl, data);
}
@Override
public Object visit(ASTPackageDeclaration decl, Object data) {
checkCommentMeetsRequirement(data, decl, HEADER_CMT_REQUIREMENT_DESCRIPTOR);
return super.visit(decl, data);
}
@@ -212,6 +223,7 @@ public class CommentRequiredRule extends AbstractCommentRule {
return getProperty(OVERRIDE_CMT_DESCRIPTOR) == CommentRequirement.Ignored
&& getProperty(ACCESSOR_CMT_DESCRIPTOR) == CommentRequirement.Ignored
&& getProperty(HEADER_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored
&& getProperty(CLASS_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored
&& getProperty(FIELD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored
&& getProperty(PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored
&& getProperty(PROT_METHOD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored
@@ -51,6 +51,7 @@ public class Foo {
<test-code>
<description>Missing comments - only class level required.</description>
<rule-property name="headerCommentRequirement">Required</rule-property>
<rule-property name="classCommentRequirement">Required</rule-property>
<rule-property name="fieldCommentRequirement">Ignored</rule-property>
<rule-property name="publicMethodCommentRequirement">Ignored</rule-property>
<rule-property name="protectedMethodCommentRequirement">Ignored</rule-property>
@@ -62,6 +63,7 @@ public class Foo {
<test-code>
<description>Too many comments - all comments are unwanted.</description>
<rule-property name="headerCommentRequirement">Unwanted</rule-property>
<rule-property name="classCommentRequirement">Unwanted</rule-property>
<rule-property name="fieldCommentRequirement">Unwanted</rule-property>
<rule-property name="publicMethodCommentRequirement">Unwanted</rule-property>
<rule-property name="protectedMethodCommentRequirement">Unwanted</rule-property>
@@ -240,6 +242,9 @@ public class CommentRequired implements Serializable {
<description>#1522 [java] CommentRequired: false positive</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
/**
* Kommentar zu de.konsens.biene.ka.client
*/
package de.konsens.biene.ka.client;
/**
@@ -505,5 +510,35 @@ public class CommentRequired {
]]></code>
</test-code>
<test-code>
<description>#1683 [java] CommentRequired property names are inconsistent</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>7</expected-linenumbers>
<code><![CDATA[
/** license */
package test.my_package;
/** The class comment */
public class CommentRequired implements Serializable {
/** My list */
List next;
private final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField("next", List.class)};
}
]]></code>
</test-code>
<test-code>
<description>#1683 [java] CommentRequired property names are inconsistent - package with comment without new lines</description>
<expected-problems>2</expected-problems>
<code><![CDATA[
/** licence comment */ package test.my_package; /** Test class */ public class Test { public void method1() { /** comment here */ } public void method2() { } }
]]></code>
</test-code>
<test-code>
<description>#1683 [java] CommentRequired property names are inconsistent - package without comment and without new lines</description>
<expected-problems>3</expected-problems>
<code><![CDATA[
package test.my_package; /** Test class */ public class Test { public void method1() { /** comment here */ } public void method2() { } }
]]></code>
</test-code>
</test-data>