001:package sli.kim.classfile;
002:
003:/**
004:* This class provides a useful routine to convert signatures to
005:* regular java type declarations.
006:*/
007:public class Signature {
008: // Signature is not meant to be instantiated
009: private Signature() {}
010:
011: /**
012: * Convert a signature into a normal type declaration.
013: * <ul>
014: * <li>"I",null -> "int"
015: * <li>"Z","foo" -> "boolean foo"
016: * <li>"[J","foo" -> "long[] foo"
017: * <li>"Lmypackage/MyClass;",null -> "mypackage.MyClass"
018: * <li>"()V",null -> "void ()"
019: * <li>"(S[Ljava/lang/String;)V","foo" -> "void foo (short, String[])"
020: * </ul>
021: * @param sig the signature.
022: * @param name the name of the field or method. This can be null.
023: */
024: public static String signatureToTypeDecl(String sig, String name) {
025: String[] sigOut = new String[1];
026: sigOut[0] = sig;
027: return _sigToType(sigOut, name);
028: }
029:
030: private static String _sigToType(String[] sigOut, String name) {
031: if (sigOut[0] == null || sigOut[0].length() == 0)
032: return "";
033:
034: String sig = sigOut[0];
035: String result = "";
036:
037: switch (sig.charAt(0)) {
038: case 'V':
039: result = "void";
040: sig = sig.substring(1);
041: break;
042: case 'B':
043: result = "byte";
044: sig = sig.substring(1);
045: break;
046: case 'S':
047: result = "short";
048: sig = sig.substring(1);
049: break;
050: case 'I':
051: result = "int";
052: sig = sig.substring(1);
053: break;
054: case 'J':
055: result = "long";
056: sig = sig.substring(1);
057: break;
058: case 'F':
059: result = "float";
060: sig = sig.substring(1);
061: break;
062: case 'D':
063: result = "double";
064: sig = sig.substring(1);
065: break;
066: case 'Z':
067: result = "boolean";
068: sig = sig.substring(1);
069: break;
070: case 'L':
071: {
072: int semi = sig.indexOf(';');
073: result = sig.substring(1, semi).replace('/', '.');
074: if (result.startsWith("java.lang."))
075: result = result.substring(10);
076: sig = sig.substring(semi+1);
077: }
078: break;
079: case '[':
080: {
081: sig = sig.substring(1);
082: sigOut[0] = sig;
083: result = _sigToType(sigOut, null) + "[]";
084: sig = sigOut[0];
085: }
086: break;
087: case '(':
088: {
089: int closeParen = sig.indexOf(')');
090: String[] paramOut = new String[1];
091: paramOut[0] = sig.substring(1, closeParen);
092: String paramStr = "";
093: while (paramOut[0] != null && paramOut[0].length() > 0) {
094: paramStr += _sigToType(paramOut, null);
095: if (paramOut[0] != null && paramOut[0].length() > 0)
096: paramStr += ", ";
097: }
098: String[] returnOut = new String[1];
099: returnOut[0] = sig.substring(closeParen+1);
100: String returnStr = _sigToType(returnOut, name);
101: result = returnStr + " (" + paramStr + ')';
102: name = null;
103: }
104: break;
105: }
106:
107: sigOut[0] = sig;
108: return result + (name != null ? " " + name : "");
109: }
110:
111: /**
112: * Simple unit test. Usage:
113: * <pre>java sli.kim.classfile.Signature <signature> [<name>]</pre>
114: */
115: public static void main(String[] args) {
116: if (args.length == 2)
117: System.out.println(signatureToTypeDecl(args[0], args[1]));
118: else
119: System.out.println(signatureToTypeDecl(args[0], null));
120: }
121:}
122:
|