ICU-5362 gather and report information about internal APIs
X-SVN-Rev: 20221
This commit is contained in:
parent
2c80376017
commit
054143f68f
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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" },
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user