From 9ba39378eb703af25d811722b10206e55b5bbdad Mon Sep 17 00:00:00 2001 From: chibash Date: Fri, 13 May 2022 02:15:47 +0900 Subject: [PATCH] does refactoring --- .../bytecode/SignatureAttribute.java | 222 ++++++++++-------- 1 file changed, 130 insertions(+), 92 deletions(-) diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java index 37eec07f..ff160f82 100644 --- a/src/main/javassist/bytecode/SignatureAttribute.java +++ b/src/main/javassist/bytecode/SignatureAttribute.java @@ -122,106 +122,23 @@ public class SignatureAttribute extends AttributeInfo { if (j < 0) break; - StringBuilder nameBuf = new StringBuilder(); - StringBuilder genericParamBuf = new StringBuilder(); final ArrayList nameBufs = new ArrayList<>(); final ArrayList genericParamBufs = new ArrayList<>(); - int k = j; - char c; - try { - while ((c = desc.charAt(++k)) != ';') { - if (c == '<') { - genericParamBuf.append(c); - int level = 1; - while (level > 0) { - c = desc.charAt(++k); - genericParamBuf.append(c); - if (c == '<') - ++level; - else if (c == '>') - --level; - } - } - else if (c == '.') { - nameBufs.add(nameBuf); - genericParamBufs.add(genericParamBuf); - nameBuf = new StringBuilder(); - genericParamBuf = new StringBuilder(); - } - else - nameBuf.append(c); - } - } - catch (IndexOutOfBoundsException e) { break; } - - nameBufs.add(nameBuf); - genericParamBufs.add(genericParamBuf); - i = k + 1; + i = parseClassName(nameBufs, genericParamBufs, desc, j) + 1; + if (i < 0) + break; String name = String.join("$", nameBufs.toArray(new StringBuilder[0])); String newname = map.get(name); if (newname != null) { - final String[] nameSplit = name.split("\\$"); - final String[] newnameSplit = newname.split("\\$"); - if (nameSplit.length == newnameSplit.length) { - final String[] newnames = new String[nameBufs.size()]; - for (int start = 0, z = 0; z < nameBufs.size(); z++) { - final int toAggregate = (int) nameBufs.get(z).chars().filter(ch -> ch == '$').count() + 1; - String s = String.join("$", Arrays.copyOfRange(newnameSplit, start, start + toAggregate)); - start += toAggregate; - newnames[z] = s; - } - - newdesc.append(desc.substring(head, j)); - newdesc.append('L'); - for (int z = 0; z < newnames.length; z++) { - if (z > 0) - newdesc.append('.'); - - newdesc.append(newnames[z]); - final String newgenericParam; - final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); - if (genericParamBufCurrent.length() > 0) - newgenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; - else - newgenericParam = genericParamBufCurrent.toString(); //empty string - - newdesc.append(newgenericParam); - } - newdesc.append(c); //the final semicolon + if (makeNewClassName(desc, map, name, newname, newdesc, head, j, + nameBufs, genericParamBufs)) head = i; - } - } - else { - final ArrayList newGenericParamBufs = new ArrayList(); - boolean changed = false; - for (int z = 0; z < genericParamBufs.size(); z++) { - final String newGenericParam; - final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); - if (genericParamBufCurrent.length() > 0) { - newGenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; - changed = changed || !genericParamBufCurrent.toString().equals(newGenericParam); - } - else - newGenericParam = genericParamBufCurrent.toString(); //empty string - - newGenericParamBufs.add(newGenericParam); - } - - if (changed) { - newdesc.append(desc.substring(head, j)); - newdesc.append('L'); - for (int z = 0; z < genericParamBufs.size(); z++) { - if (z > 0) - newdesc.append('.'); - - newdesc.append(nameBufs.get(z)); - newdesc.append(newGenericParamBufs.get(z)); - } - newdesc.append(';'); - head = i; - } } + else + if (replaceTypeArguments(desc, map, newdesc, head, j, + nameBufs, genericParamBufs)) + head = i; } if (head == 0) @@ -233,6 +150,127 @@ public class SignatureAttribute extends AttributeInfo { return newdesc.toString(); } + private static int parseClassName(ArrayList nameBufs, + ArrayList genericParamBufs, + String desc, int j) + { + StringBuilder nameBuf = new StringBuilder(); + StringBuilder genericParamBuf = new StringBuilder(); + int k = j; + char c; + try { + while ((c = desc.charAt(++k)) != ';') { + if (c == '<') { + genericParamBuf.append(c); + int level = 1; + while (level > 0) { + c = desc.charAt(++k); + genericParamBuf.append(c); + if (c == '<') + ++level; + else if (c == '>') + --level; + } + } + else if (c == '.') { + nameBufs.add(nameBuf); + genericParamBufs.add(genericParamBuf); + nameBuf = new StringBuilder(); + genericParamBuf = new StringBuilder(); + } + else + nameBuf.append(c); + } + } + catch (IndexOutOfBoundsException e) { + return -2; // error + } + + nameBufs.add(nameBuf); + genericParamBufs.add(genericParamBuf); + return k; + } + + private static boolean makeNewClassName(String desc, + Map map, String name, + String newname, StringBuilder newdesc, + int head, int j, + ArrayList nameBufs, + ArrayList genericParamBufs) + { + final String[] nameSplit = name.split("\\$"); + final String[] newnameSplit = newname.split("\\$"); + if (nameSplit.length == newnameSplit.length) { + final String[] newnames = new String[nameBufs.size()]; + for (int start = 0, z = 0; z < nameBufs.size(); z++) { + final int toAggregate = (int) nameBufs.get(z).chars().filter(ch -> ch == '$').count() + 1; + String s = String.join("$", Arrays.copyOfRange(newnameSplit, start, start + toAggregate)); + start += toAggregate; + newnames[z] = s; + } + + newdesc.append(desc.substring(head, j)); + newdesc.append('L'); + for (int z = 0; z < newnames.length; z++) { + if (z > 0) + newdesc.append('.'); + + newdesc.append(newnames[z]); + final String newgenericParam; + final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); + if (genericParamBufCurrent.length() > 0) + newgenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; + else + newgenericParam = genericParamBufCurrent.toString(); //empty string + + newdesc.append(newgenericParam); + } + newdesc.append(';'); //the final semicolon + return true; + } + else + return false; + } + + private static boolean replaceTypeArguments(String desc, + Map map, + StringBuilder newdesc, + int head, int j, + ArrayList nameBufs, + ArrayList genericParamBufs) + { + final ArrayList newGenericParamBufs = new ArrayList(); + boolean changed = false; + for (int z = 0; z < genericParamBufs.size(); z++) { + final String newGenericParam; + final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); + if (genericParamBufCurrent.length() > 0) { + newGenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; + changed = changed || !genericParamBufCurrent.toString().equals(newGenericParam); + } + else + newGenericParam = genericParamBufCurrent.toString(); //empty string + + newGenericParamBufs.add(newGenericParam); + } + + if (changed) { + newdesc.append(desc.substring(head, j)); + newdesc.append('L'); + for (int z = 0; z < genericParamBufs.size(); z++) { + if (z > 0) + newdesc.append('.'); + + newdesc.append(nameBufs.get(z)); + newdesc.append(newGenericParamBufs.get(z)); + } + newdesc.append(';'); + return true; + } + else + return false; + } + @SuppressWarnings("unused") private static boolean isNamePart(int c) { return c != ';' && c != '<'; -- 2.39.5