summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android-changes.txt6
-rw-r--r--src/com/google/doclava/ClassInfo.java25
-rw-r--r--src/com/google/doclava/Errors.java9
-rw-r--r--src/com/google/doclava/FieldInfo.java10
-rw-r--r--src/com/google/doclava/MethodInfo.java31
5 files changed, 63 insertions, 18 deletions
diff --git a/android-changes.txt b/android-changes.txt
index 025bcd8..a62b071 100644
--- a/android-changes.txt
+++ b/android-changes.txt
@@ -1,6 +1,12 @@
Changes in this version relative to http://doclava.googlecode.com/
------------------------------------------------------------------
+* Added a new command line option -showAnnotation <@interface classname>,
+ which takes in a fully qualified annotation classname. The specified
+ annotation will override any @hide annotations within the javadoc. To
+ specify multiple annotations to override @hide, use multiple
+ -showAnnotation options.
+
* 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
diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java
index 927b240..d3ed434 100644
--- a/src/com/google/doclava/ClassInfo.java
+++ b/src/com/google/doclava/ClassInfo.java
@@ -247,6 +247,10 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
return mIsFinal;
}
+ public boolean isEffectivelyFinal() {
+ return mIsFinal || mApiCheckConstructors.isEmpty();
+ }
+
public boolean isIncluded() {
return mIsIncluded;
}
@@ -1694,10 +1698,25 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
+ " changed abstract qualifier");
}
- if (mIsFinal != cl.mIsFinal) {
+ if (!mIsFinal && cl.mIsFinal) {
+ /*
+ * It is safe to make a class final if it did not previously have any public
+ * constructors because it was impossible for an application to create a subclass.
+ */
+ if (mApiCheckConstructors.isEmpty()) {
+ consistent = false;
+ Errors.error(Errors.ADDED_FINAL_UNINSTANTIABLE, cl.position(),
+ "Class " + cl.qualifiedName() + " added final qualifier but "
+ + "was previously uninstantiable and therefore could not be subclassed");
+ } else {
+ consistent = false;
+ Errors.error(Errors.ADDED_FINAL, cl.position(), "Class " + cl.qualifiedName()
+ + " added final qualifier");
+ }
+ } else if (mIsFinal && !cl.mIsFinal) {
consistent = false;
- Errors.error(Errors.CHANGED_FINAL, cl.position(), "Class " + cl.qualifiedName()
- + " changed final qualifier");
+ Errors.error(Errors.REMOVED_FINAL, cl.position(), "Class " + cl.qualifiedName()
+ + " removed final qualifier");
}
if (mIsStatic != cl.mIsStatic) {
diff --git a/src/com/google/doclava/Errors.java b/src/com/google/doclava/Errors.java
index 2fc0f0c..e890aa4 100644
--- a/src/com/google/doclava/Errors.java
+++ b/src/com/google/doclava/Errors.java
@@ -134,7 +134,7 @@ public class Errors {
public static Error REMOVED_FIELD = new Error(10, WARNING);
public static Error REMOVED_INTERFACE = new Error(11, WARNING);
public static Error CHANGED_STATIC = new Error(12, WARNING);
- public static Error CHANGED_FINAL = new Error(13, WARNING);
+ public static Error ADDED_FINAL = new Error(13, WARNING);
public static Error CHANGED_TRANSIENT = new Error(14, WARNING);
public static Error CHANGED_VOLATILE = new Error(15, WARNING);
public static Error CHANGED_TYPE = new Error(16, WARNING);
@@ -147,6 +147,8 @@ public class Errors {
public static Error CHANGED_CLASS = new Error(23, WARNING);
public static Error CHANGED_DEPRECATED = new Error(24, WARNING);
public static Error CHANGED_SYNCHRONIZED = new Error(25, ERROR);
+ public static Error ADDED_FINAL_UNINSTANTIABLE = new Error(26, WARNING);
+ public static Error REMOVED_FINAL = new Error(27, WARNING);
// Errors in javadoc generation
public static final Error UNRESOLVED_LINK = new Error(101, WARNING);
@@ -175,10 +177,11 @@ public class Errors {
UNAVAILABLE_SYMBOL, HIDDEN_SUPERCLASS, DEPRECATED, DEPRECATION_MISMATCH, MISSING_COMMENT,
IO_ERROR, NO_SINCE_DATA, NO_FEDERATION_DATA, PARSE_ERROR, ADDED_PACKAGE, ADDED_CLASS,
ADDED_METHOD, ADDED_FIELD, ADDED_INTERFACE, REMOVED_PACKAGE, REMOVED_CLASS,
- REMOVED_METHOD, REMOVED_FIELD, REMOVED_INTERFACE, CHANGED_STATIC, CHANGED_FINAL,
+ REMOVED_METHOD, REMOVED_FIELD, REMOVED_INTERFACE, CHANGED_STATIC, ADDED_FINAL,
CHANGED_TRANSIENT, CHANGED_VOLATILE, CHANGED_TYPE, CHANGED_VALUE, CHANGED_SUPERCLASS,
CHANGED_SCOPE, CHANGED_ABSTRACT, CHANGED_THROWS, CHANGED_NATIVE, CHANGED_CLASS,
- CHANGED_DEPRECATED, CHANGED_SYNCHRONIZED, BROKEN_SINCE_FILE, INVALID_CONTENT_TYPE};
+ CHANGED_DEPRECATED, CHANGED_SYNCHRONIZED, ADDED_FINAL_UNINSTANTIABLE, REMOVED_FINAL,
+ BROKEN_SINCE_FILE, INVALID_CONTENT_TYPE};
public static boolean setErrorLevel(int code, int level) {
for (Error e : ERRORS) {
diff --git a/src/com/google/doclava/FieldInfo.java b/src/com/google/doclava/FieldInfo.java
index 0200b95..09391a6 100644
--- a/src/com/google/doclava/FieldInfo.java
+++ b/src/com/google/doclava/FieldInfo.java
@@ -438,9 +438,13 @@ public class FieldInfo extends MemberInfo {
consistent = false;
}
- if (mIsFinal != fInfo.mIsFinal) {
- Errors.error(Errors.CHANGED_FINAL, fInfo.position(), "Field " + fInfo.qualifiedName()
- + " has changed 'final' qualifier");
+ if (!mIsFinal && fInfo.mIsFinal) {
+ Errors.error(Errors.ADDED_FINAL, fInfo.position(), "Field " + fInfo.qualifiedName()
+ + " has added 'final' qualifier");
+ consistent = false;
+ } else if (mIsFinal && !fInfo.mIsFinal) {
+ Errors.error(Errors.REMOVED_FINAL, fInfo.position(), "Field " + fInfo.qualifiedName()
+ + " has removed 'final' qualifier");
consistent = false;
}
diff --git a/src/com/google/doclava/MethodInfo.java b/src/com/google/doclava/MethodInfo.java
index db5e0cf..fc8959f 100644
--- a/src/com/google/doclava/MethodInfo.java
+++ b/src/com/google/doclava/MethodInfo.java
@@ -624,6 +624,17 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv
return mIsVarargs;
}
+ public boolean isEffectivelyFinal() {
+ if (mIsFinal) {
+ return true;
+ }
+ ClassInfo containingClass = containingClass();
+ if (containingClass != null && containingClass.isEffectivelyFinal()) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public String toString() {
return this.name();
@@ -729,17 +740,19 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv
+ " has changed 'native' qualifier");
}
- if (mIsFinal != mInfo.mIsFinal) {
- // Compiler-generated methods vary in their 'final' qual between versions of
+ if (!mIsStatic) {
+ // Compiler-generated methods vary in their 'final' qualifier between versions of
// the compiler, so this check needs to be quite narrow. A change in 'final'
// status of a method is only relevant if (a) the method is not declared 'static'
- // and (b) the method's class is not itself 'final'.
- if (!mIsStatic) {
- if ((containingClass() == null) || (!containingClass().isFinal())) {
- consistent = false;
- Errors.error(Errors.CHANGED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName()
- + " has changed 'final' qualifier");
- }
+ // and (b) the method is not already inferred to be 'final' by virtue of its class.
+ if (!isEffectivelyFinal() && mInfo.isEffectivelyFinal()) {
+ consistent = false;
+ Errors.error(Errors.ADDED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName()
+ + " has added 'final' qualifier");
+ } else if (isEffectivelyFinal() && !mInfo.isEffectivelyFinal()) {
+ consistent = false;
+ Errors.error(Errors.REMOVED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName()
+ + " has removed 'final' qualifier");
}
}