1
2
3
4 package net.sourceforge.pmd.lang.java.rule.comments;
5
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.List;
9 import java.util.SortedMap;
10 import java.util.TreeMap;
11
12 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
13 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
14 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
15 import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration;
16 import net.sourceforge.pmd.lang.java.ast.Comment;
17 import net.sourceforge.pmd.lang.java.ast.FormalComment;
18 import net.sourceforge.pmd.lang.java.ast.MultiLineComment;
19 import net.sourceforge.pmd.lang.java.ast.SingleLineComment;
20 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
21 import net.sourceforge.pmd.util.StringUtil;
22
23
24
25
26
27 public abstract class AbstractCommentRule extends AbstractJavaRule {
28
29
30 protected AbstractCommentRule() {
31
32 }
33
34 protected List<Integer> tagsIndicesIn(String comments) {
35
36 int atPos = comments.indexOf('@');
37 if (atPos < 0) return Collections.EMPTY_LIST;
38
39 List<Integer> ints = new ArrayList<Integer>();
40 ints.add(atPos);
41
42 atPos = comments.indexOf('@', atPos+1);
43 while (atPos >= 0) {
44 ints.add(atPos);
45 atPos = comments.indexOf('@', atPos+1);
46 }
47
48 return ints;
49 }
50
51 protected String filteredCommentIn(Comment comment) {
52
53 String trimmed = comment.getImage().trim();
54
55 if (comment instanceof SingleLineComment) {
56 return singleLineIn(trimmed);
57 }
58 if (comment instanceof MultiLineComment) {
59 return multiLinesIn(trimmed);
60 }
61 if (comment instanceof FormalComment) {
62 return formalLinesIn(trimmed);
63 }
64
65 return trimmed;
66 }
67
68 private String singleLineIn(String comment) {
69
70 if (comment.startsWith("//")) return comment.substring(2);
71
72 return comment;
73 }
74
75 private static String asSingleString(List<String> lines) {
76
77 StringBuilder sb = new StringBuilder();
78 for (String line : lines) {
79 if (StringUtil.isEmpty(line)) continue;
80 sb.append(line).append('\n');
81 }
82
83 return sb.toString().trim();
84 }
85
86 private static String multiLinesIn(String comment) {
87
88 String[] lines = comment.split("\n");
89 List<String> filteredLines = new ArrayList<String>(lines.length);
90
91 for (String rawLine : lines) {
92 String line = rawLine.trim();
93
94 if (line.endsWith("*/")) {
95 int end = line.length()-2;
96 int start = line.startsWith("/*") ? 2 : 0;
97 filteredLines.add(line.substring(start, end));
98 continue;
99 }
100
101 if (line.length() > 0 && line.charAt(0) == '*') {
102 filteredLines.add(line.substring(1));
103 continue;
104 }
105
106 if (line.startsWith("/*")) {
107 filteredLines.add(line.substring(2));
108 continue;
109 }
110
111 }
112
113 return asSingleString(filteredLines);
114 }
115
116 private String formalLinesIn(String comment) {
117
118 String[] lines = comment.split("\n");
119 List<String> filteredLines = new ArrayList<String>(lines.length);
120
121 for (String line : lines) {
122
123 if (line.endsWith("*/")) {
124 filteredLines.add(line.substring(0, line.length()-2));
125 continue;
126 }
127
128 if (line.length() > 0 && line.charAt(0) == '*') {
129 filteredLines.add(line.substring(1));
130 continue;
131 }
132 if (line.startsWith("/**")) {
133 filteredLines.add(line.substring(3));
134 continue;
135 }
136
137 }
138
139 return asSingleString(filteredLines);
140 }
141
142 protected SortedMap<Integer, Object> orderedCommentsAndDeclarations(ASTCompilationUnit cUnit) {
143
144 SortedMap<Integer, Object> itemsByLineNumber = new TreeMap<Integer, Object>();
145
146 List<ASTPackageDeclaration> packageDecl = cUnit.findDescendantsOfType(ASTPackageDeclaration.class);
147 for (ASTPackageDeclaration decl : packageDecl) {
148 itemsByLineNumber.put(decl.getBeginLine(), decl);
149 }
150
151 for (Comment comment : cUnit.getComments()) {
152 itemsByLineNumber.put(comment.getBeginLine(), comment);
153 }
154
155 List<ASTFieldDeclaration> fields = cUnit.findDescendantsOfType(ASTFieldDeclaration.class);
156 for (ASTFieldDeclaration fieldDecl : fields) {
157 itemsByLineNumber.put(fieldDecl.getBeginLine(), fieldDecl);
158 }
159
160 List<ASTMethodDeclaration> methods = cUnit.findDescendantsOfType(ASTMethodDeclaration.class);
161 for (ASTMethodDeclaration methodDecl : methods) {
162 itemsByLineNumber.put(methodDecl.getBeginLine(), methodDecl);
163 }
164
165 System.out.println("Items:" + itemsByLineNumber);
166
167 return itemsByLineNumber;
168 }
169 }