Fixed droiddoc to properly version varargs and type-parameter methods.

This also removes many false-positive warnings in the droiddoc output
from methods whose visibility didn't require documentation.
This commit is contained in:
Jesse Wilson
2009-08-11 16:36:42 -07:00
parent 0c72ede79e
commit 90c1d538f9
2 changed files with 73 additions and 22 deletions

View File

@@ -363,8 +363,17 @@ public class MethodInfo extends MemberInfo
public String getHashableName() { public String getHashableName() {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
result.append(name()); result.append(name());
for (ParameterInfo pInfo : mParameters) { for (int p = 0; p < mParameters.length; p++) {
result.append(":").append(pInfo.type().fullName()); result.append(":");
if (p == mParameters.length - 1 && isVarArgs()) {
// TODO: note that this does not attempt to handle hypothetical
// vararg methods whose last parameter is a list of arrays, e.g.
// "Object[]...".
result.append(mParameters[p].type().fullNameNoDimension(typeVariables()))
.append("...");
} else {
result.append(mParameters[p].type().fullName(typeVariables()));
}
} }
return result.toString(); return result.toString();
} }

View File

@@ -1,8 +1,13 @@
// Copyright 2009 Google Inc. All Rights Reserved. // Copyright 2009 Google Inc. All Rights Reserved.
import com.android.apicheck.*; import com.android.apicheck.ApiCheck;
import com.android.apicheck.ApiInfo;
import java.util.*; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Collections;
import org.clearsilver.HDF; import org.clearsilver.HDF;
@@ -165,31 +170,68 @@ public class SinceTagger {
*/ */
private void warnForMissingVersions(ClassInfo[] classDocs) { private void warnForMissingVersions(ClassInfo[] classDocs) {
for (ClassInfo claz : classDocs) { for (ClassInfo claz : classDocs) {
if (!checkLevelRecursive(claz)) {
continue;
}
if (claz.getSince() == null) { if (claz.getSince() == null) {
Errors.error(Errors.NO_SINCE_DATA, claz.position(), Errors.error(Errors.NO_SINCE_DATA, claz.position(),
"XML missing class " + claz.qualifiedName()); "XML missing class " + claz.qualifiedName());
} }
for (FieldInfo field : claz.fields()) {
if (field.getSince() == null) { for (FieldInfo field : missingVersions(claz.fields())) {
Errors.error(Errors.NO_SINCE_DATA, field.position(), Errors.error(Errors.NO_SINCE_DATA, field.position(),
"XML missing field " "XML missing field " + claz.qualifiedName()
+ claz.qualifiedName() + "#" + field .name()); + "#" + field.name());
}
} }
for (MethodInfo constructor : claz.constructors()) {
if (constructor.getSince() == null) { for (MethodInfo constructor : missingVersions(claz.constructors())) {
Errors.error(Errors.NO_SINCE_DATA, constructor.position(), Errors.error(Errors.NO_SINCE_DATA, constructor.position(),
"XML missing constructor " "XML missing constructor " + claz.qualifiedName()
+ claz.qualifiedName() + "#" + constructor.getHashableName()); + "#" + constructor.getHashableName());
}
} }
for (MethodInfo method : claz.methods()) {
if (method.getSince() == null) { for (MethodInfo method : missingVersions(claz.methods())) {
Errors.error(Errors.NO_SINCE_DATA, method.position(), Errors.error(Errors.NO_SINCE_DATA, method.position(),
"XML missing method " "XML missing method " + claz.qualifiedName()
+ claz.qualifiedName() + "#" + method .getHashableName()); + "#" + method.getHashableName());
}
} }
} }
} }
/**
* Returns the DocInfos in {@code all} that are documented but do not have
* since tags.
*/
private <T extends MemberInfo> Iterable<T> missingVersions(T[] all) {
List<T> result = Collections.emptyList();
for (T t : all) {
// if this member has version info or isn't documented, skip it
if (t.getSince() != null
|| t.isHidden()
|| !checkLevelRecursive(t.realContainingClass())) {
continue;
}
if (result.isEmpty()) {
result = new ArrayList<T>(); // lazily construct a mutable list
}
result.add(t);
}
return result;
}
/**
* Returns true if {@code claz} and all containing classes are documented.
* The result may be used to filter out members that exist in the API
* data structure but aren't a part of the API.
*/
private boolean checkLevelRecursive(ClassInfo claz) {
for (ClassInfo c = claz; c != null; c = c.containingClass()) {
if (!c.checkLevel()) {
return false;
}
}
return true;
}
} }