jaroslav@378: /** jaroslav@378: * Back 2 Browser Bytecode Translator jaroslav@378: * Copyright (C) 2012 Jaroslav Tulach jaroslav@378: * jaroslav@378: * This program is free software: you can redistribute it and/or modify jaroslav@378: * it under the terms of the GNU General Public License as published by jaroslav@378: * the Free Software Foundation, version 2 of the License. jaroslav@378: * jaroslav@378: * This program is distributed in the hope that it will be useful, jaroslav@378: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@378: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@378: * GNU General Public License for more details. jaroslav@378: * jaroslav@378: * You should have received a copy of the GNU General Public License jaroslav@378: * along with this program. Look for COPYING file in the top folder. jaroslav@378: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@235: */ jaroslav@555: package org.apidesign.bck2brwsr.emul.reflect; jaroslav@235: jaroslav@235: import java.lang.annotation.Annotation; jaroslav@652: import java.lang.reflect.Method; jaroslav@652: import java.lang.reflect.Modifier; jaroslav@235: import org.apidesign.bck2brwsr.core.JavaScriptBody; jaroslav@235: jaroslav@235: /** jaroslav@235: * jaroslav@235: * @author Jaroslav Tulach jaroslav@235: */ jaroslav@266: public final class AnnotationImpl implements Annotation { jaroslav@654: private final Class type; jaroslav@654: jaroslav@654: public AnnotationImpl(Class type) { jaroslav@654: this.type = type; jaroslav@654: } jaroslav@654: jaroslav@235: public Class annotationType() { jaroslav@654: return type; jaroslav@235: } jaroslav@235: jaroslav@652: @JavaScriptBody(args = { "a", "n", "arr", "values" }, body = "" jaroslav@253: + "function f(v, p) {\n" jaroslav@253: + " var val = v;\n" jaroslav@253: + " var prop = p;\n" jaroslav@253: + " return function() {\n" jaroslav@253: + " return val[prop];\n" jaroslav@253: + " };\n" jaroslav@253: + "}\n" jaroslav@652: + "for (var i = 0; i < arr.length; i += 2) {\n" jaroslav@652: + " var m = arr[i];\n" jaroslav@652: + " var p = arr[i + 1];\n" jaroslav@652: + " a[m] = new f(values, p);\n" jaroslav@253: + "}\n" jaroslav@253: + "a['$instOf_' + n] = true;\n" jaroslav@235: + "return a;" jaroslav@235: ) jaroslav@652: private static native T create( jaroslav@652: AnnotationImpl a, String n, String[] methodsAndProps, Object values jaroslav@652: ); jaroslav@652: jaroslav@266: public static T create(Class annoClass, Object values) { jaroslav@654: return create(new AnnotationImpl(annoClass), jaroslav@652: annoClass.getName().replace('.', '_'), jaroslav@652: findProps(annoClass), values jaroslav@652: ); jaroslav@235: } jaroslav@238: jaroslav@266: public static Annotation[] create(Object anno) { jaroslav@238: String[] names = findNames(anno); jaroslav@238: Annotation[] ret = new Annotation[names.length]; jaroslav@238: for (int i = 0; i < names.length; i++) { jaroslav@652: String annoNameSlash = names[i].substring(1, names[i].length() - 1); jaroslav@654: Class annoClass; jaroslav@652: try { jaroslav@654: annoClass = (Class)Class.forName(annoNameSlash.replace('/', '.')); jaroslav@652: } catch (ClassNotFoundException ex) { jaroslav@652: throw new IllegalStateException("Can't find annotation class " + annoNameSlash); jaroslav@652: } jaroslav@652: ret[i] = create( jaroslav@654: new AnnotationImpl(annoClass), jaroslav@652: annoNameSlash.replace('/', '_'), jaroslav@652: findProps(annoClass), jaroslav@652: findData(anno, names[i]) jaroslav@652: ); jaroslav@238: } jaroslav@238: return ret; jaroslav@238: } jaroslav@238: @JavaScriptBody(args = "anno", body = jaroslav@238: "var arr = new Array();" jaroslav@254: + "var props = Object.getOwnPropertyNames(anno);\n" jaroslav@254: + "for (var i = 0; i < props.length; i++) {\n" jaroslav@254: + " var p = props[i];\n" jaroslav@238: + " arr.push(p);" jaroslav@238: + "}" jaroslav@238: + "return arr;" jaroslav@238: ) jaroslav@652: private static native String[] findNames(Object anno); jaroslav@238: jaroslav@238: @JavaScriptBody(args={ "anno", "p"}, body="return anno[p];") jaroslav@652: private static native Object findData(Object anno, String p); jaroslav@652: jaroslav@652: private static String[] findProps(Class annoClass) { jaroslav@652: final Method[] marr = MethodImpl.findMethods(annoClass, Modifier.PUBLIC); jaroslav@652: String[] arr = new String[marr.length * 2]; jaroslav@652: int pos = 0; jaroslav@652: for (Method m : marr) { jaroslav@652: arr[pos++] = MethodImpl.toSignature(m); jaroslav@652: arr[pos++] = m.getName(); jaroslav@652: } jaroslav@652: return arr; jaroslav@238: } jaroslav@235: }