ICU-5362 gather and report information about internal APIs

X-SVN-Rev: 20221
This commit is contained in:
Doug Felt 2006-09-01 00:58:35 +00:00
parent 2c80376017
commit 054143f68f
6 changed files with 107 additions and 74 deletions

View File

@ -674,6 +674,7 @@
path="${build.dir}">
<param name="-name" value="ICU4J 3.6"/>
<param name="-output" value="${api.dir}/icu4j36.api"/>
<param name="-internal"/>
<param name="-gzip"/>
</doclet>
</javadoc>
@ -684,8 +685,9 @@
<arg value="-old:"/>
<arg value="${api.dir}/icu4j343.api.gz"/>
<arg value="-new:"/>
<arg value="${api.dir}/icu4j346.api.gz"/>
<arg value="${api.dir}/icu4j36.api.gz"/>
<arg value="-html"/>
<arg value="-internal"/>
<arg value="-out:"/>
<arg value="${api.dir}/icu4j_compare_343_36.html"/>
</java>

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2004-2005, International Business Machines Corporation and *
* Copyright (C) 2004-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -21,19 +21,25 @@ public final class APIData {
String base;
TreeSet set;
static APIData read(BufferedReader br) {
static APIData read(BufferedReader br, boolean internal) {
try {
APIData data = new 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 + ")");
}
data.name = APIInfo.readToken(br);
data.base = APIInfo.readToken(br); // base
br.readLine();
data.set = new TreeSet(APIInfo.defaultComparator());
for (APIInfo info = new APIInfo(); info.read(br); info = new APIInfo()) {
data.set.add(info);
if (internal || !info.isInternal()) {
data.set.add(info);
}
}
// System.out.println("read " + data.set.size() + " record(s)");
return data;
}
catch (IOException e) {
@ -43,7 +49,7 @@ public final class APIData {
}
}
static APIData read(File file) {
static APIData read(File file, boolean internal) {
String fileName = file.getName();
try {
InputStream is;
@ -64,7 +70,7 @@ public final class APIData {
}
}
InputStreamReader isr = new InputStreamReader(is);
return read(new BufferedReader(isr));
return read(new BufferedReader(isr), internal);
}
catch (IOException e) {
RuntimeException re = new RuntimeException("error getting info stream: " + fileName);
@ -73,18 +79,18 @@ public final class APIData {
}
}
static APIData read(String fileName) {
return read(new File(fileName));
static APIData read(String fileName, boolean internal) {
return read(new File(fileName), internal);
}
private static final String[] stanames = { "draft", "stable", "deprecated", "obsolete" };
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
// draft, stable, other
int[] stats = new int[16];
int[] stats = new int[catnames.length * stanames.length];
Iterator iter = set.iterator();
while (iter.hasNext()) {
@ -93,16 +99,16 @@ public final class APIData {
if (info.isPublic() || info.isProtected()) {
int sta = info.getVal(APIInfo.STA);
int cat = info.getVal(APIInfo.CAT);
stats[cat * 4 + sta] += 1;
stats[cat * stanames.length + sta] += 1;
}
}
int tt = 0;
for (int cat = 0; cat < 4; ++cat) {
for (int cat = 0; cat < catnames.length; ++cat) {
pw.println(catnames[cat]);
int t = 0;
for (int sta = 0; sta < 4; ++sta) {
int v = stats[cat * 4 + sta];
for (int sta = 0; sta < stanames.length; ++sta) {
int v = stats[cat * stanames.length + sta];
t += v;
pw.println(" " + stanames[sta] + ": " + v);
}
@ -116,20 +122,25 @@ public final class APIData {
public static void main(String[] args) {
PrintWriter pw = new PrintWriter(System.out);
boolean internal = false;
String path = "src/com/ibm/icu/dev/tool/docs/";
String fn = "icu4j341.api.gz";
if (args.length == 0) {
args = new String[] { "-file", fn };
}
for (int i = 0; i < args.length; ++i) {
String arg = args[i];
if (arg.equals("-path")) {
if (arg.equals("-path:")) {
path = args[++i];
} else if (arg.equals("-internal:")) {
internal = args[++i].toLowerCase().charAt(0) == 't';
} else if (arg.equals("-file")) {
fn = args[++i];
File f = new File(path, fn);
read(f).printStats(pw);
read(f,internal).printStats(pw);
pw.flush();
}
}

View File

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2005, International Business Machines Corporation and *
* Copyright (C) 2005-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -17,11 +17,11 @@ import java.util.*;
class APIInfo {
// version id for the format of the APIInfo data
public static final int VERSION = 1;
public static final int VERSION = 2;
// 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;
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;
@ -36,11 +36,13 @@ class APIInfo {
public static final int NUM_TYPES = 11;
// the separator between tokens in the data file
public int[] masks = { 0x7, 0x3, 0x1, 0x1, 0x1, 0x1, 0x3 };
public int[] shifts = { 0, 3, 5, 6, 7, 8, 9 };
public static final char SEP = ';';
// internal state
private int info; // information about numeric values packed into an int as 2-bit nibbles
// Internal State
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
@ -72,6 +74,7 @@ class APIInfo {
public void setStable() { setType(STA, STA_STABLE); }
public void setDeprecated() { setType(STA, STA_DEPRECATED); }
public void setObsolete() { setType(STA, STA_OBSOLETE); }
public void setInternal() { setType(STA, STA_INTERNAL); }
public void setPackage() { setType(VIS, VIS_PACKAGE); }
public void setPublic() { setType(VIS, VIS_PUBLIC); }
public void setProtected() { setType(VIS, VIS_PROTECTED); }
@ -95,6 +98,7 @@ class APIInfo {
public boolean isStable() { return getVal(STA) == STA_STABLE; }
public boolean isDeprecated() { return getVal(STA) == STA_DEPRECATED; }
public boolean isObsolete() { return getVal(STA) == STA_OBSOLETE; }
public boolean isInternal() { return getVal(STA) == STA_INTERNAL; }
public boolean isPackage() { return getVal(VIS) == VIS_PACKAGE; }
public boolean isPublic() { return getVal(VIS) == VIS_PUBLIC; }
public boolean isProtected() { return getVal(VIS) == VIS_PROTECTED; }
@ -121,7 +125,7 @@ class APIInfo {
*/
public int getVal(int typ) {
validateType(typ);
return (info >> (typ*2)) & 0x3;
return (info >>> shifts[typ]) & masks[typ];
}
/**
@ -143,7 +147,7 @@ class APIInfo {
case EXC: return exc;
}
}
int val = (info >> (typ*2)) & 0x3;
int val = (info >>> shifts[typ]) & masks[typ];
return vals[val];
}
@ -154,8 +158,8 @@ class APIInfo {
*/
public void setType(int typ, int val) {
validateType(typ);
info &= ~(0x3 << (typ*2));
info |= (val&0x3) << (typ * 2);
info &= ~(masks[typ] << shifts[typ]);
info |= (val&masks[typ]) << shifts[typ];
}
/**
@ -183,8 +187,8 @@ class APIInfo {
for (int i = 0; i < vals.length; ++i) {
if (val.equalsIgnoreCase(vals[i])) {
info &= ~(0x3 << (typ*2));
info |= i << (typ*2);
info &= ~(masks[typ] << shifts[typ]);
info |= i << shifts[typ];
return;
}
}
@ -390,8 +394,14 @@ class APIInfo {
for (int i = STA; i < CAT; ++i) { // include status
String s = get(i, false);
if (s != null && s.length() > 0) {
buf.append(s);
buf.append(' ');
if (html && s.indexOf("internal") != -1) {
buf.append("<span style='color:red'>");
buf.append(s);
buf.append("</span>");
} else {
buf.append(s);
buf.append(' ');
}
}
}
@ -457,8 +467,17 @@ class APIInfo {
"abstract", "category", "package", "class", "name", "signature"
};
public static final String getTypeValName(int typ, int val) {
try {
return names[typ][val];
}
catch (Exception e) {
return "";
}
}
private static final String[][] names = {
{ "(draft) ", "(stable) ", "(deprecated)", "(obsolete) " },
{ "(draft) ", "(stable) ", "(deprecated)", "(obsolete) ", "*internal* " },
{ "package", "public", "protected", "private" },
{ "", "static" },
{ "", "final" },
@ -473,7 +492,7 @@ class APIInfo {
};
private static final String[][] shortNames = {
{ "DR", "ST", "DP", "OB" },
{ "DR", "ST", "DP", "OB", "IN" },
{ "PK", "PB", "PT", "PR" },
{ "NS", "ST" },
{ "NF", "FN" },

View File

@ -34,8 +34,6 @@
* -source 1.4
* com.ibm.icu.lang com.ibm.icu.math com.ibm.icu.text com.ibm.icu.util
*
* todo: separate generation of data files (which requires taglet) from
* comparison and report generation (which does not require it)
* 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
@ -62,6 +60,7 @@ public class GatherAPIData {
Pattern pat;
boolean zip;
boolean gzip;
boolean internal;
public static int optionLength(String option) {
if (option.equals("-name")) {
@ -76,7 +75,9 @@ public class GatherAPIData {
return 1;
} else if (option.equals("-gzip")) {
return 1;
}
} else if (option.equals("-internal")) {
return 1;
}
return 0;
}
@ -102,7 +103,9 @@ public class GatherAPIData {
this.zip = true;
} else if (opt.equals("-gzip")) {
this.gzip = true;
}
} else if (opt.equals("-internal")) {
this.internal = true;
}
}
results = new TreeSet(APIInfo.defaultComparator());
@ -143,9 +146,6 @@ public class GatherAPIData {
bw.newLine();
writeResults(results, bw);
bw.close(); // should flush, close all, etc
// if (zip) {
// ((ZipOutputStream)os).finish();
// }
} catch (IOException e) {
try { bw.close(); } catch (IOException e2) {}
RuntimeException re = new RuntimeException("write error: " + e.getMessage());
@ -188,10 +188,12 @@ public class GatherAPIData {
if (doc.qualifiedName().indexOf(".misc") != -1) {
System.out.println("misc: " + doc.qualifiedName()); return true;
}
Tag[] tags = doc.tags();
for (int i = 0; i < tags.length; ++i) {
if (tagKindIndex(tags[i].kind()) == INTERNAL) return true;
}
if (!internal) { // debug
Tag[] tags = doc.tags();
for (int i = 0; i < tags.length; ++i) {
if (tagKindIndex(tags[i].kind()) == INTERNAL) { return true; }
}
}
if (pat != null && (doc.isClass() || doc.isInterface())) {
if (!pat.matcher(doc.name()).matches()) {
return true;
@ -331,7 +333,7 @@ public class GatherAPIData {
return info;
}
private static int tagStatus(final Doc doc) {
private int tagStatus(final Doc doc) {
class Result {
int res = -1;
void set(int val) {
@ -341,7 +343,8 @@ public class GatherAPIData {
return;
} else if (res != APIInfo.STA_DEPRECATED) {
// if already not deprecated, this is an error
throw new RuntimeException("bad doc: " + doc + " old: " + res + " new: " + val);
System.err.println("bad doc: " + doc + " both: " + APIInfo.getTypeValName(APIInfo.STA, res) + " and: " + APIInfo.getTypeValName(APIInfo.STA, val));
return;
}
}
// ok to replace with new tag
@ -366,7 +369,7 @@ public class GatherAPIData {
switch (ix) {
case INTERNAL:
result.set(-2);
result.set(internal ? APIInfo.STA_INTERNAL : -2); // -2 for legacy compatibility
break;
case DRAFT:

View File

@ -73,7 +73,7 @@ public class ReportAPI {
String newFile = null;
String outFile = null;
boolean html = false;
boolean internal = false;
for (int i = 0; i < args.length; ++i) {
String arg = args[i];
if (arg.equals("-old:")) {
@ -84,10 +84,12 @@ public class ReportAPI {
outFile = args[++i];
} else if (arg.equals("-html")) {
html = true;
} else if (arg.equals("-internal")) {
internal = true;
}
}
new ReportAPI(oldFile, newFile).writeReport(outFile, html);
new ReportAPI(oldFile, newFile, internal).writeReport(outFile, html, internal);
}
/*
@ -108,9 +110,13 @@ public class ReportAPI {
*/
ReportAPI(String oldFile, String newFile) {
oldData = APIData.read(oldFile);
newData = APIData.read(newFile);
ReportAPI(String oldFile, String newFile, boolean internal) {
this(APIData.read(oldFile, internal), APIData.read(newFile, internal));
}
ReportAPI(APIData oldData, APIData newData) {
this.oldData = oldData;
this.newData = newData;
removed = (TreeSet)oldData.set.clone();
removed.removeAll(newData.set);
@ -128,7 +134,7 @@ public class ReportAPI {
PrintWriter outpw = new PrintWriter(System.out);
APIInfo a = null, r = null;
while (ai.hasNext() && ri.hasNext()) {
while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
if (a == null) a = (APIInfo)ai.next();
if (r == null) r = (APIInfo)ri.next();
@ -190,7 +196,7 @@ public class ReportAPI {
ai = changedAdded.iterator();
ri = changedRemoved.iterator();
a = r = null;
while (ai.hasNext() && ri.hasNext()) {
while ((a != null || ai.hasNext()) && (r != null || ri.hasNext())) {
if (a == null) a = (APIInfo)ai.next();
if (r == null) r = (APIInfo)ri.next();
int result = c.compare(a, r);
@ -223,13 +229,13 @@ public class ReportAPI {
}
}
int lstatus = lhs.getVal(APIInfo.STA);
if (lstatus == APIInfo.STA_OBSOLETE || lstatus == APIInfo.STA_DEPRECATED) {
if (lstatus == APIInfo.STA_OBSOLETE || lstatus == APIInfo.STA_DEPRECATED || lstatus == APIInfo.STA_INTERNAL) {
return -1;
}
return 1;
}
private boolean writeReport(String outFile, boolean html) {
private boolean writeReport(String outFile, boolean html, boolean internal) {
OutputStream os = System.out;
if (outFile != null) {
try {
@ -279,7 +285,11 @@ public class ReportAPI {
pw.println();
pw.println("<hr/>");
pw.println("<h2>Deprecated or Obsoleted in " + newData.name + "</h2>");
if (internal) {
pw.println("<h2>Withdrawn, Deprecated, or Obsoleted in " + newData.name + "</h2>");
} else {
pw.println("<h2>Deprecated or Obsoleted in " + newData.name + "</h2>");
}
if (obsoleted.size() > 0) {
printResults(obsoleted, pw, true, false);
} else {
@ -331,7 +341,11 @@ public class ReportAPI {
pw.println();
pw.println();
pw.println("=== Deprecatd or Obsoleted in " + newData.name + " ===");
if (internal) {
pw.println("=== Withdrawn, Deprecated, or Obsoleted in " + newData.name + " ===");
} else {
pw.println("=== Deprecated or Obsoleted in " + newData.name + " ===");
}
if (obsoleted.size() > 0) {
printResults(obsoleted, pw, false, false);
} else {
@ -421,29 +435,14 @@ public class ReportAPI {
}
clas = className;
}
// pw.print(" ");
}
if (html) {
pw.print("<li>");
// if (info instanceof DeltaInfo) {
// DeltaInfo dinfo = (DeltaInfo)info;
// dinfo.removed.print(pw, isChangedAPIs, html);
// pw.println("</br>");
// dinfo.added.print(pw, isChangedAPIs, html);
// } else {
info.print(pw, isChangedAPIs, html);
// }
pw.println("</li>");
} else {
// if (info instanceof DeltaInfo) {
// DeltaInfo dinfo = (DeltaInfo)info;
// dinfo.removed.println(pw, isChangedAPIs, html);
// pw.print(" --> ");
// dinfo.added.println(pw, isChangedAPIs, html);
// } else {
info.println(pw, isChangedAPIs, html);
// }
}
}

View File

@ -20,8 +20,7 @@ import com.ibm.icu.impl.Assert;
* Rule Based Break Iterator
* This is a port of the C++ class RuleBasedBreakIterator from ICU4C.
*
* @internal
* @deprecated This API is ICU internal only.
* @stable ICU 2.0
*/
public class RuleBasedBreakIterator extends BreakIterator {
@ -31,7 +30,7 @@ public class RuleBasedBreakIterator extends BreakIterator {
//=======================================================================
/**
*@internal
* @internal
* @deprecated This API is ICU internal only.
*/
public RuleBasedBreakIterator() {