jodd-proxetta/src/main/java/jodd/asm/AsmUtil.java
public static String typedescToSignature(final String desc, final MutableInteger from) {
		int fromIndex = from.get();
		from.value++;	// default usage for most cases

		switch (desc.charAt(fromIndex)) {
			case 'B': return "byte";
			case 'C': return "char";
			case 'D': return "double";
			case 'F': return "float";
			case 'I': return "int";
			case 'J': return "long";
			case 'S': return "short";
			case 'Z': return "boolean";
			case 'V': return "void";

			case 'L':
				int index = desc.indexOf(';', fromIndex);
				if (index < 0) {
					throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
				}
				from.set(index + 1);
				String str = desc.substring(fromIndex + 1, index);
				return str.replace('/', '.');

			case 'T':
				return desc.substring(from.value);

			case '[':
				StringBuilder brackets = new StringBuilder();
				int n = fromIndex;
				while (desc.charAt(n) == '[') {	// count opening brackets
					brackets.append("[]");
					n++;
				}
				from.value = n;
				String type = typedescToSignature(desc, from);	// the rest of the string denotes a `<field_type>'
				return type + brackets;

			default:
				if (from.value == 0) {
					throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
				}
				// generics!
				return desc.substring(from.value);
		}
	}
public static String typedescToSignature(final String desc, final MutableInteger from) {
		int fromIndex = from.get();
		from.value++;	// default usage for most cases

		switch (desc.charAt(fromIndex)) {
			case 'B': return "byte";
			case 'C': return "char";
			case 'D': return "double";
			case 'F': return "float";
			case 'I': return "int";
			case 'J': return "long";
			case 'S': return "short";
			case 'Z': return "boolean";
			case 'V': return "void";

			case 'L':
				int index = desc.indexOf(';', fromIndex);
				if (index < 0) {
					throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
				}
				from.set(index + 1);
				String str = desc.substring(fromIndex + 1, index);
				return str.replace('/', '.');

			case 'T':
				return desc.substring(from.value);

			case '[':
				StringBuilder brackets = new StringBuilder();
				int n = fromIndex;
				while (desc.charAt(n) == '[') {	// count opening brackets
					brackets.append("[]");
					n++;
				}
				from.value = n;
				String type = typedescToSignature(desc, from);	// the rest of the string denotes a `<field_type>'
				return type + brackets;

			default:
				if (from.value == 0) {
					throw new IllegalArgumentException(INVALID_TYPE_DESCRIPTION + desc);
				}
				// generics!
				return desc.substring(from.value);
		}
	}
Returns java-like signature of a bytecode-like description.
Only first description is parsed.

The field signature represents the value of an argument to a function or
the value of a variable. It is a series of bytes generated by the
following grammar:

<PRE>{@code
<field_signature> ::= <field_type>
<field_type>      ::= <base_type>|<object_type>|<array_type>
<base_type>       ::= B|C|D|F|I|J|S|Z
<object_type>     ::= L<fullclassname>;
<array_type>      ::= [<field_type>

The meaning of the base types is as follows:
B byte signed byte
C char character
D double double precision IEEE float
F float single precision IEEE float
I int integer
J long long integer
L<fullclassname>; ... an object of the given class
S short signed short
Z boolean true or false
[<field sig> ... array
}</PRE>

This method converts this string into a Java type declaration such as
<code>String[]</code>.