RevEngAPIpublic class RevEngAPI extends APIFormatter Make up a compilable version of a given Sun or other API,
so developers can compile against it without a licensed copy. In Sun's case,
all public API info is public on Sun's web site, so this does not disclose
anything that is Sun Confidential.
This is a clean-room implementation: I did not look at the code
for Sun's javap or any similar tool in preparing this program.
XXX TODO:
- Class printing: add superclasses.
- Collapse common code in printing Constructors and Methods
- Method printing: add exceptions
- Arguments: Handle arrays (names begin [L)
- Provide default (0, false, null) based on type; use in return statements
and in assigment to protected final variables.
|
Fields Summary |
---|
private static final String | PREFIX_ARG | private String | classNameNOT THREAD SAFE | private int | classNameOffset | private ModInfo[] | modInfo |
Methods Summary |
---|
private java.lang.String | defaultValue(java.lang.Class c)
if (c.getName().equals("boolean"))
return "false";
// XXX else if object type return null;
else return "0";
| public void | doClass(java.lang.Class c)Generate a .java file for the outline of the given class.
className = c.getName();
// pre-compute offset for stripping package name
classNameOffset = className.lastIndexOf('.") + 1;
// Inner class
if (className.indexOf('$") != -1)
return;
// get name, as String, with . changed to /
String slashName = className.replace('.",'/");
String fileName = slashName + ".java";
System.out.println(className + " --> " + fileName);
String dirName = slashName.substring(0, slashName.lastIndexOf("/"));
new File(dirName).mkdirs();
// create the file.
PrintWriter out = new PrintWriter(new FileWriter(fileName));
out.println("// Generated by RevEngAPI for class " + className);
// If in a package, say so.
Package pkg;
if ((pkg = c.getPackage()) != null) {
out.println("package " + pkg.getName() + ';");
out.println();
}
// print class header
int cMods = c.getModifiers();
printMods(cMods, out);
out.print("class ");
out.print(trim(c.getName()));
out.print(' ");
// XXX get superclass
out.println('{");
// print constructors
Constructor[] ctors = c.getDeclaredConstructors();
for (int i=0; i< ctors.length; i++) {
if (i == 0) {
out.println();
out.println("\t// Constructors");
}
Constructor cons = ctors[i];
int mods = cons.getModifiers();
if (Modifier.isPrivate(mods))
continue;
out.print('\t");
printMods(mods, out);
out.print(trim(cons.getName()) + "(");
Class[] classes = cons.getParameterTypes();
for (int j = 0; j<classes.length; j++) {
if (j > 0) out.print(", ");
out.print(trim(classes[j].getName()) + ' " +
mkName(PREFIX_ARG, j));
}
out.println(") {");
out.print("\t}");
}
// print method names
Method[] mems = c.getDeclaredMethods();
for (int i=0; i< mems.length; i++) {
if (i == 0) {
out.println();
out.println("\t// Methods");
}
Method m = mems[i];
if (m.getName().startsWith("access$"))
continue;
int mods = m.getModifiers();
if (Modifier.isPrivate(mods))
continue;
out.print('\t");
printMods(mods, out);
out.print(m.getReturnType());
out.print(' ");
out.print(trim(m.getName()) + "(");
Class[] classes = m.getParameterTypes();
for (int j = 0; j<classes.length; j++) {
if (j > 0) out.print(", ");
out.print(trim(classes[j].getName()) + ' " +
mkName(PREFIX_ARG, j));
}
out.println(") {");
out.println("\treturn " + defaultValue(m.getReturnType()) + ';");
out.println("\t}");
}
// print fields
Field[] flds = c.getDeclaredFields();
for (int i=0; i< flds.length; i++) {
if (i == 0) {
out.println();
out.println("\t// Fields");
}
Field f = flds[i];
int mods = f.getModifiers();
if (Modifier.isPrivate(mods))
continue;
out.print('\t");
printMods(mods, out);
out.print(trim(f.getType().getName()));
out.print(' ");
out.print(f.getName());
if (Modifier.isFinal(mods)) {
try {
out.print(" = " + f.get(null));
} catch (IllegalAccessException ex) {
out.print("; // " + ex.toString());
}
}
out.println(';");
}
out.println("}");
//out.flush();
out.close();
| public void | endFile()
// XXX generate a trivial "build.xml" for Ant to create the jar file.
| public static void | main(java.lang.String[] argv)
new RevEngAPI().doArgs(argv);
| private java.lang.String | mkName(java.lang.String name, int number)Make up names like "arg0" "arg1", etc.
return new StringBuffer(name).append(number).toString();
| private void | printMods(int mods, java.io.PrintWriter out)
for (int i=0; i < modInfo.length; i++) {
if ((mods & modInfo[i].val) == modInfo[i].val) {
out.print(modInfo[i].name);
out.print(' ");
}
}
| public void | startFile()
// XXX save filename as project name
| private java.lang.String | trim(java.lang.String theName)
return theName.startsWith(className) ?
theName.substring(classNameOffset) : theName;
|
|