1
2
3
4
5 package com.qulice.checkstyle;
6
7 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
8 import com.puppycrawl.tools.checkstyle.api.DetailAST;
9 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
10
11
12
13
14
15
16
17
18
19 public final class JavadocLocationCheck extends AbstractCheck {
20
21 @Override
22 public int[] getDefaultTokens() {
23 return new int[] {
24 TokenTypes.CLASS_DEF,
25 TokenTypes.INTERFACE_DEF,
26 TokenTypes.VARIABLE_DEF,
27 TokenTypes.CTOR_DEF,
28 TokenTypes.METHOD_DEF,
29 };
30 }
31
32 @Override
33 public int[] getAcceptableTokens() {
34 return this.getDefaultTokens();
35 }
36
37 @Override
38 public int[] getRequiredTokens() {
39 return this.getDefaultTokens();
40 }
41
42 @Override
43 public void visitToken(final DetailAST ast) {
44 if (!JavadocLocationCheck.isField(ast)) {
45 return;
46 }
47 final String[] lines = this.getLines();
48 int current = ast.getLineNo();
49 boolean found = false;
50 final int start = current;
51 --current;
52 while (true) {
53 if (current <= 0) {
54 break;
55 }
56 final String line = lines[current - 1].trim();
57 if (line.endsWith("*/")) {
58 found = true;
59 break;
60 }
61 if (!line.isEmpty()) {
62 break;
63 }
64 --current;
65 }
66 if (found) {
67 this.report(start, current);
68 }
69 }
70
71
72
73
74
75
76 private void report(final int current, final int end) {
77 final int diff = current - end;
78 if (diff > 1) {
79 for (int pos = 1; pos < diff; pos += 1) {
80 this.log(
81 end + pos,
82 "Empty line between javadoc and subject"
83 );
84 }
85 }
86 }
87
88
89
90
91
92
93
94
95 private static boolean isField(final DetailAST node) {
96 boolean yes = true;
97 if (TokenTypes.VARIABLE_DEF == node.getType()) {
98 yes = TokenTypes.OBJBLOCK == node.getParent().getType();
99 }
100 return yes;
101 }
102 }