如果有特定的注释,如何使Checkstyle忽略缺少的JavaDoc

时间:2015-02-06 07:50:41

标签: java checkstyle

我想自定义Checkstyle JavadocVariable规则,以便它不会抱怨具有@FindBy注释的字段。

class Demo{

    @FindBy(id = "new-button")
    public WebElement createButton;  //<- no JavaDoc required because it is a field "injected" by selenium

    public String otherField;    //<- complain about missing Java doc
}

但我不清楚如何在checkstyle.xml文件中指定它。有人有想法吗?

在此用例中不起作用的事情:

  • 修改已检查的类也无法解决!
  • SuppressWithNearbyCommentFilter 不起作用,因为它是注释但不是注释

1 个答案:

答案 0 :(得分:10)

我知道几种解决方案,但所有这些解决方案都需要做额外的工作。

  1. 实现自己的JavadocVariableCheck,可以在提供注释的情况下跳过检查。
  2. 实施checkstyle过滤器(例如SuppressWarningsHolder + SuppressWarningsFilter,但带有注释支持)
  3. 或者实现简单的过滤器,扫描@FindBy并忽略后面的两行。
  4. 我的解决方案(最简单的一个):

    package org.aap.checks;
    
    import com.google.common.collect.Lists;
    import com.puppycrawl.tools.checkstyle.api.AuditEvent;
    import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
    import com.puppycrawl.tools.checkstyle.api.FileContents;
    import com.puppycrawl.tools.checkstyle.api.Filter;
    import com.puppycrawl.tools.checkstyle.checks.FileContentsHolder;
    
    import java.lang.ref.WeakReference;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;
    
    public class SuppressWithAnnotationFilter
            extends AutomaticBean
            implements Filter {
    
        public class Tag implements Comparable<Tag> {
            private final int firstLine;
            private final int lastLine;
    
            public Tag(int firstLine, int lastLine) {
                this.firstLine = firstLine;
                this.lastLine = lastLine;
            }
    
            @Override
            public int compareTo(Tag other) {
                if (firstLine == other.firstLine) {
                    return lastLine - other.lastLine;
                }
                return (firstLine - other.firstLine);
            }
    
            public boolean isMatch(AuditEvent event) {
                final int line = event.getLine();
                return line >= firstLine && line <= lastLine;
            }
    
            @Override
            public final String toString() {
                return "Tag[lines=" + firstLine + " to " + lastLine + "]";
            }
        }
    
        private final List<Tag> tags = Lists.newArrayList();
        private WeakReference<FileContents> fileContentsReference =
                new WeakReference<FileContents>(null);
    
        public FileContents getFileContents() {
            return fileContentsReference.get();
        }
    
        public void setFileContents(FileContents fileContents) {
            fileContentsReference = new WeakReference<FileContents>(fileContents);
        }
    
        @Override
        public boolean accept(AuditEvent event) {
            if (event.getLocalizedMessage() == null) {
                return true;        // A special event.
            }
    
            final FileContents currentContents = FileContentsHolder.getContents();
            if (currentContents == null) {
                return true;
            }
            if (getFileContents() != currentContents) {
                setFileContents(currentContents);
                tagSuppressions();
            }
            for (final Iterator<Tag> iter = tags.iterator(); iter.hasNext(); ) {
                final Tag tag = iter.next();
                if (tag.isMatch(event)) {
                    return false;
                }
            }
            return true;
        }
    
        private void tagSuppressions() {
            tags.clear();
            final FileContents contents = getFileContents();
    
            String[] contentsLines = contents.getLines();
            for (int i = 0; i < contentsLines.length; i++) {
                if (contentsLines[i].contains("@FindBy")) {
                    tags.add(new Tag(i+1, i+2));
                }
            }
    
            Collections.sort(tags);
        }
    }
    

    将结果类添加到checkstyle任务的类路径中,然后在checkstyle.xml中指定过滤器:

    <?xml version="1.0"?>
    <!DOCTYPE module PUBLIC
        "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
        "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
    <module name="Checker">
      <module name="TreeWalker">
        ....
        <!-- your Check goes here -->
        <module name="org.aap.checks.SuppressWithAnnotationFilter"/>
        ....
      </module>
    </module>