1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.bytecode;
6 
7 import org.objectweb.asm.Type;
8 
9 import java.util.HashMap;
10 import java.util.Map;
11 
12 /**
13  * Utility methods for accessing {@link Type}s Strings.
14  *
15  * Useful definitions to keep in mind when using this class:
16  * Internal name - The fully qualified name for a type with dots replaced by slashes. Not really
17  * relevant for primitive types.
18  * Type descriptor - Single letters for primitive types, "L" + internal name + ";" for class types.
19  *
20  * The methods in this class accept internal names or primitive type descriptors.
21  */
22 class TypeUtils {
23     static final String ASSERTION_ERROR = "java/lang/AssertionError";
24     static final String ASSET_MANAGER = "android/content/res/AssetManager";
25     static final String BUILD_HOOKS = "org/chromium/build/BuildHooks";
26     static final String BUILD_HOOKS_ANDROID = "org/chromium/build/BuildHooksAndroid";
27     static final String CONFIGURATION = "android/content/res/Configuration";
28     static final String CONTEXT = "android/content/Context";
29     static final String CONTEXT_WRAPPER = "android/content/ContextWrapper";
30     static final String RESOURCES = "android/content/res/Resources";
31     static final String STRING = "java/lang/String";
32     static final String THEME = "android/content/res/Resources$Theme";
33 
34     static final String BOOLEAN = "Z";
35     static final String INT = "I";
36     static final String VOID = "V";
37     private static final Map<String, Type> PRIMITIVE_DESCRIPTORS;
38     static {
39         PRIMITIVE_DESCRIPTORS = new HashMap<>();
Type.BOOLEAN_TYPE.toString()40         PRIMITIVE_DESCRIPTORS.put(Type.BOOLEAN_TYPE.toString(), Type.BOOLEAN_TYPE);
Type.INT_TYPE.toString()41         PRIMITIVE_DESCRIPTORS.put(Type.INT_TYPE.toString(), Type.INT_TYPE);
Type.VOID_TYPE.toString()42         PRIMITIVE_DESCRIPTORS.put(Type.VOID_TYPE.toString(), Type.VOID_TYPE);
43     }
44 
45     /**
46      * Returns the full method signature with internal names.
47      *
48      * @param methodName Name of the method (ex. "getResources").
49      * @param returnType Internal name for the return type.
50      * @param argumentTypes List of internal names for argument types.
51      * @return String representation of the method signature.
52      */
getMethodSignature( String methodName, String returnType, String... argumentTypes)53     static String getMethodSignature(
54             String methodName, String returnType, String... argumentTypes) {
55         return methodName + getMethodDescriptor(returnType, argumentTypes);
56     }
57 
58     /**
59      * Builds a method descriptor suitable for use with {@link org.objectweb.asm.MethodVisitor}.
60      *
61      * @param returnType Internal name for the return type of the method (primitive or class).
62      * @param argumentTypes Internal names for the argument types (primitive or class).
63      * @return The generated method descriptor.
64      */
getMethodDescriptor(String returnType, String... argumentTypes)65     static String getMethodDescriptor(String returnType, String... argumentTypes) {
66         Type[] typedArguments = new Type[argumentTypes.length];
67         for (int i = 0; i < argumentTypes.length; ++i) {
68             // Argument list should be empty in this case, not V (void).
69             assert !Type.VOID_TYPE.toString().equals(argumentTypes[i]);
70             typedArguments[i] = convert(argumentTypes[i]);
71         }
72         return Type.getMethodDescriptor(convert(returnType), typedArguments);
73     }
74 
75     /**
76      * Converts an internal name for a type to a {@link Type}.
77      *
78      * @param type Internal name for a type (primitive or class).
79      * @return The resulting Type.
80      */
convert(String type)81     private static Type convert(String type) {
82         if (PRIMITIVE_DESCRIPTORS.containsKey(type)) {
83             return PRIMITIVE_DESCRIPTORS.get(type);
84         }
85         return Type.getObjectType(type);
86     }
87 }
88