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