Main.java revision fdeef52e2b7df4cd2184bb42deb8f1e4325cedce
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import java.lang.reflect.Method; 18import java.lang.reflect.Proxy; 19import java.util.Arrays; 20 21public class Main { 22 public static void main(String[] args) throws Exception { 23 System.loadLibrary(args[1]); 24 25 doTest(); 26 } 27 28 public static void doTest() throws Exception { 29 testMethod("java.lang.Object", "toString"); 30 testMethod("java.lang.String", "charAt", int.class); 31 testMethod("java.lang.Math", "sqrt", double.class); 32 testMethod("java.util.List", "add", Object.class); 33 34 testMethod(getProxyClass(), "run"); 35 36 // Find a synthetic method in the dummy inner class. Do not print the name. Javac and Jack 37 // disagree on the naming of synthetic accessors. 38 testMethod(findSyntheticMethod(), NestedSynthetic.class, false); 39 } 40 41 private static Class<?> proxyClass = null; 42 43 private static Class<?> getProxyClass() throws Exception { 44 if (proxyClass != null) { 45 return proxyClass; 46 } 47 48 proxyClass = Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Runnable.class }); 49 return proxyClass; 50 } 51 52 private static void testMethod(String className, String methodName, Class<?>... types) 53 throws Exception { 54 Class<?> base = Class.forName(className); 55 testMethod(base, methodName, types); 56 } 57 58 private static void testMethod(Class<?> base, String methodName, Class<?>... types) 59 throws Exception { 60 Method m = base.getDeclaredMethod(methodName, types); 61 testMethod(m, base, true); 62 } 63 64 private static void testMethod(Method m, Class<?> base, boolean printName) { 65 String[] result = getMethodName(m); 66 if (!result[0].equals(m.getName())) { 67 throw new RuntimeException("Name not equal: " + m.getName() + " vs " + result[0]); 68 } 69 if (printName) { 70 System.out.println(Arrays.toString(result)); 71 } 72 73 Class<?> declClass = getMethodDeclaringClass(m); 74 if (base != declClass) { 75 throw new RuntimeException("Declaring class not equal: " + base + " vs " + declClass); 76 } 77 System.out.println(declClass); 78 79 int modifiers = getMethodModifiers(m); 80 if (modifiers != m.getModifiers()) { 81 throw new RuntimeException("Modifiers not equal: " + m.getModifiers() + " vs " + modifiers); 82 } 83 System.out.println(modifiers); 84 85 System.out.print("Max locals: "); 86 try { 87 System.out.println(getMaxLocals(m)); 88 } catch (RuntimeException e) { 89 System.out.println(e.getMessage()); 90 } 91 92 System.out.print("Argument size: "); 93 try { 94 System.out.println(getArgumentsSize(m)); 95 } catch (RuntimeException e) { 96 System.out.println(e.getMessage()); 97 } 98 99 System.out.print("Location start: "); 100 try { 101 System.out.println(getMethodLocationStart(m)); 102 } catch (RuntimeException e) { 103 System.out.println(e.getMessage()); 104 } 105 106 System.out.print("Location end: "); 107 try { 108 System.out.println(getMethodLocationEnd(m)); 109 } catch (RuntimeException e) { 110 System.out.println(e.getMessage()); 111 } 112 113 System.out.println("Is native: " + isMethodNative(m)); 114 System.out.println("Is obsolete: " + isMethodObsolete(m)); 115 System.out.println("Is synthetic: " + isMethodSynthetic(m)); 116 } 117 118 private static class NestedSynthetic { 119 // Accessing this private field will create a synthetic accessor method; 120 private static String dummy; 121 } 122 123 private static void dummyAccess() { 124 System.out.println(NestedSynthetic.dummy); 125 } 126 127 private static Method findSyntheticMethod() throws Exception { 128 Method methods[] = NestedSynthetic.class.getDeclaredMethods(); 129 for (Method m : methods) { 130 if (m.isSynthetic()) { 131 return m; 132 } 133 } 134 throw new RuntimeException("Could not find synthetic method"); 135 } 136 137 private static native String[] getMethodName(Method m); 138 private static native Class<?> getMethodDeclaringClass(Method m); 139 private static native int getMethodModifiers(Method m); 140 private static native int getMaxLocals(Method m); 141 private static native int getArgumentsSize(Method m); 142 private static native long getMethodLocationStart(Method m); 143 private static native long getMethodLocationEnd(Method m); 144 private static native boolean isMethodNative(Method m); 145 private static native boolean isMethodObsolete(Method m); 146 private static native boolean isMethodSynthetic(Method m); 147} 148