Skip to content

Commit 1373d21

Browse files
agiagi90
authored andcommitted
Closes mozilla-mobile#35: Include parent class annotations into API.
1 parent ef22c66 commit 1373d21

File tree

3 files changed

+105
-7
lines changed

3 files changed

+105
-7
lines changed

apidoc-plugin/src/main/java/org/mozilla/doclet/ApiDoclet.java

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
import java.io.BufferedWriter;
88
import java.io.FileWriter;
99
import java.io.IOException;
10+
import java.util.ArrayList;
11+
import java.util.Arrays;
1012
import java.util.Comparator;
1113
import java.util.HashSet;
14+
import java.util.List;
1215
import java.util.Optional;
1316
import java.util.Set;
1417
import java.util.stream.Collectors;
@@ -156,8 +159,26 @@ private int compareProgramElement(ProgramElementDoc o1, ProgramElementDoc o2) {
156159
}
157160
};
158161

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+
159178
private String toLine(ClassDoc classDoc) {
160-
String classLine = annotationFragment(classDoc);
179+
String classLine = annotationFragment(
180+
collectHierarchyAnnotations(classDoc).stream());
181+
161182
classLine += classDoc.modifiers() + " ";
162183

163184
if (!classDoc.isInterface() && !classDoc.isEnum() &&
@@ -209,17 +230,21 @@ Stream.<Stream<ProgramElementDoc>> of(
209230
writer.newLine();
210231
}
211232

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)
215235
.map(AnnotationTypeDoc::toString)
216236
.filter(ANNOTATIONS::contains)
217237
.map(s -> "@" + s);
218238
}
219239

220240
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(" "));
223248
if (fragment.equals("")) {
224249
return "";
225250
}
@@ -302,10 +327,43 @@ private String typeParamsFragment(ExecutableMemberDoc executable) {
302327
return typeParamsFragment(executable.typeParameters());
303328
}
304329

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+
305362
private String toLine(ProgramElementDoc member) {
306363
String line = tag(member) + " ";
307364

308-
line += annotationFragment(member);
365+
line += annotationFragment(
366+
collectMethodHierarchyAnnotations(member).stream());
309367

310368
if (!member.modifiers().equals("")) {
311369
line += member.modifiers() + " ";

apidoc-plugin/src/test/fake_root/org/mozilla/test/TestClass.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,33 @@ public void testInterfaceMethod() {}
3636
}
3737
public static class TestExtends extends TestInterfaceImpl {}
3838

39+
@Deprecated
40+
public static class TestAnnotationBase {
41+
private TestAnnotationBase();
42+
43+
@Deprecated
44+
public void methodToOverride();
45+
}
46+
47+
public static class TestAnnotationChildShouldHaveAnnotation extends TestAnnotationBase {
48+
private TestAnnotationChildShouldHaveAnnotation();
49+
50+
@Override
51+
public void methodToOverride();
52+
53+
// NOTE: Not @Override
54+
public void methodToOverride(int overload);
55+
}
56+
57+
@Deprecated
58+
public static class TestAnnotationChildDuplicateAnnotation extends TestAnnotationBase {
59+
private TestAnnotationChildDuplicateAnnotation();
60+
61+
@Override
62+
@Deprecated
63+
public void methodToOverride();
64+
}
65+
3966
public TestClass() {}
4067
public TestClass(String arg1) {}
4168
public TestClass(String arg1, int arg2) {}

apidoc-plugin/src/test/resources/expected-doclet-output.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ package org.mozilla.test {
5656
public static interface TestClass.TestAnnotation implements java.lang.annotation.Annotation {
5757
}
5858

59+
@java.lang.Deprecated public static class TestClass.TestAnnotationBase {
60+
method @java.lang.Deprecated public void methodToOverride();
61+
}
62+
63+
@java.lang.Deprecated public static class TestClass.TestAnnotationChildDuplicateAnnotation extends org.mozilla.test.TestClass.TestAnnotationBase {
64+
method @java.lang.Deprecated public void methodToOverride();
65+
}
66+
67+
@java.lang.Deprecated public static class TestClass.TestAnnotationChildShouldHaveAnnotation extends org.mozilla.test.TestClass.TestAnnotationBase {
68+
method @java.lang.Deprecated public void methodToOverride();
69+
method public void methodToOverride(int);
70+
}
71+
5972
public static final enum TestClass.TestEnum {
6073
method public static org.mozilla.test.TestClass.TestEnum valueOf(java.lang.String);
6174
method public static org.mozilla.test.TestClass.TestEnum[] values();

0 commit comments

Comments
 (0)