ICU-7395 update api tools

X-SVN-Rev: 27443
This commit is contained in:
Doug Felt 2010-01-29 19:43:53 +00:00
parent 744be6916f
commit 44f7023ffa
4 changed files with 154 additions and 72 deletions

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2004-2006, International Business Machines Corporation and *
* Copyright (C) 2004-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -19,7 +19,7 @@ public final class APIData {
int version;
String name;
String base;
TreeSet set;
TreeSet<APIInfo> set;
static APIData read(BufferedReader br, boolean internal) {
try {
@ -27,7 +27,9 @@ public final class APIData {
data.version = Integer.parseInt(APIInfo.readToken(br)); // version
if (data.version > APIInfo.VERSION) {
throw new IllegalArgumentException("data version " + data.version + " is newer than current version (" + APIInfo.VERSION + ")");
throw new IllegalArgumentException(
"data version " + data.version
+ " is newer than current version (" + APIInfo.VERSION + ")");
}
data.name = APIInfo.readToken(br);
data.base = APIInfo.readToken(br); // base
@ -83,8 +85,12 @@ public final class APIData {
return read(new File(fileName), internal);
}
private static final String[] stanames = { "draft", "stable", "deprecated", "obsolete", "internal" };
private static final String[] catnames = { "classes", "fields", "constructors", "methods" };
private static final String[] stanames = {
"draft", "stable", "deprecated", "obsolete", "internal"
};
private static final String[] catnames = {
"classes", "fields", "constructors", "methods"
};
public void printStats(PrintWriter pw) {
// classes, methods, fields

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2005-2007, International Business Machines Corporation and *
* Copyright (C) 2005-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -21,13 +21,16 @@ class APIInfo {
// public keys and values for queries on info
public static final int STA = 0, STA_DRAFT = 0, STA_STABLE = 1, STA_DEPRECATED = 2, STA_OBSOLETE = 3, STA_INTERNAL = 4;
public static final int VIS = 1, VIS_PACKAGE = 0, VIS_PUBLIC= 1, VIS_PROTECTED = 2, VIS_PRIVATE = 3;
public static final int STA = 0, STA_DRAFT = 0, STA_STABLE = 1, STA_DEPRECATED = 2,
STA_OBSOLETE = 3, STA_INTERNAL = 4;
public static final int VIS = 1, VIS_PACKAGE = 0, VIS_PUBLIC= 1, VIS_PROTECTED = 2,
VIS_PRIVATE = 3;
public static final int STK = 2, STK_STATIC = 1;
public static final int FIN = 3, FIN_FINAL = 1;
public static final int SYN = 4, SYN_SYNCHRONIZED = 1;
public static final int ABS = 5, ABS_ABSTRACT = 1;
public static final int CAT = 6, CAT_CLASS = 0, CAT_FIELD = 1, CAT_CONSTRUCTOR = 2, CAT_METHOD = 3;
public static final int CAT = 6, CAT_CLASS = 0, CAT_FIELD = 1, CAT_CONSTRUCTOR = 2,
CAT_METHOD = 3;
public static final int PAK = 7;
public static final int CLS = 8;
public static final int NAM = 9;
@ -42,11 +45,14 @@ class APIInfo {
public static final char SEP = ';';
// Internal State
private int info; // information about numeric values packed into an int as variable-length nibbles
private String pack = ""; // package
private int info; // information about numeric values packed into an int
// as variable-length nibbles
private String pack = ""; // package
private String cls = ""; // enclosing class
private String name = ""; // name
private String sig = ""; // signature, class: inheritance, method: signature, field: type, const: signature
private String name = ""; // name
private String sig = ""; // signature, class: inheritance, method: signature,
// field: type, const: signature
private String exc = ""; // throws
private String stver = ""; // status version
@ -205,7 +211,8 @@ class APIInfo {
}
}
throw new IllegalArgumentException("unrecognized value '" + val + "' for type '" + typeNames[typ] + "'");
throw new IllegalArgumentException(
"unrecognized value '" + val + "' for type '" + typeNames[typ] + "'");
}
/**
@ -374,7 +381,8 @@ class APIInfo {
boolean rcls = rhi.getVal(CAT) == CAT_CLASS;
result = lcls == rcls ? 0 : (lcls ? -1 : 1);
if (result == 0) {
result = (lcls ? lhi.name : lhi.cls).compareTo(rcls ? rhi.name : rhi.cls);
result = (lcls ? lhi.name : lhi.cls).compareTo(
rcls ? rhi.name : rhi.cls);
if (result == 0) {
result = lhi.getVal(CAT)- rhi.getVal(CAT);
if (result == 0) {

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2004-2008, International Business Machines Corporation and *
* Copyright (C) 2004-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -18,16 +18,16 @@
* - constructor, member, field (C M F)
*
* Requires JDK 1.4.2 or later
*
*
* Sample compilation:
* c:/doug/java/jdk1.4.2/build/windows-i586/bin/javac *.java
*
* Sample execution
* c:/j2sdk1.4.2/bin/javadoc
* -classpath c:/jd2sk1.4.2/lib/tools.jar
* -classpath c:/jd2sk1.4.2/lib/tools.jar
* -doclet com.ibm.icu.dev.tool.docs.GatherAPIData
* -docletpath c:/doug/cvsproj/icu4j/src
* -sourcepath c:/doug/cvsproj/icu4j/src
* -docletpath c:/doug/cvsproj/icu4j/src
* -sourcepath c:/doug/cvsproj/icu4j/src
* -name "ICU4J 3.0"
* -output icu4j30.api
* -gzip
@ -35,8 +35,8 @@
* com.ibm.icu.lang com.ibm.icu.math com.ibm.icu.text com.ibm.icu.util
*
* todo: provide command-line control of filters of which subclasses/packages to process
* todo: record full inheritance heirarchy, not just immediate inheritance
* todo: allow for aliasing comparisons (force (pkg.)*class to be treated as though it
* todo: record full inheritance heirarchy, not just immediate inheritance
* todo: allow for aliasing comparisons (force (pkg.)*class to be treated as though it
* were in a different pkg/class heirarchy (facilitates comparison of icu4j and java)
*/
@ -177,7 +177,9 @@ public class GatherAPIData {
doDocs(cdoc.fields());
doDocs(cdoc.constructors());
doDocs(cdoc.methods());
doDocs(cdoc.innerClasses());
// don't call this to iterate over inner classes,
// root.classes already includes them
// doDocs(cdoc.innerClasses());
}
APIInfo info = createInfo(doc);
@ -186,13 +188,73 @@ public class GatherAPIData {
}
}
// Sigh. Javadoc's isEnum/isOrdinaryClass apis don't seem to work.
// For now, manually list enum methods to ignore.
// list of enum classes to ignore
private static final String[] ignoredEnumApis = {
"com.ibm.icu.text.UnicodeSet.ComparisonStyle.values",
"com.ibm.icu.text.UnicodeSet.ComparisonStyle.valueOf",
"com.ibm.icu.text.UnicodeSet.SpanCondition.values",
"com.ibm.icu.text.UnicodeSet.SpanCondition.valueOf",
"com.ibm.icu.text.UnicodeSet.SpanCondition.values",
"com.ibm.icu.text.UnicodeSet.SpanCondition.valueOf",
"com.ibm.icu.text.LocaleDisplayNames.DialectHandling.values",
"com.ibm.icu.text.LocaleDisplayNames.DialectHandling.valueOf",
};
private boolean isIgnoredEnumMethod(ProgramElementDoc doc) {
String qn = doc.qualifiedName();
for (String ignored: ignoredEnumApis) {
if (qn.equals(ignored)) {
return true;
}
}
return false;
}
// isSynthesized also doesn't seem to work. Let's do this, documenting
// synthesized constructors for abstract classes is kind of weird.
// We can't actually tell if the constructor was synthesized or is
// actually in the docs, but this shouldn't matter. We don't really
// care if we didn't properly document the draft status of
// default constructors for abstract classes.
private boolean isAbstractClassDefaultConstructor(ProgramElementDoc doc) {
return doc.isConstructor()
&& doc.containingClass().isAbstract()
&& "()".equals(((ConstructorDoc) doc).signature());
}
private boolean ignore(ProgramElementDoc doc) {
if (doc == null) return true;
if (doc.isPrivate() || doc.isPackagePrivate()) return true;
if (doc instanceof ConstructorDoc && ((ConstructorDoc)doc).isSynthetic()) return true;
if (doc.qualifiedName().indexOf(".misc") != -1) {
System.out.println("misc: " + doc.qualifiedName()); return true;
if (doc instanceof MemberDoc && ((MemberDoc)doc).isSynthetic()) return true;
if (doc.qualifiedName().indexOf(".misc") != -1) {
System.out.println("misc: " + doc.qualifiedName()); return true;
}
if (isIgnoredEnumMethod(doc)) {
return true;
}
if (isAbstractClassDefaultConstructor(doc)) {
return true;
}
if (false && doc.qualifiedName().indexOf("LocaleDisplayNames") != -1) {
System.err.print("*** " + doc.qualifiedName() + ":");
if (doc.isClass()) System.err.print(" class");
if (doc.isConstructor()) System.err.print(" constructor");
if (doc.isEnum()) System.err.print(" enum");
if (doc.isEnumConstant()) System.err.print(" enum_constant");
if (doc.isError()) System.err.print(" error");
if (doc.isException()) System.err.print(" exception");
if (doc.isField()) System.err.print(" field");
if (doc.isInterface()) System.err.print(" interface");
if (doc.isMethod()) System.err.print(" method");
if (doc.isOrdinaryClass()) System.err.print(" ordinary_class");
System.err.println();
}
if (!internal) { // debug
Tag[] tags = doc.tags();
for (int i = 0; i < tags.length; ++i) {
@ -243,7 +305,7 @@ public class GatherAPIData {
if (version) {
info.includeStatusVersion(true);
}
// status
String[] version = new String[1];
info.setType(APIInfo.STA, tagStatus(doc, version));
@ -286,8 +348,8 @@ public class GatherAPIData {
}
info.setPackage(trimBase(doc.containingPackage().name()));
info.setClassName((doc.isClass() || doc.isInterface() || (doc.containingClass() == null))
? ""
info.setClassName((doc.isClass() || doc.isInterface() || (doc.containingClass() == null))
? ""
: trimBase(doc.containingClass().name()));
info.setName(trimBase(doc.name()));
@ -297,7 +359,7 @@ public class GatherAPIData {
} else if (doc instanceof ClassDoc) {
ClassDoc cdoc = (ClassDoc)doc;
if (cdoc.isClass() && cdoc.isAbstract()) {
if (cdoc.isClass() && cdoc.isAbstract()) {
// interfaces are abstract by default, don't mark them as abstract
info.setAbstract();
}
@ -343,17 +405,19 @@ public class GatherAPIData {
return info;
}
private int tagStatus(final Doc doc, String[] version) {
private int tagStatus(final ProgramElementDoc doc, String[] version) {
class Result {
int res = -1;
void set(int val) {
void set(int val) {
if (res != -1) {
if (val == APIInfo.STA_DEPRECATED) {
// ok to have both a 'standard' tag and deprecated
return;
} else if (res != APIInfo.STA_DEPRECATED) {
// if already not deprecated, this is an error
System.err.println("bad doc: " + doc + " both: " + APIInfo.getTypeValName(APIInfo.STA, res) + " and: " + APIInfo.getTypeValName(APIInfo.STA, val));
System.err.println("bad doc: " + doc + " both: "
+ APIInfo.getTypeValName(APIInfo.STA, res) + " and: "
+ APIInfo.getTypeValName(APIInfo.STA, val));
return;
}
}
@ -468,8 +532,8 @@ public class GatherAPIData {
private static int tagKindIndex(String kind) {
final String[] tagKinds = {
"@internal", "@draft", "@stable", "@since", "@deprecated", "@author", "@see", "@version",
"@param", "@return", "@throws", "@obsolete", "@exception", "@serial"
"@internal", "@draft", "@stable", "@since", "@deprecated", "@author", "@see",
"@version", "@param", "@return", "@throws", "@obsolete", "@exception", "@serial"
};
for (int i = 0; i < tagKinds.length; ++i) {

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2004-2007, International Business Machines Corporation and *
* Copyright (C) 2004-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -32,11 +32,11 @@ public class ReportAPI {
boolean html;
String outputFile;
TreeSet added;
TreeSet removed;
TreeSet promoted;
TreeSet obsoleted;
ArrayList changed;
TreeSet<APIInfo> added;
TreeSet<APIInfo> removed;
TreeSet<APIInfo> promoted;
TreeSet<APIInfo> obsoleted;
ArrayList<DeltaInfo> changed;
static final class DeltaInfo extends APIInfo {
APIInfo added;
@ -118,25 +118,25 @@ public class ReportAPI {
this.oldData = oldData;
this.newData = newData;
removed = (TreeSet)oldData.set.clone();
removed = (TreeSet<APIInfo>)oldData.set.clone();
removed.removeAll(newData.set);
added = (TreeSet)newData.set.clone();
added = (TreeSet<APIInfo>)newData.set.clone();
added.removeAll(oldData.set);
changed = new ArrayList();
Iterator ai = added.iterator();
Iterator ri = removed.iterator();
Comparator c = APIInfo.changedComparator();
changed = new ArrayList<DeltaInfo>();
Iterator<APIInfo> ai = added.iterator();
Iterator<APIInfo> ri = removed.iterator();
Comparator<APIInfo> c = APIInfo.changedComparator();
ArrayList ams = new ArrayList();
ArrayList rms = new ArrayList();
ArrayList<APIInfo> ams = new ArrayList<APIInfo>();
ArrayList<APIInfo> rms = new ArrayList<APIInfo>();
//PrintWriter outpw = new PrintWriter(System.out);
APIInfo a = null, r = null;
while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
if (a == null) a = (APIInfo)ai.next();
if (r == null) r = (APIInfo)ri.next();
if (a == null) a = ai.next();
if (r == null) r = ri.next();
String am = a.getClassName() + "." + a.getName();
String rm = r.getClassName() + "." + r.getName();
@ -150,7 +150,7 @@ public class ReportAPI {
if (!ams.isEmpty()) {
// simplest case first
if (ams.size() == 1 && rms.size() == 1) {
changed.add(new DeltaInfo((APIInfo)ams.get(0), (APIInfo)rms.get(0)));
changed.add(new DeltaInfo(ams.get(0), rms.get(0)));
} else {
// dang, what to do now?
// TODO: modify deltainfo to deal with lists of added and removed
@ -172,33 +172,33 @@ public class ReportAPI {
}
// now clean up added and removed by cleaning out the changed members
Iterator ci = changed.iterator();
Iterator<DeltaInfo> ci = changed.iterator();
while (ci.hasNext()) {
DeltaInfo di = (DeltaInfo)ci.next();
DeltaInfo di = ci.next();
added.remove(di.added);
removed.remove(di.removed);
}
Set tempAdded = new HashSet();
Set<APIInfo> tempAdded = new HashSet<APIInfo>();
tempAdded.addAll(newData.set);
tempAdded.removeAll(removed);
TreeSet changedAdded = new TreeSet(APIInfo.defaultComparator());
TreeSet<APIInfo> changedAdded = new TreeSet<APIInfo>(APIInfo.defaultComparator());
changedAdded.addAll(tempAdded);
Set tempRemoved = new HashSet();
Set<APIInfo> tempRemoved = new HashSet<APIInfo>();
tempRemoved.addAll(oldData.set);
tempRemoved.removeAll(added);
TreeSet changedRemoved = new TreeSet(APIInfo.defaultComparator());
TreeSet<APIInfo> changedRemoved = new TreeSet<APIInfo>(APIInfo.defaultComparator());
changedRemoved.addAll(tempRemoved);
promoted = new TreeSet(APIInfo.defaultComparator());
obsoleted = new TreeSet(APIInfo.defaultComparator());
promoted = new TreeSet<APIInfo>(APIInfo.defaultComparator());
obsoleted = new TreeSet<APIInfo>(APIInfo.defaultComparator());
ai = changedAdded.iterator();
ri = changedRemoved.iterator();
a = r = null;
while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
if (a == null) a = (APIInfo)ai.next();
if (r == null) r = (APIInfo)ri.next();
if (a == null) a = ai.next();
if (r == null) r = ri.next();
int result = c.compare(a, r);
if (result < 0) {
a = null;
@ -229,7 +229,9 @@ public class ReportAPI {
}
}
int lstatus = lhs.getVal(APIInfo.STA);
if (lstatus == APIInfo.STA_OBSOLETE || lstatus == APIInfo.STA_DEPRECATED || lstatus == APIInfo.STA_INTERNAL) {
if (lstatus == APIInfo.STA_OBSOLETE
|| lstatus == APIInfo.STA_DEPRECATED
|| lstatus == APIInfo.STA_INTERNAL) {
return -1;
}
return 1;
@ -260,7 +262,8 @@ public class ReportAPI {
String year = fmt.format(new Date());
String title = "ICU4J API Comparison: " + oldData.name + " with " + newData.name;
String info = "Contents generated by ReportAPI tool on " + new Date().toString();
String copyright = "Copyright (C) " + year + ", International Business Machines Corporation, All Rights Reserved.";
String copyright = "Copyright (C) " + year +
", International Business Machines Corporation, All Rights Reserved.";
if (html) {
pw.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
@ -389,12 +392,13 @@ public class ReportAPI {
return false;
}
private static void printResults(Collection c, PrintWriter pw, boolean html, boolean isChangedAPIs) {
Iterator iter = c.iterator();
private static void printResults(Collection<? extends APIInfo> c, PrintWriter pw, boolean html,
boolean isChangedAPIs) {
Iterator<? extends APIInfo> iter = c.iterator();
String pack = null;
String clas = null;
while (iter.hasNext()) {
APIInfo info = (APIInfo)iter.next();
APIInfo info = iter.next();
String packageName = info.getPackageName();
if (!packageName.equals(pack)) {
@ -457,19 +461,19 @@ public class ReportAPI {
pw.println();
}
private static TreeSet stripAndResort(TreeSet t) {
private static TreeSet<APIInfo> stripAndResort(TreeSet<APIInfo> t) {
stripClassInfo(t);
TreeSet r = new TreeSet(APIInfo.classFirstComparator());
TreeSet<APIInfo> r = new TreeSet<APIInfo>(APIInfo.classFirstComparator());
r.addAll(t);
return r;
}
private static void stripClassInfo(Collection c) {
private static void stripClassInfo(Collection<APIInfo> c) {
// c is sorted with class info first
Iterator iter = c.iterator();
Iterator<? extends APIInfo> iter = c.iterator();
String cname = null;
while (iter.hasNext()) {
APIInfo info = (APIInfo)iter.next();
APIInfo info = iter.next();
String className = info.getClassName();
if (cname != null) {
if (cname.equals(className)) {