diff options
-rw-r--r-- | dexgen/src/com/android/dexgen/rop/cst/CstType.java | 13 | ||||
-rw-r--r-- | dexgen/src/com/android/dexgen/rop/type/Type.java | 76 |
2 files changed, 86 insertions, 3 deletions
diff --git a/dexgen/src/com/android/dexgen/rop/cst/CstType.java b/dexgen/src/com/android/dexgen/rop/cst/CstType.java index 3a92e7a8c..8ad418b37 100644 --- a/dexgen/src/com/android/dexgen/rop/cst/CstType.java +++ b/dexgen/src/com/android/dexgen/rop/cst/CstType.java @@ -134,6 +134,17 @@ public final class CstType extends TypedConstant { } /** + * Returns an interned instance of this class for the given + * {@code Class} instance. + * + * @param clazz {@code non-null;} the underlying {@code Class} object + * @return {@code non-null;} an appropriately-constructed instance + */ + public static CstType intern(Class clazz) { + return intern(Type.intern(clazz)); + } + + /** * Constructs an instance. * * @param type {@code non-null;} the underlying type @@ -227,4 +238,4 @@ public final class CstType extends TypedConstant { return descriptor; } -} +}
\ No newline at end of file diff --git a/dexgen/src/com/android/dexgen/rop/type/Type.java b/dexgen/src/com/android/dexgen/rop/type/Type.java index 62f3f14e5..365bd781e 100644 --- a/dexgen/src/com/android/dexgen/rop/type/Type.java +++ b/dexgen/src/com/android/dexgen/rop/type/Type.java @@ -31,6 +31,10 @@ public final class Type implements TypeBearer, Comparable<Type> { private static final HashMap<String, Type> internTable = new HashMap<String, Type>(500); + /** {@code non-null;} table mapping types as {@code Class} objects to internal form */ + private static final HashMap<Class, Type> CLASS_TYPE_MAP = + new HashMap<Class, Type>(); + /** basic type constant for {@code void} */ public static final int BT_VOID = 0; @@ -117,6 +121,20 @@ public final class Type implements TypeBearer, Comparable<Type> { * Note: VOID isn't put in the intern table, since it's special and * shouldn't be found by a normal call to intern(). */ + + /* + * Create a mapping between types as Java Class objects + * and types in dx internal format. + */ + CLASS_TYPE_MAP.put(boolean.class, BOOLEAN); + CLASS_TYPE_MAP.put(short.class, SHORT); + CLASS_TYPE_MAP.put(int.class, INT); + CLASS_TYPE_MAP.put(long.class, LONG); + CLASS_TYPE_MAP.put(char.class, CHAR); + CLASS_TYPE_MAP.put(byte.class, BYTE); + CLASS_TYPE_MAP.put(float.class, FLOAT); + CLASS_TYPE_MAP.put(double.class, DOUBLE); + CLASS_TYPE_MAP.put(void.class, VOID); } /** @@ -277,6 +295,21 @@ public final class Type implements TypeBearer, Comparable<Type> { private Type initializedType; /** + * Returns the unique instance corresponding to the type represented by + * given {@code Class} object. See vmspec-2 sec4.3.2 for details on the + * field descriptor syntax. This method does <i>not</i> allow + * {@code "V"} (that is, type {@code void}) as a valid + * descriptor. + * + * @param clazz {@code non-null;} class whose descriptor + * will be internalized + * @return {@code non-null;} the corresponding instance + */ + public static Type intern(Class clazz) { + return intern(getInternalTypeName(clazz)); + } + + /** * Returns the unique instance corresponding to the type with the * given descriptor. See vmspec-2 sec4.3.2 for details on the * field descriptor syntax. This method does <i>not</i> allow @@ -289,7 +322,7 @@ public final class Type implements TypeBearer, Comparable<Type> { * invalid syntax */ public static Type intern(String descriptor) { - + Type result = internTable.get(descriptor); if (result != null) { return result; @@ -362,6 +395,20 @@ public final class Type implements TypeBearer, Comparable<Type> { } /** + * Returns the unique instance corresponding to the type represented by + * given {@code Class} object, allowing {@code "V"} to return the type + * for {@code void}. Other than that one caveat, this method + * is identical to {@link #intern}. + * + * @param clazz {@code non-null;} class which descriptor + * will be internalized + * @return {@code non-null;} the corresponding instance + */ + public static Type internReturnType(Class clazz) { + return internReturnType(getInternalTypeName(clazz)); + } + + /** * Returns the unique instance corresponding to the type with the * given descriptor, allowing {@code "V"} to return the type * for {@code void}. Other than that one caveat, this method @@ -411,6 +458,31 @@ public final class Type implements TypeBearer, Comparable<Type> { } /** + * Converts type name in the format as returned by reflection + * into dex internal form. + * + * @param clazz {@code non-null;} class whose name will be internalized + * @return string with the type name in dex internal format + */ + public static String getInternalTypeName(Class clazz) { + if (clazz == null) { + throw new NullPointerException("clazz == null"); + } + + if (clazz.isPrimitive()) { + return CLASS_TYPE_MAP.get(clazz).getDescriptor(); + } + + String slashed = clazz.getName().replace('.', '/'); + + if (clazz.isArray()) { + return slashed; + } + + return 'L' + slashed + ';'; + } + + /** * Constructs an instance corresponding to an "uninitialized type." * This is a private constructor; use one of the public static * methods to get instances. @@ -853,4 +925,4 @@ public final class Type implements TypeBearer, Comparable<Type> { return type; } } -} +}
\ No newline at end of file |