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 import org.cactoos.text.Sub;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public final class MultilineJavadocTagsCheck extends AbstractCheck {
38
39 @Override
40 public int[] getDefaultTokens() {
41 return new int[] {
42 TokenTypes.METHOD_DEF,
43 TokenTypes.CTOR_DEF,
44 TokenTypes.PACKAGE_DEF,
45 };
46 }
47
48 @Override
49 public int[] getAcceptableTokens() {
50 return this.getDefaultTokens();
51 }
52
53 @Override
54 public int[] getRequiredTokens() {
55 return this.getDefaultTokens();
56 }
57
58 @Override
59 public void visitToken(final DetailAST ast) {
60 final String[] lines = this.getLines();
61 final int start = ast.getLineNo();
62 final int cstart =
63 MultilineJavadocTagsCheck.findCommentStart(lines, start) + 1;
64 final int cend =
65 MultilineJavadocTagsCheck.findCommentEnd(lines, start) - 1;
66 if (cend >= cstart && cstart >= 0) {
67 this.checkJavaDoc(lines, cstart, cend);
68 } else {
69 this.log(0, "Can't find method comment");
70 }
71 }
72
73
74
75
76
77
78
79 @SuppressWarnings("PMD.InefficientEmptyStringCheck")
80 private void checkJavaDoc(final String[] lines, final int start,
81 final int end) {
82 boolean tagged = false;
83 int index = -1;
84 for (int current = start; current <= end; current += 1) {
85 final String line = lines[current];
86 if (line.contains("* @")) {
87 tagged = true;
88 index = line.indexOf('@');
89 } else {
90 if (tagged) {
91 final int comment = line.indexOf('*');
92 final String sub = new Sub(
93 line, comment + 1, index + 1
94 ).toString();
95 final String ext = new Sub(
96 line, comment + 1, index + 2
97 ).toString();
98 if (!sub.trim().isEmpty() || ext.trim().isEmpty()) {
99 this.log(
100 current + 1,
101 "Should contain one indentation space"
102 );
103 }
104 }
105 }
106 }
107 }
108
109
110
111
112
113
114
115 private static int findCommentStart(final String[] lines, final int start) {
116 final int doc = MultilineJavadocTagsCheck.findTrimmedTextUp(lines, start, "/**");
117 final int comment = MultilineJavadocTagsCheck.findTrimmedTextUp(lines, start, "/*");
118 return Math.max(doc, comment);
119 }
120
121
122
123
124
125
126
127 private static int findCommentEnd(final String[] lines, final int start) {
128 return MultilineJavadocTagsCheck.findTrimmedTextUp(lines, start, "*/");
129 }
130
131
132
133
134
135
136
137
138 private static int findTrimmedTextUp(final String[] lines,
139 final int start, final String text) {
140 int found = -1;
141 for (int pos = start - 1; pos >= 0; pos -= 1) {
142 if (lines[pos].trim().equals(text)) {
143 found = pos;
144 break;
145 }
146 }
147 return found;
148 }
149 }