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"
59 + " if (!c[m].cls) continue;\n"
61 + " arr.push(c[m]);\n"
62 + " arr.push(c[m].cls.$class);\n"
66 private static native Object[] findMethodData(
67 Class<?> clazz, String prefix);
69 public static Method findMethod(
70 Class<?> clazz, String name, Class<?>... parameterTypes) {
71 Object[] data = findMethodData(clazz, name + "__");
72 BIG: for (int i = 0; i < data.length; i += 3) {
73 String sig = ((String) data[i]).substring(name.length() + 2);
74 Class<?> cls = (Class<?>) data[i + 2];
75 Method tmp = INSTANCE.create(cls, name, data[i + 1], sig);
76 Class<?>[] tmpParms = tmp.getParameterTypes();
77 if (parameterTypes.length != tmpParms.length) {
80 for (int j = 0; j < tmpParms.length; j++) {
81 if (!parameterTypes[j].equals(tmpParms[j])) {
90 public static Method[] findMethods(Class<?> clazz, int mask) {
91 Object[] namesAndData = findMethodData(clazz, "");
93 for (int i = 0; i < namesAndData.length; i += 3) {
94 String sig = (String) namesAndData[i];
95 Object data = namesAndData[i + 1];
96 int middle = sig.indexOf("__");
100 String name = sig.substring(0, middle);
101 sig = sig.substring(middle + 2);
102 Class<?> cls = (Class<?>) namesAndData[i + 2];
103 final Method m = INSTANCE.create(cls, name, data, sig);
104 if ((m.getModifiers() & mask) == 0) {
107 namesAndData[cnt++] = m;
109 Method[] arr = new Method[cnt];
110 for (int i = 0; i < cnt; i++) {
111 arr[i] = (Method) namesAndData[i];
115 static String toSignature(Method m) {
116 StringBuilder sb = new StringBuilder();
117 sb.append(m.getName()).append("__");
118 appendType(sb, m.getReturnType());
119 Class<?>[] arr = m.getParameterTypes();
120 for (int i = 0; i < arr.length; i++) {
121 appendType(sb, arr[i]);
123 return sb.toString();
126 private static void appendType(StringBuilder sb, Class<?> type) {
127 if (type == Integer.TYPE) {
131 if (type == Long.TYPE) {
135 if (type == Double.TYPE) {
139 if (type == Float.TYPE) {
143 if (type == Byte.TYPE) {
147 if (type == Boolean.TYPE) {
151 if (type == Short.TYPE) {
155 if (type == Void.TYPE) {
159 if (type == Character.TYPE) {
163 if (type.isArray()) {
165 appendType(sb, type.getComponentType());
168 sb.append('L').append(type.getName().replace('.', '_'));
172 public static int signatureElements(String sig) {
173 Enumeration<Class> en = signatureParser(sig);
175 while (en.hasMoreElements()) {
182 public static Enumeration<Class> signatureParser(final String sig) {
183 class E implements Enumeration<Class> {
186 public boolean hasMoreElements() {
187 return pos < sig.length();
190 public Class nextElement() {
191 switch (sig.charAt(pos++)) {
209 return Character.TYPE;
212 int up = sig.indexOf("_2", pos);
213 String type = sig.substring(pos, up);
215 return Class.forName(type.replace('_', '.'));
216 } catch (ClassNotFoundException ex) {
217 throw new IllegalStateException(ex);
220 char nch = sig.charAt(pos++);
221 assert nch == '3' : "Can't find '3' at " + sig.substring(pos - 1);
222 final Class compType = nextElement();
223 return Array.newInstance(compType, 0).getClass();
226 throw new UnsupportedOperationException(sig + " at " + pos);