Some improvements in the code

This commit is contained in:
Ilya Mizus 2014-10-08 03:46:52 +04:00
parent d1d97351b9
commit 7d4cd23837

View File

@ -21,6 +21,7 @@ import java.util.HashMap;
public class SignatureParser { public class SignatureParser {
private final ClassLoader loader; private final ClassLoader loader;
private final char[] array; private final char[] array;
private final String signature;
private int offset; private int offset;
private final Type type; private final Type type;
private final Map<String, TypeVariable> typeVariables; private final Map<String, TypeVariable> typeVariables;
@ -35,6 +36,7 @@ public class SignatureParser {
private SignatureParser(ClassLoader loader, String signature, Map<String, TypeVariable> typeVariables) { private SignatureParser(ClassLoader loader, String signature, Map<String, TypeVariable> typeVariables) {
this.loader = loader; this.loader = loader;
this.signature = signature;
array = signature.toCharArray(); array = signature.toCharArray();
this.typeVariables = typeVariables; this.typeVariables = typeVariables;
type = parseType(); type = parseType();
@ -63,13 +65,15 @@ public class SignatureParser {
} else if (c == 'Z') { } else if (c == 'Z') {
return Boolean.TYPE; return Boolean.TYPE;
} else if (c == 'T') { } else if (c == 'T') {
StringBuilder tnsb = new StringBuilder(); int end = signature.indexOf(';', offset);
while ((c = array[offset++]) != ';') { if (end < 0) {
tnsb.append(c); throw new RuntimeException("No semicolon found while parsing signature");
} }
return typeVariables.get(tnsb.toString()); Type res = typeVariables.get(new String(array, offset, end - offset));
offset = end + 1;
return res;
} else if (c != 'L') { } else if (c != 'L') {
throw new IllegalArgumentException("Unexpected character: " + c); throw new IllegalArgumentException("Unexpected character: " + c + ", signature: " + new String(array, 0, array.length) + ", i = " + offset);
} }
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
Type ownerType = null; Type ownerType = null;
@ -169,45 +173,45 @@ public class SignatureParser {
} }
for (Class cur : classList) { for (Class cur : classList) {
final List<TypeVariable> varsList = new LinkedList<TypeVariable>(); final LinkedList<TypeVariableImpl> varsList = new LinkedList<TypeVariableImpl>();
if (cur.vmClass.addendum != null && cur.vmClass.addendum.signature != null) { if (cur.vmClass.addendum != null && cur.vmClass.addendum.signature != null) {
String signature = Classes.toString((byte[]) cur.vmClass.addendum.signature); String signature = Classes.toString((byte[]) cur.vmClass.addendum.signature);
final char[] signChars = signature.toCharArray(); final char[] signChars = signature.toCharArray();
int i = 0; try {
if (signChars[i] == '<') { int i = 0;
i++; if (signChars[i] == '<') {
do {
StringBuilder typeVarSB = new StringBuilder();
while (signChars[i] != ':') {
typeVarSB.append(signChars[i]);
i++;
}
String typeVarName = typeVarSB.toString();
i++; i++;
do {
StringBuilder typeSB = new StringBuilder(); final int colon = signature.indexOf(':', i);
if (colon < 0 || colon + 1 == signChars.length) {
int angles = 0; throw new RuntimeException("Can't find ':' in the signature " + signature + " starting from " + i);
while (angles > 0 || signChars[i] != ';') { }
if (signChars[i] == '<') angles ++; String typeVarName = new String(signChars, i, colon - i);
else if (signChars[i] == '>') angles --; i = colon + 1;
typeSB.append(signChars[i]);
int start = i;
int angles = 0;
while (angles > 0 || signChars[i] != ';') {
if (signChars[i] == '<') angles ++;
else if (signChars[i] == '>') angles --;
i++;
}
String typeName = new String(signChars, start, i - start + 1);
final Type baseType = SignatureParser.parse(cur.vmClass.loader, typeName, varsMap);
TypeVariableImpl tv = new TypeVariableImpl(typeVarName, baseType);
varsList.add(tv);
i++; i++;
} } while (signChars[i] != '>');
typeSB.append(signChars[i]);
String typeName = typeSB.toString();
final Type baseType = SignatureParser.parse(cur.vmClass.loader, typeName, varsMap);
TypeVariable tv = new TypeVariableImpl(typeVarName, baseType);
varsList.add(tv);
i++;
} while (signChars[i] != '>');
}
} catch (IndexOutOfBoundsException e) {
throw new RuntimeException("Signature of " + cur + " is broken (" + signature + ") and can't be parsed", e);
} }
} }
for (TypeVariable tv : varsList) { for (TypeVariableImpl tv : varsList) {
((TypeVariableImpl)tv).setVars(varsList); tv.setVars(varsList);
varsMap.put(tv.getName(), tv); varsMap.put(tv.getName(), tv);
} }
cur = cur.getDeclaringClass(); cur = cur.getDeclaringClass();
@ -218,7 +222,7 @@ public class SignatureParser {
private static class TypeVariableImpl implements TypeVariable { private static class TypeVariableImpl implements TypeVariable {
private String name; private String name;
private Type baseType; private Type baseType;
private TypeVariable[] vars; private TypeVariableImpl[] vars;
public Type[] getBounds() { public Type[] getBounds() {
return new Type[] { baseType }; return new Type[] { baseType };
@ -241,8 +245,8 @@ public class SignatureParser {
this.baseType = baseType; this.baseType = baseType;
} }
void setVars(List<TypeVariable> vars) { void setVars(List<TypeVariableImpl> vars) {
this.vars = new TypeVariable[vars.size()]; this.vars = new TypeVariableImpl[vars.size()];
vars.toArray(this.vars); vars.toArray(this.vars);
} }