Minor refactoring: remove the duplicated code further (cherry picked from commit e0c3cdf)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/c46f9fcd Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/c46f9fcd Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/c46f9fcd Branch: refs/heads/GROOVY_2_6_X Commit: c46f9fcd9b6f1b6cf03fc55c756817c54b8a2b95 Parents: 15da82d Author: sunlan <sun...@apache.org> Authored: Tue Feb 6 16:03:41 2018 +0800 Committer: sunlan <sun...@apache.org> Committed: Tue Feb 6 17:09:46 2018 +0800 ---------------------------------------------------------------------- .../groovy/classgen/asm/BytecodeHelper.java | 44 ++++++------------ .../classgen/asm/util/TypeDescriptionUtil.java | 47 ++++++++++++++++---- 2 files changed, 53 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/c46f9fcd/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java index 4b812f1..a983af4 100644 --- a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java +++ b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java @@ -163,30 +163,23 @@ public class BytecodeHelper implements Opcodes { * @return the ASM type description */ private static String getTypeDescription(ClassNode c, boolean end) { - StringBuilder buf = new StringBuilder(); ClassNode d = c; - while (true) { - if (ClassHelper.isPrimitiveType(d.redirect())) { - d = d.redirect(); - buf.append(TypeDescriptionUtil.getDescriptionByType(d)); - return buf.toString(); - } else if (d.isArray()) { - buf.append('['); - d = d.getComponentType(); - } else { - buf.append('L'); - String name = d.getName(); - int len = name.length(); - for (int i = 0; i < len; ++i) { - char car = name.charAt(i); - buf.append(car == '.' ? '/' : car); - } - if (end) buf.append(';'); - return buf.toString(); + if (ClassHelper.isPrimitiveType(d.redirect())) { + d = d.redirect(); + } + + String desc = TypeDescriptionUtil.getDescriptionByType(d); + + if (!end) { + if (desc.endsWith(";")) { + desc = desc.substring(0, desc.length() - 1); } } + + return desc; } + /** * @return an array of ASM internal names of the type */ @@ -267,16 +260,7 @@ public class BytecodeHelper implements Opcodes { return "java.lang.Object;"; } - if (name.equals("int") - || name.equals("long") - || name.equals("short") - || name.equals("float") - || name.equals("double") - || name.equals("byte") - || name.equals("char") - || name.equals("boolean") - || name.equals("void") - ) { + if (TypeDescriptionUtil.isPrimitiveType(name)) { return name; } @@ -297,7 +281,7 @@ public class BytecodeHelper implements Opcodes { prefix = "["; name = name.substring(0, name.length() - 2); - return prefix + TypeDescriptionUtil.getDescriptionByName(name) + (TypeDescriptionUtil.isPrimitiveType(name) ? "" : name.replace('/', '.') + ";"); + return prefix + TypeDescriptionUtil.getDescriptionByName(name); } return name.replace('/', '.'); http://git-wip-us.apache.org/repos/asf/groovy/blob/c46f9fcd/src/main/java/org/codehaus/groovy/classgen/asm/util/TypeDescriptionUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/util/TypeDescriptionUtil.java b/src/main/java/org/codehaus/groovy/classgen/asm/util/TypeDescriptionUtil.java index 18a6e8d..2f7349a 100644 --- a/src/main/java/org/codehaus/groovy/classgen/asm/util/TypeDescriptionUtil.java +++ b/src/main/java/org/codehaus/groovy/classgen/asm/util/TypeDescriptionUtil.java @@ -19,6 +19,7 @@ package org.codehaus.groovy.classgen.asm.util; +import groovy.lang.Tuple2; import org.apache.groovy.util.Maps; import org.codehaus.groovy.ast.ClassNode; @@ -34,6 +35,9 @@ import static org.codehaus.groovy.ast.ClassHelper.int_TYPE; import static org.codehaus.groovy.ast.ClassHelper.long_TYPE; import static org.codehaus.groovy.ast.ClassHelper.short_TYPE; +/** + * A utility for extracting type description + */ public class TypeDescriptionUtil { private static final String REF_DESCRIPTION = "L"; private static final Map<ClassNode, String> TYPE_TO_DESCRIPTION_MAP = Maps.of( @@ -69,21 +73,48 @@ public class TypeDescriptionUtil { } public static String getDescriptionByType(ClassNode type) { - if (null == type) { - return REF_DESCRIPTION; - } - String desc = TYPE_TO_DESCRIPTION_MAP.get(type); - return null == desc ? REF_DESCRIPTION : desc; + if (null == desc) { // reference type + if (!type.isArray()) { + return makeRefDescription(type.getName()); + } + + StringBuilder arrayDescription = new StringBuilder(32); + Tuple2<ClassNode, Integer> arrayInfo = extractArrayInfo(type); + + for (int i = 0, dimension = arrayInfo.getSecond(); i < dimension; i++) { + arrayDescription.append("["); + } + + ClassNode componentType = arrayInfo.getFirst(); + return arrayDescription.append(getDescriptionByType(componentType)).toString(); + } + + return desc; } public static String getDescriptionByName(String name) { - if (null == name) { - return REF_DESCRIPTION; + ClassNode type = NAME_TO_TYPE_MAP.get(name); + + if (null == type) { + return makeRefDescription(name); } - return getDescriptionByType(NAME_TO_TYPE_MAP.get(name)); + return getDescriptionByType(type); + } + + private static String makeRefDescription(String name) { + return REF_DESCRIPTION + name.replace('.', '/') + ";"; } + private static Tuple2<ClassNode, Integer> extractArrayInfo(ClassNode type) { + int dimension = 0; + + do { + dimension++; + } while ((type = type.getComponentType()).isArray()); + + return new Tuple2<ClassNode, Integer>(type, dimension); + } }