|
7 | 7 | import java.io.BufferedWriter; |
8 | 8 | import java.io.FileWriter; |
9 | 9 | import java.io.IOException; |
| 10 | +import java.util.ArrayList; |
| 11 | +import java.util.Arrays; |
10 | 12 | import java.util.Comparator; |
11 | 13 | import java.util.HashSet; |
| 14 | +import java.util.List; |
12 | 15 | import java.util.Optional; |
13 | 16 | import java.util.Set; |
14 | 17 | import java.util.stream.Collectors; |
@@ -156,8 +159,26 @@ private int compareProgramElement(ProgramElementDoc o1, ProgramElementDoc o2) { |
156 | 159 | } |
157 | 160 | }; |
158 | 161 |
|
| 162 | + /** Collects all annotations in the class hierarchy. */ |
| 163 | + private List<AnnotationDesc> collectHierarchyAnnotations(ClassDoc classDoc, |
| 164 | + List<AnnotationDesc> annotations) { |
| 165 | + annotations.addAll(Arrays.asList(classDoc.annotations())); |
| 166 | + |
| 167 | + if (classDoc.superclass() != null) { |
| 168 | + collectHierarchyAnnotations(classDoc.superclass(), annotations); |
| 169 | + } |
| 170 | + |
| 171 | + return annotations; |
| 172 | + } |
| 173 | + |
| 174 | + private List<AnnotationDesc> collectHierarchyAnnotations(ClassDoc classDoc) { |
| 175 | + return collectHierarchyAnnotations(classDoc, new ArrayList<AnnotationDesc>()); |
| 176 | + } |
| 177 | + |
159 | 178 | private String toLine(ClassDoc classDoc) { |
160 | | - String classLine = annotationFragment(classDoc); |
| 179 | + String classLine = annotationFragment( |
| 180 | + collectHierarchyAnnotations(classDoc).stream()); |
| 181 | + |
161 | 182 | classLine += classDoc.modifiers() + " "; |
162 | 183 |
|
163 | 184 | if (!classDoc.isInterface() && !classDoc.isEnum() && |
@@ -209,17 +230,21 @@ Stream.<Stream<ProgramElementDoc>> of( |
209 | 230 | writer.newLine(); |
210 | 231 | } |
211 | 232 |
|
212 | | - private Stream<String> from(AnnotationDesc[] annotation) { |
213 | | - return Stream.of(annotation) |
214 | | - .map(AnnotationDesc::annotationType) |
| 233 | + private Stream<String> from(Stream<AnnotationDesc> annotations) { |
| 234 | + return annotations.map(AnnotationDesc::annotationType) |
215 | 235 | .map(AnnotationTypeDoc::toString) |
216 | 236 | .filter(ANNOTATIONS::contains) |
217 | 237 | .map(s -> "@" + s); |
218 | 238 | } |
219 | 239 |
|
220 | 240 | private String annotationFragment(ProgramElementDoc member) { |
221 | | - String fragment = from(member.annotations()) |
222 | | - .collect(Collectors.joining(" ")); |
| 241 | + return annotationFragment(Stream.of(member.annotations())); |
| 242 | + } |
| 243 | + |
| 244 | + private String annotationFragment(Stream<AnnotationDesc> annotations) { |
| 245 | + String fragment = from(annotations) |
| 246 | + .distinct() |
| 247 | + .collect(Collectors.joining(" ")); |
223 | 248 | if (fragment.equals("")) { |
224 | 249 | return ""; |
225 | 250 | } |
@@ -302,10 +327,43 @@ private String typeParamsFragment(ExecutableMemberDoc executable) { |
302 | 327 | return typeParamsFragment(executable.typeParameters()); |
303 | 328 | } |
304 | 329 |
|
| 330 | + private ExecutableMemberDoc findSuperMethod(ExecutableMemberDoc member) { |
| 331 | + ClassDoc superClass = member.containingClass().superclass(); |
| 332 | + if (superClass == null) { |
| 333 | + return null; |
| 334 | + } |
| 335 | + |
| 336 | + return Stream.of(superClass.methods()) |
| 337 | + .filter(m -> m.name().equals(member.name()) |
| 338 | + && paramsFragment(m).equals(paramsFragment(member))) |
| 339 | + .findFirst() |
| 340 | + .orElse(null); |
| 341 | + } |
| 342 | + |
| 343 | + private List<AnnotationDesc> collectMethodHierarchyAnnotations( |
| 344 | + ProgramElementDoc member, |
| 345 | + List<AnnotationDesc> annotations) { |
| 346 | + annotations.addAll(Arrays.asList(member.annotations())); |
| 347 | + |
| 348 | + if (member instanceof ExecutableMemberDoc) { |
| 349 | + ProgramElementDoc superMethod = findSuperMethod((ExecutableMemberDoc) member); |
| 350 | + if (superMethod != null) { |
| 351 | + collectMethodHierarchyAnnotations(superMethod, annotations); |
| 352 | + } |
| 353 | + } |
| 354 | + |
| 355 | + return annotations; |
| 356 | + } |
| 357 | + |
| 358 | + private List<AnnotationDesc> collectMethodHierarchyAnnotations(ProgramElementDoc member) { |
| 359 | + return collectMethodHierarchyAnnotations(member, new ArrayList<AnnotationDesc>()); |
| 360 | + } |
| 361 | + |
305 | 362 | private String toLine(ProgramElementDoc member) { |
306 | 363 | String line = tag(member) + " "; |
307 | 364 |
|
308 | | - line += annotationFragment(member); |
| 365 | + line += annotationFragment( |
| 366 | + collectMethodHierarchyAnnotations(member).stream()); |
309 | 367 |
|
310 | 368 | if (!member.modifiers().equals("")) { |
311 | 369 | line += member.modifiers() + " "; |
|
0 commit comments