2 * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
25 package org.apidesign.bck2brwsr.emul.reflect;
27 import java.lang.reflect.Array;
28 import java.lang.reflect.Method;
29 import java.util.Enumeration;
30 import org.apidesign.bck2brwsr.core.JavaScriptBody;
32 /** Utilities to work on methods.
34 * @author Jaroslav Tulach <jtulach@netbeans.org>
36 public abstract class MethodImpl {
37 public static MethodImpl INSTANCE;
40 Class.forName(Method.class.getName());
41 } catch (ClassNotFoundException ex) {
42 throw new IllegalStateException(ex);
46 protected abstract Method create(Class<?> declaringClass, String name, Object data, String sig);
50 // bck2brwsr implementation
53 @JavaScriptBody(args = {"clazz", "prefix"},
55 + "var c = clazz.cnstr.prototype;"
56 + "var arr = new Array();\n"
58 + " if (m.indexOf(prefix) === 0) {\n"
60 + " arr.push(c[m]);\n"
64 private static native Object[] findMethodData(
65 Class<?> clazz, String prefix);
67 public static Method findMethod(
68 Class<?> clazz, String name, Class<?>... parameterTypes) {
69 Object[] data = findMethodData(clazz, name + "__");
70 BIG: for (int i = 0; i < data.length; i += 2) {
71 String sig = ((String) data[0]).substring(name.length() + 2);
72 Method tmp = INSTANCE.create(clazz, name, data[1], sig);
73 Class<?>[] tmpParms = tmp.getParameterTypes();
74 if (parameterTypes.length != tmpParms.length) {
77 for (int j = 0; j < tmpParms.length; j++) {
78 if (!parameterTypes[j].equals(tmpParms[j])) {
87 public static Method[] findMethods(Class<?> clazz, int mask) {
88 Object[] namesAndData = findMethodData(clazz, "");
90 for (int i = 0; i < namesAndData.length; i += 2) {
91 String sig = (String) namesAndData[i];
92 Object data = namesAndData[i + 1];
93 int middle = sig.indexOf("__");
97 String name = sig.substring(0, middle);
98 sig = sig.substring(middle + 2);
99 final Method m = INSTANCE.create(clazz, name, data, sig);
100 if ((m.getModifiers() & mask) == 0) {
103 namesAndData[cnt++] = m;
105 Method[] arr = new Method[cnt];
106 for (int i = 0; i < cnt; i++) {
107 arr[i] = (Method) namesAndData[i];
111 static String toSignature(Method m) {
112 StringBuilder sb = new StringBuilder();
113 sb.append(m.getName()).append("__");
114 appendType(sb, m.getReturnType());
115 Class<?>[] arr = m.getParameterTypes();
116 for (int i = 0; i < arr.length; i++) {
117 appendType(sb, arr[i]);
119 return sb.toString();
122 private static void appendType(StringBuilder sb, Class<?> type) {
123 if (type == Integer.TYPE) {
127 if (type == Long.TYPE) {
131 if (type == Double.TYPE) {
135 if (type == Float.TYPE) {
139 if (type == Byte.TYPE) {
143 if (type == Boolean.TYPE) {
147 if (type == Short.TYPE) {
151 if (type == Void.TYPE) {
155 if (type == Character.TYPE) {
159 if (type.isArray()) {
161 appendType(sb, type.getComponentType());
164 sb.append('L').append(type.getName().replace('.', '_'));
168 public static int signatureElements(String sig) {
169 Enumeration<Class> en = signatureParser(sig);
171 while (en.hasMoreElements()) {
178 public static Enumeration<Class> signatureParser(final String sig) {
179 class E implements Enumeration<Class> {
182 public boolean hasMoreElements() {
183 return pos < sig.length();
186 public Class nextElement() {
187 switch (sig.charAt(pos++)) {
205 return Character.TYPE;
208 int up = sig.indexOf("_2", pos);
209 String type = sig.substring(pos, up);
211 return Class.forName(type.replace('_', '.'));
212 } catch (ClassNotFoundException ex) {
213 throw new IllegalStateException(ex);
216 char nch = sig.charAt(pos++);
217 assert nch == '3' : "Can't find '3' at " + sig.substring(pos - 1);
218 final Class compType = nextElement();
219 return Array.newInstance(compType, 0).getClass();
222 throw new UnsupportedOperationException(sig + " at " + pos);