| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package libcore.reflect; |
| |
| import java.lang.reflect.GenericArrayType; |
| import java.lang.reflect.ParameterizedType; |
| import java.lang.reflect.Type; |
| import java.lang.reflect.TypeVariable; |
| import java.util.HashMap; |
| import java.util.Map; |
| import libcore.util.EmptyArray; |
| |
| public final class Types { |
| private Types() { |
| } |
| |
| // Holds a mapping from Java type names to native type codes. |
| private static final Map<Class<?>, String> PRIMITIVE_TO_SIGNATURE; |
| static { |
| PRIMITIVE_TO_SIGNATURE = new HashMap<Class<?>, String>(9); |
| PRIMITIVE_TO_SIGNATURE.put(byte.class, "B"); |
| PRIMITIVE_TO_SIGNATURE.put(char.class, "C"); |
| PRIMITIVE_TO_SIGNATURE.put(short.class, "S"); |
| PRIMITIVE_TO_SIGNATURE.put(int.class, "I"); |
| PRIMITIVE_TO_SIGNATURE.put(long.class, "J"); |
| PRIMITIVE_TO_SIGNATURE.put(float.class, "F"); |
| PRIMITIVE_TO_SIGNATURE.put(double.class, "D"); |
| PRIMITIVE_TO_SIGNATURE.put(void.class, "V"); |
| PRIMITIVE_TO_SIGNATURE.put(boolean.class, "Z"); |
| } |
| |
| public static Type[] getTypeArray(ListOfTypes types, boolean clone) { |
| if (types.length() == 0) { |
| return EmptyArray.TYPE; |
| } |
| Type[] result = types.getResolvedTypes(); |
| return clone ? result.clone() : result; |
| } |
| |
| public static Type getType(Type type) { |
| if (type instanceof ParameterizedTypeImpl) { |
| return ((ParameterizedTypeImpl)type).getResolvedType(); |
| } |
| return type; |
| } |
| |
| /** |
| * Returns the internal name of {@code clazz} (also known as the descriptor). |
| */ |
| public static String getSignature(Class<?> clazz) { |
| String primitiveSignature = PRIMITIVE_TO_SIGNATURE.get(clazz); |
| if (primitiveSignature != null) { |
| return primitiveSignature; |
| } else if (clazz.isArray()) { |
| return "[" + getSignature(clazz.getComponentType()); |
| } else { |
| // TODO: this separates packages with '.' rather than '/' |
| return "L" + clazz.getName() + ";"; |
| } |
| } |
| |
| /** |
| * Returns the names of {@code types} separated by commas. |
| */ |
| public static String toString(Class<?>[] types) { |
| if (types.length == 0) { |
| return ""; |
| } |
| StringBuilder result = new StringBuilder(); |
| appendTypeName(result, types[0]); |
| for (int i = 1; i < types.length; i++) { |
| result.append(','); |
| appendTypeName(result, types[i]); |
| } |
| return result.toString(); |
| } |
| |
| /** |
| * Appends the best {@link #toString} name for {@code c} to {@code out}. |
| * This works around the fact that {@link Class#getName} is lousy for |
| * primitive arrays (it writes "[C" instead of "char[]") and {@link |
| * Class#getCanonicalName()} is lousy for nested classes (it uses a "." |
| * separator rather than a "$" separator). |
| */ |
| public static void appendTypeName(StringBuilder out, Class<?> c) { |
| int dimensions = 0; |
| while (c.isArray()) { |
| c = c.getComponentType(); |
| dimensions++; |
| } |
| out.append(c.getName()); |
| for (int d = 0; d < dimensions; d++) { |
| out.append("[]"); |
| } |
| } |
| |
| /** |
| * Appends names of the {@code types} to {@code out} separated by commas. |
| */ |
| public static void appendArrayGenericType(StringBuilder out, Type[] types) { |
| if (types.length == 0) { |
| return; |
| } |
| appendGenericType(out, types[0]); |
| for (int i = 1; i < types.length; i++) { |
| out.append(','); |
| appendGenericType(out, types[i]); |
| } |
| } |
| |
| public static void appendGenericType(StringBuilder out, Type type) { |
| if (type instanceof TypeVariable) { |
| out.append(((TypeVariable) type).getName()); |
| } else if (type instanceof ParameterizedType) { |
| out.append(type.toString()); |
| } else if (type instanceof GenericArrayType) { |
| Type simplified = ((GenericArrayType) type).getGenericComponentType(); |
| appendGenericType(out, simplified); |
| out.append("[]"); |
| } else if (type instanceof Class) { |
| Class c = (Class<?>) type; |
| if (c.isArray()){ |
| String as[] = c.getName().split("\\["); |
| int len = as.length-1; |
| if (as[len].length() > 1){ |
| out.append(as[len].substring(1, as[len].length() - 1)); |
| } else { |
| char ch = as[len].charAt(0); |
| if (ch == 'I') { |
| out.append("int"); |
| } else if (ch == 'B') { |
| out.append("byte"); |
| } else if (ch == 'J') { |
| out.append("long"); |
| } else if (ch == 'F') { |
| out.append("float"); |
| } else if (ch == 'D') { |
| out.append("double"); |
| } else if (ch == 'S') { |
| out.append("short"); |
| } else if (ch == 'C') { |
| out.append("char"); |
| } else if (ch == 'Z') { |
| out.append("boolean"); |
| } else if (ch == 'V') { |
| out.append("void"); |
| } |
| } |
| for (int i = 0; i < len; i++){ |
| out.append("[]"); |
| } |
| } else { |
| out.append(c.getName()); |
| } |
| } |
| } |
| } |