rt/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 17 Jan 2017 07:04:06 +0100
changeset 1985 cd1cc103a03c
parent 1787 ea12a3bb4b33
permissions -rw-r--r--
Implementation of ClassValue for bck2brwsr
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012-2015 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 import java.io.IOException;
    21 import java.io.Serializable;
    22 import java.lang.annotation.Annotation;
    23 import java.lang.annotation.Retention;
    24 import java.lang.annotation.RetentionPolicy;
    25 import java.lang.reflect.Method;
    26 import java.net.MalformedURLException;
    27 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    28 
    29 /**
    30  *
    31  * @author Jaroslav Tulach <jtulach@netbeans.org>
    32  */
    33 @ClassesMarker(number = 10, nicknames = { "Ten", "Deset" }, count = ClassesMarker.E.TWO, subs = {
    34     @ClassesMarker.Anno(Integer.SIZE),
    35     @ClassesMarker.Anno(Integer.MIN_VALUE)
    36 })
    37 @ClassesNamer(name = "my text", anno = @ClassesMarker.Anno(333))
    38 public class Classes {
    39     public static String nameOfIO() {
    40         return nameFor(IOException.class);
    41     }
    42     
    43     private static String nameFor(Class<?> c) {
    44         return c.getName();
    45     }
    46     
    47     private static final Class<?> PRELOAD = Runnable.class;
    48     
    49     public static boolean isInterface(String s) throws ClassNotFoundException {
    50         return Class.forName(s).isInterface();
    51     }
    52     
    53     public static boolean equalsClassesOfExceptions() {
    54         return MalformedURLException.class.getSuperclass() == IOException.class;
    55     }
    56     public static boolean differenceInClasses() {
    57         Class<?> c1 = MalformedURLException.class;
    58         Class<?> c2 = IOException.class;
    59         return c1 != c2;
    60     }
    61     
    62     public static String classForInstance() {
    63         return new IOException().getClass().getName().toString();
    64     }
    65     
    66     @ClassesMarker(number = 1, nicknames = { "One", "Jedna" } )
    67     public static String name() {
    68         return IOException.class.getName().toString();
    69     }
    70 
    71     @ClassesMarker(self = Self.class, number = 42, nicknames = {})
    72     public static class Self {
    73     }
    74 
    75     @ClassesMarker(number = 42, nicknames = {})
    76     public static class DefaultSelf {
    77     }
    78 
    79     public static int self() {
    80         ClassesMarker cm = Self.class.getAnnotation(ClassesMarker.class);
    81         if (cm.self() == Self.class) {
    82             return 1;
    83         } else {
    84             return 0;
    85         }
    86     }
    87 
    88     public static int defaultSelf() {
    89         ClassesMarker cm = DefaultSelf.class.getAnnotation(ClassesMarker.class);
    90         if (cm.self() == Object.class) {
    91             return 1;
    92         } else {
    93             throw new IllegalStateException("" + cm.self());
    94         }
    95     }
    96 
    97     public static String simpleName() {
    98         return IOException.class.getSimpleName();
    99     }
   100     public static String canonicalName() {
   101         return IOException.class.getCanonicalName();
   102     }
   103     
   104     public static String objectName() throws NoSuchMethodException {
   105         return IOException.class.getMethod("wait").getDeclaringClass().getName();
   106     }
   107     
   108     public static boolean newInstance() throws Exception {
   109         IOException ioe = IOException.class.newInstance();
   110         if (ioe instanceof IOException) {
   111             return ioe.getClass() == IOException.class;
   112         }
   113         throw new IllegalStateException("Not a subtype: " + ioe);
   114     }
   115     public static String newInstanceNoPubConstructor() throws Exception {
   116         try {
   117             Float f = Float.class.newInstance();
   118             return "wrong, can't instantiate: " + f;
   119         } catch (Exception ex) {
   120             return (ex.getClass().getName() + ":" + ex.getMessage()).toString().toString();
   121         }
   122     }
   123     public static int getMarker() {
   124         if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) {
   125             return -2;
   126         }
   127         ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
   128         assert cm instanceof Object : "Is object " + cm;
   129         assert cm instanceof Annotation : "Is annotation " + cm;
   130         assert !((Object)cm instanceof Class) : "Is not Class " + cm;
   131         return cm == null ? -1 : cm.number();
   132     }
   133     public static int getMarkerDefault() {
   134         try { throw new IllegalStateException(); } catch (Exception e) {}
   135         ClassesMarker cm = CD.class.getAnnotation(ClassesMarker.class);
   136         return cm == null ? -1 : cm.number();
   137     }
   138     public static String getMarkerNicknames() {
   139         ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
   140         if (cm == null) {
   141             return null;
   142         }
   143         
   144         final Object[] arr = cm.nicknames();
   145         assert arr instanceof Object[] : "Instance of Object array: " + arr;
   146         assert arr instanceof String[] : "Instance of String array: " + arr;
   147         assert !(arr instanceof Integer[]) : "Not instance of Integer array: " + arr;
   148         
   149         StringBuilder sb = new StringBuilder();
   150         for (String s : cm.nicknames()) {
   151             sb.append(s).append("\n");
   152         }
   153         return sb.toString().toString();
   154     }
   155 
   156     static String listObject(boolean string, String prefix) {
   157         final Class<?> c = string ? String.class : Object.class;
   158         StringBuilder sb = new StringBuilder();
   159         for (Method m : c.getMethods()) {
   160             final String n = m.getName();
   161             if (n.startsWith(prefix)) {
   162                 sb.append(n).append("\n");
   163             }
   164         }
   165         return sb.toString().toString();
   166     }
   167     @Retention(RetentionPolicy.CLASS)
   168     @interface Ann {
   169     }
   170     
   171     public static String getRetention() throws Exception {
   172         Retention r = Ann.class.getAnnotation(Retention.class);
   173         assert r != null : "Annotation is present";
   174         assert r.value() == RetentionPolicy.CLASS : "Policy value is OK: " + r.value();
   175         return r.annotationType().getName();
   176     }
   177     public static String getMarkerE() {
   178         ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
   179         if (cm == null) {
   180             return null;
   181         }
   182         return cm.count().name();
   183     }
   184 
   185     @ClassesMarker(nicknames = {})
   186     class CD {
   187     }
   188     public static String getMarkerED() {
   189         ClassesMarker cm = CD.class.getAnnotation(ClassesMarker.class);
   190         if (cm == null) {
   191             return null;
   192         }
   193         return cm.count().name();
   194     }
   195     public static String getNamer(boolean direct) {
   196         if (direct) {
   197             ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class);
   198             return cm == null ? null : cm.name();
   199         }
   200         for (Annotation a : Classes.class.getAnnotations()) {
   201             if (a instanceof ClassesNamer) {
   202                 return ((ClassesNamer)a).name();
   203             }
   204         }
   205         return null;
   206     }
   207     public static int getInnerNamer() {
   208         ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class);
   209         assert cm != null : "ClassesNamer is present";
   210         return cm.anno().value();
   211     }
   212     public static int getInnerNamers() {
   213         ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
   214         assert cm != null : "ClassesNamer is present";
   215         int sum = 0;
   216         for (ClassesMarker.Anno anno : cm.subs()) {
   217             sum += anno.value();
   218         }
   219         return sum;
   220     }
   221     
   222     public static String intType() {
   223         return Integer.TYPE.getName();
   224     }
   225     
   226     public static int primitive() {
   227         return 1;
   228     }
   229     public static boolean primitiveB() {
   230         return true;
   231     }
   232     
   233     public static String primitiveType(String method) throws Exception {
   234         return reflectiveMethodCall(false, method).getClass().getName();
   235     }
   236     
   237     @JavaScriptBody(args = "msg", body = "throw msg;")
   238     private static native void thrw(String msg);
   239     
   240     public static Object reflectiveMethodCall(boolean direct, String mn) throws Exception {
   241         Method find = null;
   242         StringBuilder sb = new StringBuilder();
   243         if (!direct) {
   244             final Class<? extends Annotation> v = ClassesMarker.class;
   245             for (Method m : Classes.class.getMethods()) {
   246                 sb.append("\n").append(m.getName());
   247                 if (mn != null) {
   248                     if (m.getName().equals(mn)) {
   249                         find = m;
   250                         break;
   251                     }
   252                 } else {
   253                     if (m.getAnnotation(v) != null) {
   254                         find = m;
   255                         break;
   256                     }
   257                 }
   258             }
   259         } else {
   260             find = Classes.class.getMethod(mn);
   261         }
   262         if (find == null) {
   263             thrw(sb.toString());
   264             throw new NullPointerException(sb.toString());
   265         }
   266         return find.invoke(null);
   267     }
   268     
   269     public static int reflectiveSum(int a, int b) throws Exception {
   270         Method m = StaticMethod.class.getMethod("sum", int.class, int.class);
   271         return (int) m.invoke(null, a, b);
   272     }
   273     
   274     private abstract class Application {
   275         public abstract int getID();
   276     }
   277 
   278     private class MyApplication extends Application {
   279         @Override
   280         public int getID() {
   281             return 1;
   282         }
   283     }
   284 
   285     public static boolean isClassAssignable() {
   286         return Application.class.isAssignableFrom(MyApplication.class);
   287     }
   288     
   289     public static String valueEnum(String v) {
   290         return ClassesMarker.E.valueOf(v).toString();
   291     }
   292     
   293     public static String typeOfFn() {
   294         return fn().getClass().getName();
   295     }
   296     
   297     @JavaScriptBody(args = {  }, body = "return function() { alert('x'); };")
   298     private native static Object fn();
   299     
   300     public static boolean instanceOfSuperInterface() {
   301         Object obj = new SuperSerial() {
   302         };
   303         return obj instanceof Serializable;
   304     }
   305     
   306     public static String superInterface() {
   307         return dumpInterfaces(SuperSerial.class);
   308     }
   309 
   310     private static String dumpInterfaces(final Class<?> aClass) {
   311         final Class<?>[] arr = aClass.getInterfaces();
   312         StringBuilder sb = new StringBuilder();
   313         for (Class<?> c : arr) {
   314             sb.append(c.getName()).append("\n");
   315         }
   316         return sb.toString();
   317     }
   318 
   319     public static String superInterfaceInst() {
   320         return dumpInterfaces(new SuperSerial() {}.getClass());
   321     }
   322     
   323     private static interface SuperSerial extends Serializable {
   324     }
   325 }