blob: 932a1ea414946697de6d1693192df17136571c1f [file] [log] [blame]
Andreas Gampe3c252f02016-10-27 18:25:17 -07001/*
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;
Andreas Gampe368a2082016-10-28 17:33:13 -070018import java.lang.reflect.Proxy;
Andreas Gampe3c252f02016-10-27 18:25:17 -070019import java.util.Arrays;
20
21public class Main {
22 public static void main(String[] args) throws Exception {
Andreas Gampe3c252f02016-10-27 18:25:17 -070023 doTest();
24 }
25
26 public static void doTest() throws Exception {
27 testMethod("java.lang.Object", "toString");
28 testMethod("java.lang.String", "charAt", int.class);
29 testMethod("java.lang.Math", "sqrt", double.class);
30 testMethod("java.util.List", "add", Object.class);
Andreas Gampe368a2082016-10-28 17:33:13 -070031
32 testMethod(getProxyClass(), "run");
Andreas Gampefdeef522017-01-09 14:40:25 -080033
34 // Find a synthetic method in the dummy inner class. Do not print the name. Javac and Jack
35 // disagree on the naming of synthetic accessors.
36 testMethod(findSyntheticMethod(), NestedSynthetic.class, false);
Andreas Gampe368a2082016-10-28 17:33:13 -070037 }
38
39 private static Class<?> proxyClass = null;
40
41 private static Class<?> getProxyClass() throws Exception {
42 if (proxyClass != null) {
43 return proxyClass;
44 }
45
46 proxyClass = Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Runnable.class });
47 return proxyClass;
Andreas Gampe3c252f02016-10-27 18:25:17 -070048 }
49
50 private static void testMethod(String className, String methodName, Class<?>... types)
51 throws Exception {
52 Class<?> base = Class.forName(className);
Andreas Gampe368a2082016-10-28 17:33:13 -070053 testMethod(base, methodName, types);
54 }
55
56 private static void testMethod(Class<?> base, String methodName, Class<?>... types)
57 throws Exception {
Andreas Gampe3c252f02016-10-27 18:25:17 -070058 Method m = base.getDeclaredMethod(methodName, types);
Andreas Gampefdeef522017-01-09 14:40:25 -080059 testMethod(m, base, true);
60 }
61
62 private static void testMethod(Method m, Class<?> base, boolean printName) {
Andreas Gampe3c252f02016-10-27 18:25:17 -070063 String[] result = getMethodName(m);
Andreas Gampefdeef522017-01-09 14:40:25 -080064 if (!result[0].equals(m.getName())) {
65 throw new RuntimeException("Name not equal: " + m.getName() + " vs " + result[0]);
66 }
67 if (printName) {
68 System.out.println(Arrays.toString(result));
69 }
Andreas Gampe368a2082016-10-28 17:33:13 -070070
71 Class<?> declClass = getMethodDeclaringClass(m);
72 if (base != declClass) {
73 throw new RuntimeException("Declaring class not equal: " + base + " vs " + declClass);
74 }
75 System.out.println(declClass);
Andreas Gampe36bcd4f2016-10-28 18:07:18 -070076
77 int modifiers = getMethodModifiers(m);
78 if (modifiers != m.getModifiers()) {
79 throw new RuntimeException("Modifiers not equal: " + m.getModifiers() + " vs " + modifiers);
80 }
81 System.out.println(modifiers);
Andreas Gampef71832e2017-01-09 11:38:04 -080082
83 System.out.print("Max locals: ");
84 try {
85 System.out.println(getMaxLocals(m));
86 } catch (RuntimeException e) {
87 System.out.println(e.getMessage());
88 }
89
90 System.out.print("Argument size: ");
91 try {
92 System.out.println(getArgumentsSize(m));
93 } catch (RuntimeException e) {
94 System.out.println(e.getMessage());
95 }
96
97 System.out.print("Location start: ");
98 try {
99 System.out.println(getMethodLocationStart(m));
100 } catch (RuntimeException e) {
101 System.out.println(e.getMessage());
102 }
103
104 System.out.print("Location end: ");
105 try {
106 System.out.println(getMethodLocationEnd(m));
107 } catch (RuntimeException e) {
108 System.out.println(e.getMessage());
109 }
Andreas Gampefdeef522017-01-09 14:40:25 -0800110
111 System.out.println("Is native: " + isMethodNative(m));
112 System.out.println("Is obsolete: " + isMethodObsolete(m));
113 System.out.println("Is synthetic: " + isMethodSynthetic(m));
114 }
115
116 private static class NestedSynthetic {
117 // Accessing this private field will create a synthetic accessor method;
118 private static String dummy;
119 }
120
121 private static void dummyAccess() {
122 System.out.println(NestedSynthetic.dummy);
123 }
124
125 private static Method findSyntheticMethod() throws Exception {
126 Method methods[] = NestedSynthetic.class.getDeclaredMethods();
127 for (Method m : methods) {
128 if (m.isSynthetic()) {
129 return m;
130 }
131 }
132 throw new RuntimeException("Could not find synthetic method");
Andreas Gampe3c252f02016-10-27 18:25:17 -0700133 }
134
135 private static native String[] getMethodName(Method m);
Andreas Gampe368a2082016-10-28 17:33:13 -0700136 private static native Class<?> getMethodDeclaringClass(Method m);
Andreas Gampe36bcd4f2016-10-28 18:07:18 -0700137 private static native int getMethodModifiers(Method m);
Andreas Gampef71832e2017-01-09 11:38:04 -0800138 private static native int getMaxLocals(Method m);
139 private static native int getArgumentsSize(Method m);
140 private static native long getMethodLocationStart(Method m);
141 private static native long getMethodLocationEnd(Method m);
Andreas Gampefdeef522017-01-09 14:40:25 -0800142 private static native boolean isMethodNative(Method m);
143 private static native boolean isMethodObsolete(Method m);
144 private static native boolean isMethodSynthetic(Method m);
Andreas Gampe3c252f02016-10-27 18:25:17 -0700145}