Code drop from //branches/cupcake/...@124589
diff --git a/tools/droiddoc/src/Android.mk b/tools/droiddoc/src/Android.mk
index c0c583d..abd2581 100644
--- a/tools/droiddoc/src/Android.mk
+++ b/tools/droiddoc/src/Android.mk
@@ -39,6 +39,7 @@
LiteralTagInfo.java \
MemberInfo.java \
MethodInfo.java \
+ NavTree.java \
PackageInfo.java \
ParamTagInfo.java \
ParameterInfo.java \
diff --git a/tools/droiddoc/src/DocFile.java b/tools/droiddoc/src/DocFile.java
index 38ac55c..f53a35c 100644
--- a/tools/droiddoc/src/DocFile.java
+++ b/tools/droiddoc/src/DocFile.java
@@ -116,21 +116,21 @@
hdf.setValue("commentText", commentText);
- if(outfile.indexOf("sdk/") != -1) {
- hdf.setValue("sdk", "true");
- if(outfile.indexOf("index.html") != -1) {
- ClearPage.write(hdf, "sdkpage.cs", outfile);
- }else{
+ if (outfile.indexOf("sdk/") != -1) {
+ hdf.setValue("sdk", "true");
+ if (outfile.indexOf("index.html") != -1) {
+ ClearPage.write(hdf, "sdkpage.cs", outfile);
+ } else {
+ ClearPage.write(hdf, "docpage.cs", outfile);
+ }
+ } else if (outfile.indexOf("guide/") != -1){
+ hdf.setValue("guide", "true");
ClearPage.write(hdf, "docpage.cs", outfile);
- }
- }else if(outfile.indexOf("guide/") != -1){
- hdf.setValue("guide", "true");
- ClearPage.write(hdf, "docpage.cs", outfile);
- }else if(outfile.indexOf("publish/") != -1){
- hdf.setValue("publish", "true");
- ClearPage.write(hdf, "docpage.cs", outfile);
- }else{
- ClearPage.write(hdf, "nosidenavpage.cs", outfile);
+ } else if (outfile.indexOf("publish/") != -1){
+ hdf.setValue("publish", "true");
+ ClearPage.write(hdf, "docpage.cs", outfile);
+ } else {
+ ClearPage.write(hdf, "nosidenavpage.cs", outfile);
}
}
diff --git a/tools/droiddoc/src/DroidDoc.java b/tools/droiddoc/src/DroidDoc.java
index b0412c9..23ff654 100644
--- a/tools/droiddoc/src/DroidDoc.java
+++ b/tools/droiddoc/src/DroidDoc.java
@@ -209,6 +209,9 @@
writeHTMLPages();
}
+ // Navigation tree
+ NavTree.writeNavTree(javadocDir);
+
// Packages Pages
writePackages(javadocDir
+ (ClearPage.htmlDir!=null
@@ -475,7 +478,7 @@
classesToCheck = pkg.interfaces();
break;
default:
- System.out.println("Error reading package: " + pkg.name());
+ System.err.println("Error reading package: " + pkg.name());
break;
}
for (ClassInfo cl : classesToCheck) {
@@ -516,24 +519,17 @@
if (len > 3 && ".cs".equals(templ.substring(len-3))) {
HDF data = makeHDF();
String filename = templ.substring(0,len-3) + htmlExtension;
- System.out.println("Writing CS: " + filename);
ClearPage.write(data, templ, filename);
}
else if (len > 3 && ".jd".equals(templ.substring(len-3))) {
String filename = templ.substring(0,len-3) + htmlExtension;
- System.out.println("Writing JD: " + filename);
DocFile.writePage(f.getAbsolutePath(), relative, filename);
}
else {
-// System.out.println("relative=" + relative
-// + " f.getAbsolutePath()=" + f.getAbsolutePath()
-// + " templ=" + templ);
- System.out.println("Copying: " + templ);
ClearPage.copyFile(f, templ);
}
}
else if (f.isDirectory()) {
- System.out.println("Writing dir: " + relative + f.getName() + "/");
writeDirectory(f, relative + f.getName() + "/");
}
}
@@ -543,7 +539,7 @@
{
File f = new File(ClearPage.htmlDir);
if (!f.isDirectory()) {
- System.out.println("htmlDir not a directory: " + ClearPage.htmlDir);
+ System.err.println("htmlDir not a directory: " + ClearPage.htmlDir);
}
writeDirectory(f, "");
}
@@ -644,7 +640,7 @@
}
}
catch (FileNotFoundException e) {
- System.out.println("error writing file: " + filename);
+ System.err.println("error writing file: " + filename);
}
finally {
if (stream != null) {
@@ -653,13 +649,13 @@
}
}
- public static void writePackages(String filename)
- {
- System.out.println("Writing packages...");
- HDF data = makePackageHDF();
+ private static PackageInfo[] sVisiblePackages = null;
+ public static PackageInfo[] choosePackages() {
+ if (sVisiblePackages != null) {
+ return sVisiblePackages;
+ }
ClassInfo[] classes = Converter.rootClasses();
-
SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
for (ClassInfo cl: classes) {
PackageInfo pkg = cl.containingPackage();
@@ -672,7 +668,8 @@
sorted.put(name, pkg);
}
- int i = 0;
+ ArrayList<PackageInfo> result = new ArrayList();
+
for (String s: sorted.keySet()) {
PackageInfo pkg = sorted.get(s);
@@ -680,10 +677,13 @@
continue;
}
Boolean allHidden = true;
- int pass = 1;
- ClassInfo[] classesToCheck = pkg.ordinaryClasses();
+ int pass = 0;
+ ClassInfo[] classesToCheck = null;
while (pass < 5 ) {
switch(pass) {
+ case 0:
+ classesToCheck = pkg.ordinaryClasses();
+ break;
case 1:
classesToCheck = pkg.enums();
break;
@@ -697,7 +697,7 @@
classesToCheck = pkg.interfaces();
break;
default:
- System.out.println("Error reading package: " + pkg.name());
+ System.err.println("Error reading package: " + pkg.name());
break;
}
for (ClassInfo cl : classesToCheck) {
@@ -715,8 +715,26 @@
continue;
}
+ result.add(pkg);
+ }
+
+ sVisiblePackages = result.toArray(new PackageInfo[result.size()]);
+ return sVisiblePackages;
+ }
+
+ public static void writePackages(String filename)
+ {
+ HDF data = makePackageHDF();
+
+ int i = 0;
+ for (PackageInfo pkg: choosePackages()) {
writePackage(pkg);
+ data.setValue("docs.packages." + i + ".name", pkg.name());
+ data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
+ TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr",
+ pkg.firstSentenceTags());
+
i++;
}
@@ -739,7 +757,6 @@
HDF data = makePackageHDF();
String name = pkg.name();
- System.out.println("Writing " + name);
data.setValue("package.name", name);
data.setValue("package.descr", "...description...");
@@ -762,8 +779,7 @@
setPageTitle(data, name);
ClearPage.write(data, "package.cs", filename);
- filename = filename.substring(0, filename.lastIndexOf('/')+1)
- + "package-descr" + htmlExtension;
+ filename = pkg.fullDescriptionHtmlPage();
setPageTitle(data, name + " Details");
ClearPage.write(data, "package-descr.cs", filename);
@@ -804,8 +820,6 @@
sorted[j].label = sorted[j].label + " (" + pkg.name() + ")";
}
}
- } else {
- //System.out.println("not duplicate: " + sorted[i].label);
}
firstMatch = i;
lastName = s;
@@ -838,7 +852,7 @@
cl.makeKeywordEntries(keywords);
}
- HDF data = makePackageHDF();
+ HDF data = makeHDF();
Collections.sort(keywords);
@@ -884,7 +898,6 @@
{
cl.makeHDF(data);
- System.out.println("Writing " + cl.name());
setPageTitle(data, cl.name());
ClearPage.write(data, "class.cs", cl.htmlPage());
diff --git a/tools/droiddoc/src/LinkReference.java b/tools/droiddoc/src/LinkReference.java
index fa821cf..bbcd4db 100644
--- a/tools/droiddoc/src/LinkReference.java
+++ b/tools/droiddoc/src/LinkReference.java
@@ -376,7 +376,8 @@
if (result.href == null && !skipHref) {
if (printOnErrors && (base == null || base.checkLevel())) {
Errors.error(Errors.UNRESOLVED_LINK, pos,
- "Unresolved link/see tag: " + text.trim());
+ "Unresolved link/see tag \"" + text.trim()
+ + "\" in " + ((base != null) ? base.qualifiedName() : "[null]"));
}
result.makeError();
}
diff --git a/tools/droiddoc/src/MethodInfo.java b/tools/droiddoc/src/MethodInfo.java
index ed98378..ca30665 100644
--- a/tools/droiddoc/src/MethodInfo.java
+++ b/tools/droiddoc/src/MethodInfo.java
@@ -266,9 +266,12 @@
ClassInfo[] thrownExceptions, SourcePositionInfo position,
AnnotationInstanceInfo[] annotations)
{
+ // Explicitly coerce 'final' state of Java6-compiled enum values() method, to match
+ // the Java5-emitted base API description.
super(rawCommentText, name, signature, containingClass, realContainingClass,
isPublic, isProtected, isPackagePrivate, isPrivate,
- isFinal, isStatic, isSynthetic, kind, position, annotations);
+ ((name.equals("values") && containingClass.isEnum()) ? true : isFinal),
+ isStatic, isSynthetic, kind, position, annotations);
// The underlying MethodDoc for an interface's declared methods winds up being marked
// non-abstract. Correct that here by looking at the immediate-parent class, and marking
diff --git a/tools/droiddoc/src/NavTree.java b/tools/droiddoc/src/NavTree.java
new file mode 100644
index 0000000..9eef0ce
--- /dev/null
+++ b/tools/droiddoc/src/NavTree.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.clearsilver.HDF;
+
+import java.util.ArrayList;
+
+public class NavTree {
+
+ public static void writeNavTree(String dir) {
+ ArrayList<Node> children = new ArrayList();
+ for (PackageInfo pkg: DroidDoc.choosePackages()) {
+ children.add(makePackageNode(pkg));
+ }
+ Node node = new Node("Reference", dir + "packages.html", children);
+
+ StringBuilder buf = new StringBuilder();
+ if (false) {
+ // if you want a root node
+ buf.append("[");
+ node.render(buf);
+ buf.append("]");
+ } else {
+ // if you don't want a root node
+ node.renderChildren(buf);
+ }
+
+ HDF data = DroidDoc.makeHDF();
+ data.setValue("reference_tree", buf.toString());
+ ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
+ }
+
+ private static Node makePackageNode(PackageInfo pkg) {
+ ArrayList<Node> children = new ArrayList();
+
+ children.add(new Node("Description", pkg.fullDescriptionHtmlPage(), null));
+
+ addClassNodes(children, "Interfaces", pkg.interfaces());
+ addClassNodes(children, "Classes", pkg.ordinaryClasses());
+ addClassNodes(children, "Enums", pkg.enums());
+ addClassNodes(children, "Exceptions", pkg.exceptions());
+ addClassNodes(children, "Errors", pkg.errors());
+
+ return new Node(pkg.name(), pkg.htmlPage(), children);
+ }
+
+ private static void addClassNodes(ArrayList<Node> parent, String label, ClassInfo[] classes) {
+ ArrayList<Node> children = new ArrayList();
+
+ for (ClassInfo cl: classes) {
+ if (cl.checkLevel()) {
+ children.add(new Node(cl.name(), cl.htmlPage(), null));
+ }
+ }
+
+ if (children.size() > 0) {
+ parent.add(new Node(label, null, children));
+ }
+ }
+
+ private static class Node {
+ private String mLabel;
+ private String mLink;
+ ArrayList<Node> mChildren;
+
+ Node(String label, String link, ArrayList<Node> children) {
+ mLabel = label;
+ mLink = link;
+ mChildren = children;
+ }
+
+ static void renderString(StringBuilder buf, String s) {
+ if (s == null) {
+ buf.append("null");
+ } else {
+ buf.append('"');
+ final int N = s.length();
+ for (int i=0; i<N; i++) {
+ char c = s.charAt(i);
+ if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
+ buf.append(c);
+ } else {
+ buf.append("\\u");
+ for (int j=0; i<4; i++) {
+ char x = (char)(c & 0x000f);
+ if (x > 10) {
+ x = (char)(x - 10 + 'a');
+ } else {
+ x = (char)(x + '0');
+ }
+ buf.append(x);
+ c >>= 4;
+ }
+ }
+ }
+ buf.append('"');
+ }
+ }
+
+ void renderChildren(StringBuilder buf) {
+ ArrayList<Node> list = mChildren;
+ if (list == null || list.size() == 0) {
+ // We output null for no children. That way empty lists here can just
+ // be a byproduct of how we generate the lists.
+ buf.append("null");
+ } else {
+ buf.append("[ ");
+ final int N = list.size();
+ for (int i=0; i<N; i++) {
+ list.get(i).render(buf);
+ if (i != N-1) {
+ buf.append(", ");
+ }
+ }
+ buf.append(" ]\n");
+ }
+ }
+
+ void render(StringBuilder buf) {
+ buf.append("[ ");
+ renderString(buf, mLabel);
+ buf.append(", ");
+ renderString(buf, mLink);
+ buf.append(", ");
+ renderChildren(buf);
+ buf.append(" ]");
+ }
+ }
+}
diff --git a/tools/droiddoc/src/PackageInfo.java b/tools/droiddoc/src/PackageInfo.java
index c696112..09b73d4 100644
--- a/tools/droiddoc/src/PackageInfo.java
+++ b/tools/droiddoc/src/PackageInfo.java
@@ -49,11 +49,10 @@
return s;
}
- public String htmlLinksPage()
- {
+ public String fullDescriptionHtmlPage() {
String s = mName;
s = s.replace('.', '/');
- s += "/package-links.html";
+ s += "/package-descr.html";
s = DroidDoc.javadocDir + s;
return s;
}
diff --git a/tools/droiddoc/src/Stubs.java b/tools/droiddoc/src/Stubs.java
index a233d68..806498b 100644
--- a/tools/droiddoc/src/Stubs.java
+++ b/tools/droiddoc/src/Stubs.java
@@ -83,8 +83,9 @@
if (!t.isPrimitive()) {
if (t.asClassInfo().isHidden()) {
Errors.error(Errors.UNAVAILABLE_SYMBOL,
- p.position(), "Reference to unavailable class "
- + t.fullName());
+ m.position(), "Parameter of hidden type "
+ + t.fullName() + " in "
+ + cl.qualifiedName() + "." + m.name() + "()");
}
}
}
@@ -255,10 +256,19 @@
if (pInfo.type().typeArguments() != null){
for (TypeInfo tInfoType : pInfo.type().typeArguments()){
if (tInfoType.asClassInfo() != null){
- cantStripThis(tInfoType.asClassInfo(), notStrippable,
- "10:" +
- mInfo.realContainingClass().qualifiedName() + ":" +
- mInfo.name());
+ ClassInfo tcl = tInfoType.asClassInfo();
+ if (tcl.isHidden()) {
+ Errors.error(Errors.UNAVAILABLE_SYMBOL, mInfo.position(),
+ "Parameter of hidden type "
+ + tInfoType.fullName() + " in "
+ + mInfo.containingClass().qualifiedName()
+ + '.' + mInfo.name() + "()");
+ } else {
+ cantStripThis(tcl, notStrippable,
+ "10:" +
+ mInfo.realContainingClass().qualifiedName() + ":" +
+ mInfo.name());
+ }
}
}
}
@@ -552,14 +562,8 @@
int count = 1;
int size = method.parameters().length;
for (ParameterInfo param: method.parameters()) {
- String fullTypeName = param.type().fullName(method.typeVariables());
- if (count == size && method.isVarArgs()) {
- // TODO: note that this does not attempt to handle hypothetical
- // vararg methods whose last parameter is a list of arrays, e.g.
- // "Object[]...".
- fullTypeName = param.type().qualifiedTypeName() + "...";
- }
- stream.print(comma + fullTypeName + " " + param.name());
+ stream.print(comma + fullParameterTypeName(method, param.type(), count == size)
+ + " " + param.name());
comma = ", ";
count++;
}
@@ -852,6 +856,7 @@
static void writeMethodXML(PrintStream xmlWriter, MethodInfo mi) {
String scope = DroidDoc.scope(mi);
+
String deprecatedString = "";
if (mi.isDeprecated()) {
deprecatedString = "deprecated";
@@ -860,7 +865,7 @@
}
xmlWriter.println("<method name=\"" + mi.name() + "\"\n"
+ ((mi.returnType() != null)
- ? " return=\"" + mi.returnType().qualifiedTypeName() + "\"\n"
+ ? " return=\"" + makeXMLcompliant(fullParameterTypeName(mi, mi.returnType(), false)) + "\"\n"
: "")
+ " abstract=\"" + mi.isAbstract() + "\"\n"
+ " native=\"" + mi.isNative() + "\"\n"
@@ -873,8 +878,11 @@
+ ">");
// write parameters in declaration order
+ int numParameters = mi.parameters().length;
+ int count = 0;
for (ParameterInfo pi : mi.parameters()) {
- writeParameterXML(xmlWriter, pi);
+ count++;
+ writeParameterXML(xmlWriter, mi, pi, count == numParameters);
}
// but write exceptions in canonicalized order
@@ -905,6 +913,13 @@
//+ " source=\"" + mi.position() + "\"\n"
+ ">");
+ int numParameters = mi.parameters().length;
+ int count = 0;
+ for (ParameterInfo pi : mi.parameters()) {
+ count++;
+ writeParameterXML(xmlWriter, mi, pi, count == numParameters);
+ }
+
ClassInfo[] exceptions = mi.thrownExceptions();
Arrays.sort(exceptions, ClassInfo.comparator);
for (ClassInfo pi : exceptions) {
@@ -915,9 +930,10 @@
xmlWriter.println("</constructor>");
}
- static void writeParameterXML(PrintStream xmlWriter, ParameterInfo pi) {
+ static void writeParameterXML(PrintStream xmlWriter, MethodInfo method,
+ ParameterInfo pi, boolean isLast) {
xmlWriter.println("<parameter name=\"" + pi.name() + "\" type=\"" +
- pi.type().qualifiedTypeName() + "\">");
+ makeXMLcompliant(fullParameterTypeName(method, pi.type(), isLast)) + "\">");
xmlWriter.println("</parameter>");
}
@@ -931,8 +947,12 @@
}
//need to make sure value is valid XML
String value = makeXMLcompliant(fi.constantLiteralValue());
+
+ String fullTypeName = makeXMLcompliant(fi.type().qualifiedTypeName())
+ + fi.type().dimension();
+
xmlWriter.println("<field name=\"" + fi.name() +"\"\n"
- + " type=\"" + fi.type().qualifiedTypeName() + "\"\n"
+ + " type=\"" + fullTypeName + "\"\n"
+ " transient=\"" + fi.isTransient() + "\"\n"
+ " volatile=\"" + fi.isVolatile() + "\"\n"
+ (fieldIsInitialized(fi) ? " value=\"" + value + "\"\n" : "")
@@ -954,5 +974,16 @@
returnString = returnString.replaceAll("'", "&pos;");
return returnString;
}
+
+ static String fullParameterTypeName(MethodInfo method, TypeInfo type, boolean isLast) {
+ String fullTypeName = type.fullName(method.typeVariables());
+ if (isLast && method.isVarArgs()) {
+ // TODO: note that this does not attempt to handle hypothetical
+ // vararg methods whose last parameter is a list of arrays, e.g.
+ // "Object[]...".
+ fullTypeName = type.qualifiedTypeName() + "...";
+ }
+ return fullTypeName;
+ }
}