From eb9343ecf5a1b2d324445db39195bcfc9dd01ebf Mon Sep 17 00:00:00 2001 From: Maurice Chu Date: Tue, 6 Nov 2012 11:30:22 -0800 Subject: Added -showAnnotation option to DocLava The -showAnnotation command-line option specified the fully qualified classname for an @interface declaration, which if present on a class, method, or field, will override any @hide annotations in the javadoc comments. Bug: 7457598 Change-Id: I4f21d9bacf60875c1b7444bb9139091e9a505bb5 --- android-changes.txt | 6 ++++++ src/com/google/doclava/ClassInfo.java | 29 +++++++++++++++++------------ src/com/google/doclava/Doclava.java | 8 +++++++- 3 files changed, 30 insertions(+), 13 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 f4f2853..5d6c811 100644 --- a/src/com/google/doclava/ClassInfo.java +++ b/src/com/google/doclava/ClassInfo.java @@ -44,13 +44,13 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco return a.qualifiedName().compareTo(b.qualifiedName()); } }; - + /** * Constructs a stub representation of a class. */ public ClassInfo(String qualifiedName) { super("", SourcePositionInfo.UNKNOWN); - + mQualifiedName = qualifiedName; if (qualifiedName.lastIndexOf('.') != -1) { mName = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1); @@ -1195,6 +1195,11 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco if (pkg != null && pkg.isHidden()) { return true; } + for (AnnotationInstanceInfo info : cl.annotations()) { + if (Doclava.showAnnotations.contains(info.type().qualifiedName())) { + return false; + } + } if (cl.comment().isHidden()) { return true; } @@ -1244,7 +1249,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco return null; } - + public boolean supportsMethod(MethodInfo method) { for (MethodInfo m : methods()) { if (m.getHashableName().equals(method.getHashableName())) { @@ -1373,7 +1378,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco } return null; } - + public String scope() { if (isPublic()) { return "public"; @@ -1467,7 +1472,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco private String mReasonIncluded; private ArrayList mNonWrittenConstructors; private boolean mIsDeprecated; - + // TODO: Temporary members from apicheck migration. private HashMap mApiCheckConstructors = new HashMap(); private HashMap mApiCheckMethods = new HashMap(); @@ -1476,7 +1481,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco // Resolutions private ArrayList mResolutions; - + /** * Returns true if {@code cl} implements the interface {@code iface} either by either being that * interface, implementing that interface or extending a type that implements the interface. @@ -1538,7 +1543,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco * Returns all methods defined directly in this class. For a list of all * methods supported by this class, see {@link #methods()}. */ - + public Map allMethods() { return mApiCheckMethods; } @@ -1553,7 +1558,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco } return result; } - + public String superclassName() { if (mSuperclass == null) { if (mQualifiedName.equals("java.lang.Object")) { @@ -1563,11 +1568,11 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco } return mSuperclass.mQualifiedName; } - + public void setAnnotations(ArrayList annotations) { mAnnotations = annotations; } - + public boolean isConsistent(ClassInfo cl) { boolean consistent = true; @@ -1727,7 +1732,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco return consistent; } - + // Find a superclass implementation of the given method. public static MethodInfo overriddenMethod(MethodInfo candidate, ClassInfo newClassObj) { if (newClassObj == null) { @@ -1758,7 +1763,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco } return ClassInfo.interfaceMethod(candidate, newClassObj.mSuperclass); } - + public boolean hasConstructor(MethodInfo constructor) { String name = constructor.getHashableName(); for (MethodInfo ctor : mApiCheckConstructors.values()) { diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index b7e06cb..7ef01b1 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -74,6 +74,7 @@ public class Doclava { public static SinceTagger sinceTagger = new SinceTagger(); public static HashSet knownTags = new HashSet(); public static FederationTagger federationTagger = new FederationTagger(); + public static Set showAnnotations = new HashSet(); private static boolean generateDocs = true; private static boolean parseComments = false; private static String yamlNavFile = null; @@ -172,8 +173,10 @@ public class Doclava { } } else if (a[0].equals("-keeplist")) { keepListFile = a[1]; + } else if (a[0].equals("-showAnnotation")) { + showAnnotations.add(a[1]); } else if (a[0].equals("-proguard")) { - proguardFile = a[1]; + proguardFile = a[1]; } else if (a[0].equals("-proofread")) { proofreadFile = a[1]; } else if (a[0].equals("-todo")) { @@ -493,6 +496,9 @@ public class Doclava { if (option.equals("-keeplist")) { return 2; } + if (option.equals("-showAnnotation")) { + return 2; + } if (option.equals("-proguard")) { return 2; } -- cgit v1.2.3 From 58460224d368b93f5aa6a22a73b0bfe7e79f07b1 Mon Sep 17 00:00:00 2001 From: Maurice Chu Date: Tue, 6 Nov 2012 12:01:07 -0800 Subject: Fix NPE when looking for annotation in isHiddenImpl() Change-Id: Idaebcf456ffe06d0147436986975081bf1162699 --- src/com/google/doclava/ClassInfo.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java index 5d6c811..24b6b32 100644 --- a/src/com/google/doclava/ClassInfo.java +++ b/src/com/google/doclava/ClassInfo.java @@ -1195,9 +1195,11 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco if (pkg != null && pkg.isHidden()) { return true; } - for (AnnotationInstanceInfo info : cl.annotations()) { - if (Doclava.showAnnotations.contains(info.type().qualifiedName())) { - return false; + if (cl.annotations() != null) { + for (AnnotationInstanceInfo info : cl.annotations()) { + if (Doclava.showAnnotations.contains(info.type().qualifiedName())) { + return false; + } } } if (cl.comment().isHidden()) { -- cgit v1.2.3 From ca151a9bbea066b0efd0e423bcade8895a83db71 Mon Sep 17 00:00:00 2001 From: Jeff Hamilton Date: Mon, 12 Nov 2012 17:11:27 -0600 Subject: Allow show annotations on fields and methods. Change-Id: I2556eae6cd8e84345040ad7a0c0bc7b33dda1536 --- src/com/google/doclava/ClassInfo.java | 8 ++++---- src/com/google/doclava/MemberInfo.java | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java index 24b6b32..6e5aab2 100644 --- a/src/com/google/doclava/ClassInfo.java +++ b/src/com/google/doclava/ClassInfo.java @@ -1196,11 +1196,11 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco return true; } if (cl.annotations() != null) { - for (AnnotationInstanceInfo info : cl.annotations()) { - if (Doclava.showAnnotations.contains(info.type().qualifiedName())) { - return false; - } + for (AnnotationInstanceInfo info : cl.annotations()) { + if (Doclava.showAnnotations.contains(info.type().qualifiedName())) { + return false; } + } } if (cl.comment().isHidden()) { return true; diff --git a/src/com/google/doclava/MemberInfo.java b/src/com/google/doclava/MemberInfo.java index 5600749..e5cc7a2 100644 --- a/src/com/google/doclava/MemberInfo.java +++ b/src/com/google/doclava/MemberInfo.java @@ -42,6 +42,18 @@ public abstract class MemberInfo extends DocInfo implements Comparable, Scoped { public abstract boolean isExecutable(); + @Override + public boolean isHidden() { + if (mAnnotations != null) { + for (AnnotationInstanceInfo info : mAnnotations) { + if (Doclava.showAnnotations.contains(info.type().qualifiedName())) { + return false; + } + } + } + return super.isHidden(); + } + public String anchor() { if (mSignature != null) { return mName + mSignature; -- cgit v1.2.3 From 88c435bb4d6c81c41107e23503b59af2e08acd8d Mon Sep 17 00:00:00 2001 From: Robert Ly Date: Fri, 1 Feb 2013 11:55:04 -0800 Subject: update doclava for s.a.c redesign Change-Id: I4788472ea2ba923070362624f75fe72bf5b43df7 Conflicts: src/com/google/doclava/ClearPage.java --- src/com/google/doclava/ClearPage.java | 15 +++++++++++---- src/com/google/doclava/DocFile.java | 8 ++++++++ src/com/google/doclava/Doclava.java | 8 ++++++-- src/com/google/doclava/SampleCode.java | 4 ++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/com/google/doclava/ClearPage.java b/src/com/google/doclava/ClearPage.java index 9c512c9..4a6d39a 100644 --- a/src/com/google/doclava/ClearPage.java +++ b/src/com/google/doclava/ClearPage.java @@ -28,6 +28,7 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; +import java.util.Arrays; public class ClearPage { /* @@ -156,7 +157,7 @@ public class ClearPage { } } - public static void copyFile(File from, String toPath) { + public static void copyFile(boolean allowExcepted, File from, String toPath) { File to = new File(outputDir + "/" + toPath); FileInputStream in; FileOutputStream out; @@ -176,7 +177,7 @@ public class ClearPage { System.err.println(from.getAbsolutePath() + ": Error opening file"); return; } - if (!isValidContentType(toPath, DROIDDOC_VALID_CONTENT_TYPES)) { + if (!isValidContentType(allowExcepted, toPath, DROIDDOC_VALID_CONTENT_TYPES)) { Errors.error(Errors.INVALID_CONTENT_TYPE, null, "Failed to process " + from + ": Invalid file type. Please move the file to frameworks/base/docs/image_sources/... or docs/downloads/..."); return; @@ -220,9 +221,15 @@ public class ClearPage { } } - public static String[] DROIDDOC_VALID_CONTENT_TYPES = {".txt", ".css", ".js", ".html", ".ico", ".png", ".jpg", ".gif", ".svg", ".webm", ".ogv","mp4", ".java", ".xml", ".aidl", ".rs",".zip", ".yaml", ".pdf"}; + public static ArrayList DROIDDOC_VALID_CONTENT_TYPES = new ArrayList(Arrays.asList(".txt", ".css", + ".js", ".html", ".ico", ".png", ".jpg", ".gif", ".svg", ".webm", ".ogv","mp4", ".java", ".xml", ".aidl", ".rs",".zip", ".yaml")); - public static boolean isValidContentType(String s, String[] list) { + public static ArrayList DROIDDOC_EXCEPTED_CONTENT_TYPES = new ArrayList(Arrays.asList(".pdf")); + + public static boolean isValidContentType(boolean allowExcepted, String s, ArrayList list) { + if(allowExcepted){ + list.addAll(DROIDDOC_EXCEPTED_CONTENT_TYPES); + } for (String t : list) { if (s.endsWith(t)) { return true; diff --git a/src/com/google/doclava/DocFile.java b/src/com/google/doclava/DocFile.java index da829a4..dd0a6bc 100644 --- a/src/com/google/doclava/DocFile.java +++ b/src/com/google/doclava/DocFile.java @@ -164,6 +164,14 @@ public class DocFile { } else if ((filename.indexOf("tools") == 0) || (filename.indexOf("sdk") == 0)) { hdf.setValue("tools", "true"); fromTemplate = hdf.getValue("page.template", ""); + } else if (filename.indexOf("devices") == 0) { + hdf.setValue("devices", "true"); + } else if (filename.indexOf("source") == 0) { + hdf.setValue("source", "true"); + } else if (filename.indexOf("accessories") == 0) { + hdf.setValue("accessories", "true"); + } else if (filename.indexOf("compatibility") == 0) { + hdf.setValue("compatibility", "true"); } if (fromTemplate.equals("sdk")) { ClearPage.write(hdf, "sdkpage.cs", outfile); diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index 4435018..a239210 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -90,6 +90,7 @@ public class Doclava { private static boolean gmsRef = false; private static boolean gcmRef = false; + private static boolean sac = false; public static boolean checkLevel(int level) { return (showLevel & level) == level; @@ -735,8 +736,11 @@ public class Doclava { } else if (len > 3 && ".jd".equals(templ.substring(len - 3))) { String filename = templ.substring(0, len - 3) + htmlExtension; DocFile.writePage(f.getAbsolutePath(), relative, filename); - } else { - ClearPage.copyFile(f, templ); + } else if(!f.getName().equals(".DS_Store")){ + Data data = makeHDF(); + String hdfValue = data.getValue("sac") == null ? "" : data.getValue("sac"); + boolean allowExcepted = hdfValue.equals("true") ? true : false; + ClearPage.copyFile(allowExcepted, f, templ); } } else if (f.isDirectory()) { writeDirectory(f, relative + f.getName() + "/", js); diff --git a/src/com/google/doclava/SampleCode.java b/src/com/google/doclava/SampleCode.java index 0776af1..65d44b5 100644 --- a/src/com/google/doclava/SampleCode.java +++ b/src/com/google/doclava/SampleCode.java @@ -84,13 +84,13 @@ public class SampleCode { if (inList(out, IMAGES)) { // copied directly - ClearPage.copyFile(f, out); + ClearPage.copyFile(false, f, out); writeImagePage(f, convertExtension(out, Doclava.htmlExtension), subdir); files.add(name); } if (inList(out, TEMPLATED)) { // copied and goes through the template - ClearPage.copyFile(f, out); + ClearPage.copyFile(false, f, out); writePage(f, convertExtension(out, Doclava.htmlExtension), subdir); files.add(name); } -- cgit v1.2.3 From f2a427d942636370bafe20d3852622f026f2511f Mon Sep 17 00:00:00 2001 From: Robert Ly Date: Wed, 20 Feb 2013 14:28:57 -0800 Subject: add support for differently named lists.js files Change-Id: I5eaf20ad661a5582c45e30b9bed308d9714f02e3 --- src/com/google/doclava/Doclava.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index a239210..c26e849 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -830,8 +830,13 @@ public class Doclava { } i++; } - - ClearPage.write(data, "lists.cs", javadocDir + "lists.js"); + String listNamePrefix = new String(""); + if(gcmRef) + listNamePrefix="gcm_"; + else if (gmsRef){ + listNamePrefix="gms_"; + } + ClearPage.write(data, listNamePrefix + "lists.cs", javadocDir + listNamePrefix + "lists.js"); } public static void cantStripThis(ClassInfo cl, HashSet notStrippable) { -- cgit v1.2.3 From 57657b935a6aefc36b2a7f5704665e4da818c3e6 Mon Sep 17 00:00:00 2001 From: Robert Ly Date: Thu, 21 Feb 2013 02:00:37 +0000 Subject: Revert "add support for differently named lists.js files" This reverts commit f2a427d942636370bafe20d3852622f026f2511f Change-Id: I190c9e95af040a7ff384f211649fb766a1b6e805 --- src/com/google/doclava/Doclava.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index c26e849..a239210 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -830,13 +830,8 @@ public class Doclava { } i++; } - String listNamePrefix = new String(""); - if(gcmRef) - listNamePrefix="gcm_"; - else if (gmsRef){ - listNamePrefix="gms_"; - } - ClearPage.write(data, listNamePrefix + "lists.cs", javadocDir + listNamePrefix + "lists.js"); + + ClearPage.write(data, "lists.cs", javadocDir + "lists.js"); } public static void cantStripThis(ClassInfo cl, HashSet notStrippable) { -- cgit v1.2.3 From 4c95e6c9a7c559fd66e8085c239832d505d4fbf9 Mon Sep 17 00:00:00 2001 From: Robert Ly Date: Fri, 15 Mar 2013 14:10:44 -0700 Subject: remove file type check for s.a.c Change-Id: I926b2e189cb6eee3ec81e69886a917ddd6b73a85 --- src/com/google/doclava/ClearPage.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/google/doclava/ClearPage.java b/src/com/google/doclava/ClearPage.java index 4a6d39a..ed1f069 100644 --- a/src/com/google/doclava/ClearPage.java +++ b/src/com/google/doclava/ClearPage.java @@ -223,8 +223,10 @@ public class ClearPage { public static ArrayList DROIDDOC_VALID_CONTENT_TYPES = new ArrayList(Arrays.asList(".txt", ".css", ".js", ".html", ".ico", ".png", ".jpg", ".gif", ".svg", ".webm", ".ogv","mp4", ".java", ".xml", ".aidl", ".rs",".zip", ".yaml")); - - public static ArrayList DROIDDOC_EXCEPTED_CONTENT_TYPES = new ArrayList(Arrays.asList(".pdf")); + /* Setting excepted types to allow everything. Leaving it this way in in case we want to explicitly + * specify file types later. This adds unneeded checking though since it lets everything through + */ + public static ArrayList DROIDDOC_EXCEPTED_CONTENT_TYPES = new ArrayList(Arrays.asList("")); public static boolean isValidContentType(boolean allowExcepted, String s, ArrayList list) { if(allowExcepted){ -- cgit v1.2.3 From 43d2ac8017a651b5678c8a9753248663d8bfe9a7 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 1 Apr 2013 13:40:01 -0700 Subject: apicheck: Allow safe addition and removal of final qualifier. Split the CHANGED_FINAL error into ADDED_FINAL, ADDED_FINAL_UNINSTANTIABLE and REMOVED_FINAL so that the API check scripts can more precisely target policy around changes to the final qualifier. ADDED_FINAL_UNINSTANTIABLE covers the case of a class that has become final but that was previously not instantiable. This change is safe since applications could not have declared subclasses of their own. Change-Id: I36a143bdbcffd04379788a55ff996b47398ba4fe --- src/com/google/doclava/ClassInfo.java | 21 ++++++++++++++++++--- src/com/google/doclava/Errors.java | 9 ++++++--- src/com/google/doclava/FieldInfo.java | 10 +++++++--- src/com/google/doclava/MethodInfo.java | 24 +++++++++++++++--------- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java index 927b240..f3993eb 100644 --- a/src/com/google/doclava/ClassInfo.java +++ b/src/com/google/doclava/ClassInfo.java @@ -1694,10 +1694,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..b6a5cc3 100644 --- a/src/com/google/doclava/MethodInfo.java +++ b/src/com/google/doclava/MethodInfo.java @@ -624,6 +624,10 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv return mIsVarargs; } + public boolean isFinalOrBelongsToFinalClass() { + return mIsFinal || (containingClass() != null && containingClass().isFinal()); + } + @Override public String toString() { return this.name(); @@ -729,17 +733,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 (!isFinalOrBelongsToFinalClass() && mInfo.isFinalOrBelongsToFinalClass()) { + consistent = false; + Errors.error(Errors.ADDED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName() + + " has added 'final' qualifier"); + } else if (isFinalOrBelongsToFinalClass() && !mInfo.isFinalOrBelongsToFinalClass()) { + consistent = false; + Errors.error(Errors.REMOVED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName() + + " has removed 'final' qualifier"); } } -- cgit v1.2.3 From 722ac6ad427cab1d8d6daba6bd100afa9dd94fb7 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 1 Apr 2013 17:07:37 -0700 Subject: apicheck: Handle more special cases for final. It's ok to make a method final if it belongs to a class that is effectively final (no public constructors). Change-Id: I6c497e68a91f99eee124e9dbe3d075c6672c4615 --- src/com/google/doclava/ClassInfo.java | 4 ++++ src/com/google/doclava/MethodInfo.java | 15 +++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java index f3993eb..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; } diff --git a/src/com/google/doclava/MethodInfo.java b/src/com/google/doclava/MethodInfo.java index b6a5cc3..fc8959f 100644 --- a/src/com/google/doclava/MethodInfo.java +++ b/src/com/google/doclava/MethodInfo.java @@ -624,8 +624,15 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv return mIsVarargs; } - public boolean isFinalOrBelongsToFinalClass() { - return mIsFinal || (containingClass() != null && containingClass().isFinal()); + public boolean isEffectivelyFinal() { + if (mIsFinal) { + return true; + } + ClassInfo containingClass = containingClass(); + if (containingClass != null && containingClass.isEffectivelyFinal()) { + return true; + } + return false; } @Override @@ -738,11 +745,11 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv // 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 is not already inferred to be 'final' by virtue of its class. - if (!isFinalOrBelongsToFinalClass() && mInfo.isFinalOrBelongsToFinalClass()) { + if (!isEffectivelyFinal() && mInfo.isEffectivelyFinal()) { consistent = false; Errors.error(Errors.ADDED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName() + " has added 'final' qualifier"); - } else if (isFinalOrBelongsToFinalClass() && !mInfo.isFinalOrBelongsToFinalClass()) { + } else if (isEffectivelyFinal() && !mInfo.isEffectivelyFinal()) { consistent = false; Errors.error(Errors.REMOVED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName() + " has removed 'final' qualifier"); -- cgit v1.2.3 From 74c2081b80e20f7851af91aff33aee263a7282f8 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Fri, 5 Apr 2013 13:38:35 -0700 Subject: if there's no api level available for deprecated version, provide different message Change-Id: I7268d2bc7cdbcfb08cafd5249f9b6c51e42c4bc2 --- res/assets/templates/macros.cs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/res/assets/templates/macros.cs b/res/assets/templates/macros.cs index bc6e46d..867abcd 100644 --- a/res/assets/templates/macros.cs +++ b/res/assets/templates/macros.cs @@ -101,23 +101,31 @@ def:tag_list(tags) ?> - This was deprecated - in API level . - + This was deprecated + in API level . + This is deprecated. +

-

- This was deprecated - in API level .
-

+ This was deprecated + in API level . + This is deprecated.
+ +

Date: Fri, 8 Mar 2013 18:59:15 -0800 Subject: add logic to doclava to generate meta-data JSON for .jd files. This will be used to provide search suggestions for all docs, and also automated "see also" links in doc TOC for pages w/ matching tags Change-Id: I0aefc929bc97ad6eaee77c7094d23c7f57afdf7b --- res/assets/templates/jd_lists.cs | 8 ++++ src/com/google/doclava/DocFile.java | 4 +- src/com/google/doclava/Doclava.java | 84 ++++++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 res/assets/templates/jd_lists.cs diff --git a/res/assets/templates/jd_lists.cs b/res/assets/templates/jd_lists.cs new file mode 100644 index 0000000..e205032 --- /dev/null +++ b/res/assets/templates/jd_lists.cs @@ -0,0 +1,8 @@ +var JD_DATA = [ + + { label:"", link:"", + tags:[], type:"" }, +]; diff --git a/src/com/google/doclava/DocFile.java b/src/com/google/doclava/DocFile.java index dd0a6bc..9e56235 100644 --- a/src/com/google/doclava/DocFile.java +++ b/src/com/google/doclava/DocFile.java @@ -24,8 +24,8 @@ import java.util.regex.Matcher; public class DocFile { - private static final Pattern LINE = Pattern.compile("(.*)[\r]?\n", Pattern.MULTILINE); - private static final Pattern PROP = Pattern.compile("([^=]+)=(.*)"); + public static final Pattern LINE = Pattern.compile("(.*)[\r]?\n", Pattern.MULTILINE); + public static final Pattern PROP = Pattern.compile("([^=]+)=(.*)"); public static String readFile(String filename) { try { diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index a239210..33f68c0 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -27,6 +27,7 @@ import com.sun.javadoc.*; import java.util.*; import java.util.jar.JarFile; +import java.util.regex.Matcher; import java.io.*; import java.lang.reflect.Proxy; import java.lang.reflect.Array; @@ -792,7 +793,11 @@ public class Doclava { ClearPage.write(timedata, "timestamp.cs", "timestamp.js"); } + /** Go through the docs and generate meta-data about each + page to use in search suggestions */ public static void writeLists() { + + // Write the lists for API references Data data = makeHDF(); ClassInfo[] classes = Converter.rootClasses(); @@ -830,8 +835,85 @@ public class Doclava { } i++; } - ClearPage.write(data, "lists.cs", javadocDir + "lists.js"); + + + // Write the lists for JD documents + Data jddata = makeHDF(); + Iterator counter = new Iterator(); + for (String htmlDir : inputPathHtmlDirs) { + File dir = new File(htmlDir); + if (!dir.isDirectory()) { + continue; + } + writeJdDirList(dir, jddata, counter); + } + ClearPage.write(jddata, "jd_lists.cs", javadocDir + "jd_lists.js"); + } + + private static class Iterator { + int i = 0; + } + + /** Write meta-data for a JD file, used for search suggestions */ + private static void writeJdDirList(File dir, Data data, Iterator counter) { + File[] files = dir.listFiles(); + int i, count = files.length; + // Loop all files in given directory + for (i = 0; i < count; i++) { + File f = files[i]; + if (f.isFile()) { + String filePath = f.getAbsolutePath(); + String templ = f.getName(); + int len = templ.length(); + // If it's a .jd file we want to process + if (len > 3 && ".jd".equals(templ.substring(len - 3))) { + // remove the directories below the site root + String webPath = filePath.substring(filePath.indexOf("docs/html/") + 10, filePath.length()); + // replace .jd with .html + webPath = webPath.substring(0, webPath.length() - 3) + htmlExtension; + // Parse the .jd file for properties data at top of page + Data hdf = Doclava.makeHDF(); + String filedata = DocFile.readFile(filePath); + Matcher lines = DocFile.LINE.matcher(filedata); + String line = null; + // Get each line to add the key-value to hdf + while (lines.find()) { + line = lines.group(1); + if (line.length() > 0) { + // Stop when we hit the body + if (line.equals("@jd:body")) { + break; + } + Matcher prop = DocFile.PROP.matcher(line); + if (prop.matches()) { + String key = prop.group(1); + String value = prop.group(2); + hdf.setValue(key, value); + } else { + break; + } + } + } // done gathering page properties + + // Insert the goods into HDF data (title, link, tags, type) + String title = hdf.getValue("page.title", ""); + String tags = hdf.getValue("page.tags", ""); + String dirName = (webPath.indexOf("/") != -1) + ? webPath.substring(0, webPath.indexOf("/")) : ""; + + if (!"".equals(title) && !"intl".equals(dirName)) { + data.setValue("docs.pages." + counter.i + ".label", title.replaceAll("\"", "'")); + data.setValue("docs.pages." + counter.i + ".link", webPath); + data.setValue("docs.pages." + counter.i + ".tags", tags); + data.setValue("docs.pages." + counter.i + ".type", dirName); + counter.i++; + } + } + } else if (f.isDirectory()) { + writeJdDirList(f, data, counter); + } + } } public static void cantStripThis(ClassInfo cl, HashSet notStrippable) { -- cgit v1.2.3 From 9950dd094869cc176d63050a9e1ac3d0b4053f84 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Thu, 11 Apr 2013 19:03:58 -0700 Subject: strip tags from document titles for search suggest Change-Id: I7fcae84660f174b8c6afd2166b38f1686ff16bdd --- src/com/google/doclava/Doclava.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index 33f68c0..38f40d6 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -898,12 +898,21 @@ public class Doclava { // Insert the goods into HDF data (title, link, tags, type) String title = hdf.getValue("page.title", ""); + title = title.replaceAll("\"", "'"); + // if there's a in the title, get rid of it + if (title.indexOf(""); + title = splitTitle[0]; + for (int j = 1; j < splitTitle.length; j++) { + title.concat(splitTitle[j]); + } + } String tags = hdf.getValue("page.tags", ""); String dirName = (webPath.indexOf("/") != -1) ? webPath.substring(0, webPath.indexOf("/")) : ""; if (!"".equals(title) && !"intl".equals(dirName)) { - data.setValue("docs.pages." + counter.i + ".label", title.replaceAll("\"", "'")); + data.setValue("docs.pages." + counter.i + ".label", title); data.setValue("docs.pages." + counter.i + ".link", webPath); data.setValue("docs.pages." + counter.i + ".tags", tags); data.setValue("docs.pages." + counter.i + ".type", dirName); -- cgit v1.2.3 From 489864e7dd2eee3f6a90919e5084964ad4d8b3c7 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Fri, 12 Apr 2013 11:20:51 -0700 Subject: add ability to manually exclude files from search suggestions. Use the hdf tag excludeFromSuggestions=true Change-Id: If2f0f0f19f0e3b27adf69e09b9527e8d97213db5 --- src/com/google/doclava/Doclava.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index 38f40d6..61b1c6c 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -911,7 +911,9 @@ public class Doclava { String dirName = (webPath.indexOf("/") != -1) ? webPath.substring(0, webPath.indexOf("/")) : ""; - if (!"".equals(title) && !"intl".equals(dirName)) { + if (!"".equals(title) && + !"intl".equals(dirName) && + !hdf.getBooleanValue("excludeFromSuggestions")) { data.setValue("docs.pages." + counter.i + ".label", title); data.setValue("docs.pages." + counter.i + ".link", webPath); data.setValue("docs.pages." + counter.i + ".tags", tags); -- cgit v1.2.3 From e65daec66ebdf02baa00c0ee403321fa304f7ad5 Mon Sep 17 00:00:00 2001 From: Dirk Dougherty Date: Mon, 29 Apr 2013 18:44:48 -0700 Subject: Add doclava command line option to bypass copying of default doclava assets dir to output. Change-Id: Idb4425fcc7cf709efa22bab3876cc108c4ab7f9d --- src/com/google/doclava/Doclava.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index a239210..168361d 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -225,6 +225,8 @@ public class Doclava { apiFile = a[1]; } else if (a[0].equals("-nodocs")) { generateDocs = false; + } else if (a[0].equals("-nodefaultassets")) { + includeDefaultAssets = false; } else if (a[0].equals("-parsecomments")) { parseComments = true; } else if (a[0].equals("-since")) { @@ -584,6 +586,9 @@ public class Doclava { if (option.equals("-nodocs")) { return 1; } + if (option.equals("-nodefaultassets")) { + return 1; + } if (option.equals("-parsecomments")) { return 1; } -- cgit v1.2.3 From 68a238ae4243e6f0f2a370b8b915ef0686ca0b37 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Tue, 30 Apr 2013 12:34:19 -0700 Subject: add deprecated true/false to lists.js to help sort search suggestions Change-Id: Ia34c5139bc637ce24a91aef830356606e4c7a4c2 --- res/assets/templates/lists.cs | 2 +- src/com/google/doclava/DocInfo.java | 4 ++++ src/com/google/doclava/Doclava.java | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/res/assets/templates/lists.cs b/res/assets/templates/lists.cs index 0af32b2..dcbf8e5 100644 --- a/res/assets/templates/lists.cs +++ b/res/assets/templates/lists.cs @@ -1,5 +1,5 @@ var DATA = [ { id:, label:"", link:"", type:"" }, +?> { id:, label:"", link:"", type:"", deprecated:"" }, ]; diff --git a/src/com/google/doclava/DocInfo.java b/src/com/google/doclava/DocInfo.java index 935bbda..714beb8 100644 --- a/src/com/google/doclava/DocInfo.java +++ b/src/com/google/doclava/DocInfo.java @@ -93,6 +93,10 @@ public abstract class DocInfo { return mDeprecatedSince; } + public boolean isDeprecated() { + return mDeprecatedSince != null ? true : false; + } + public final void addFederatedReference(FederatedSite source) { mFederatedReferences.add(source); } diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index 30ef4da..d916161 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -833,10 +833,12 @@ public class Doclava { PackageInfo pkg = (PackageInfo) o; data.setValue("docs.pages." + i + ".link", pkg.htmlPage()); data.setValue("docs.pages." + i + ".type", "package"); + data.setValue("docs.pages." + i + ".deprecated", pkg.isDeprecated() ? "true" : "false"); } else if (o instanceof ClassInfo) { ClassInfo cl = (ClassInfo) o; data.setValue("docs.pages." + i + ".link", cl.htmlPage()); data.setValue("docs.pages." + i + ".type", "class"); + data.setValue("docs.pages." + i + ".deprecated", cl.isDeprecated() ? "true" : "false"); } i++; } -- cgit v1.2.3 From 7791802d9b43c2067b566bf81667096ed91decb8 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Tue, 21 May 2013 11:46:35 -0700 Subject: don't generate the jd_lists.js file for search suggestions unless there are actual files to process Change-Id: I3b40afb151885bdb6c0e235be0fe4f76370598f8 --- src/com/google/doclava/Doclava.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index d916161..3bcc689 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -845,17 +845,19 @@ public class Doclava { ClearPage.write(data, "lists.cs", javadocDir + "lists.js"); - // Write the lists for JD documents - Data jddata = makeHDF(); - Iterator counter = new Iterator(); - for (String htmlDir : inputPathHtmlDirs) { - File dir = new File(htmlDir); - if (!dir.isDirectory()) { - continue; + // Write the lists for JD documents (if there are HTML directories to process) + if (inputPathHtmlDirs.size() > 0) { + Data jddata = makeHDF(); + Iterator counter = new Iterator(); + for (String htmlDir : inputPathHtmlDirs) { + File dir = new File(htmlDir); + if (!dir.isDirectory()) { + continue; + } + writeJdDirList(dir, jddata, counter); } - writeJdDirList(dir, jddata, counter); + ClearPage.write(jddata, "jd_lists.cs", javadocDir + "jd_lists.js"); } - ClearPage.write(jddata, "jd_lists.cs", javadocDir + "jd_lists.js"); } private static class Iterator { -- cgit v1.2.3