Fix doclava to preserve annotations on fields and methods
The android.jar stubs file used in the SDK was missing @Deprecated
annotations on methods and fields.
This changeset updates doclava to write annotations on methods and
fields as well, and to also add a @Deprecated annotation for APIs that
were marked deprecated but missing an annotation (presumably because
they only used the @deprecated doc comment; there are about 30 such
APIs out of 800+ deprecation usages.)
This fixes
http://code.google.com/p/android/issues/detail?id=26173
Change-Id: Iad675d4cfdf650165bfb7050cdcc0978c3a72d55
diff --git a/android-changes.txt b/android-changes.txt
new file mode 100644
index 0000000..025bcd8
--- /dev/null
+++ b/android-changes.txt
@@ -0,0 +1,12 @@
+Changes in this version relative to http://doclava.googlecode.com/
+------------------------------------------------------------------
+
+* Modified the Java stub generator code to write out annotations for
+ methods and fields as well, not just classes. This meant adding a
+ writeAnnotations call to writeMethod and to writeField
+
+* Modified the writeAnnotations method to take a "isDeprecated"
+ parameter, which when set adds a @Deprecated annotation if one
+ doesn't already exist. This ensures that APIs only marked with a
+ @deprecated documentation comment will also be marked as
+ @Deprecated. Also strips out @Override annotations.
diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java
index c83731a..b493aa0 100644
--- a/src/com/google/doclava/Stubs.java
+++ b/src/com/google/doclava/Stubs.java
@@ -324,7 +324,7 @@
}
static void writeClass(PrintStream stream, HashSet<ClassInfo> notStrippable, ClassInfo cl) {
- writeAnnotations(stream, cl.annotations());
+ writeAnnotations(stream, cl.annotations(), cl.isDeprecated());
stream.print(cl.scope() + " ");
if (cl.isAbstract() && !cl.isAnnotation() && !cl.isInterface()) {
@@ -498,6 +498,8 @@
static void writeMethod(PrintStream stream, MethodInfo method, boolean isConstructor) {
String comma;
+ writeAnnotations(stream, method.annotations(), method.isDeprecated());
+
stream.print(method.scope() + " ");
if (method.isStatic()) {
stream.print("static ");
@@ -560,6 +562,8 @@
}
static void writeField(PrintStream stream, FieldInfo field) {
+ writeAnnotations(stream, field.annotations(), field.isDeprecated());
+
stream.print(field.scope() + " ");
if (field.isStatic()) {
stream.print("static ");
@@ -712,12 +716,35 @@
}
}
- static void writeAnnotations(PrintStream stream, ArrayList<AnnotationInstanceInfo> annotations) {
+ /**
+ * Write out the given list of annotations. If the {@code isDeprecated}
+ * flag is true also write out a {@code @Deprecated} annotation if it did not
+ * already appear in the list of annotations. (This covers APIs that mention
+ * {@code @deprecated} in their documentation but fail to add
+ * {@code @Deprecated} as an annotation.
+ * <p>
+ * {@code @Override} annotations are deliberately skipped.
+ */
+ static void writeAnnotations(PrintStream stream, List<AnnotationInstanceInfo> annotations,
+ boolean isDeprecated) {
+ assert annotations != null;
for (AnnotationInstanceInfo ann : annotations) {
+ // Skip @Override annotations: the stubs do not need it and in some cases it leads
+ // to compilation errors with the way the stubs are generated
+ if (ann.type() != null && ann.type().qualifiedName().equals("java.lang.Override")) {
+ continue;
+ }
if (!ann.type().isHidden()) {
stream.println(ann.toString());
+ if (isDeprecated && ann.type() != null
+ && ann.type().qualifiedName().equals("java.lang.Deprecated")) {
+ isDeprecated = false; // Prevent duplicate annotations
+ }
}
}
+ if (isDeprecated) {
+ stream.println("@Deprecated");
+ }
}
static void writeAnnotationElement(PrintStream stream, MethodInfo ann) {