vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
branchjavap
changeset 152 2cda429aeb49
parent 151 40f95fe90cdc
child 156 3bb1a148a795
     1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Nov 11 13:23:52 2012 +0100
     1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Nov 12 00:07:34 2012 +0100
     1.3 @@ -24,6 +24,7 @@
     1.4  import java.util.List;
     1.5  import org.apidesign.bck2brwsr.core.ExtraJavaScript;
     1.6  import org.apidesign.bck2brwsr.core.JavaScriptBody;
     1.7 +import sun.tools.javap.AnnotationParser;
     1.8  import sun.tools.javap.ClassData;
     1.9  import sun.tools.javap.FieldData;
    1.10  import sun.tools.javap.MethodData;
    1.11 @@ -68,19 +69,14 @@
    1.12          Collection<? super String> scripts
    1.13      ) throws IOException {
    1.14          ClassData jc = new ClassData(classFile);
    1.15 -        /*
    1.16 -        final ClassName extraAnn = ClassName.getClassName(ExtraJavaScript.class.getName().replace('.', '/'));
    1.17 -        Annotation a = jc.getAnnotation(extraAnn);
    1.18 -        if (a != null) {
    1.19 -            final ElementValue annVal = a.getComponent("resource").getValue();
    1.20 -            String res = ((PrimitiveElementValue)annVal).getValue().getValue().toString();
    1.21 -            scripts.add(res);
    1.22 -            final AnnotationComponent process = a.getComponent("processByteCode");
    1.23 -            if (process != null && "const=0".equals(process.getValue().toString())) {
    1.24 +        byte[] arrData = jc.findAnnotationData(true);
    1.25 +        String[] arr = findAnnotation(arrData, jc, ExtraJavaScript.class.getName(), "resource", "processByteCode");
    1.26 +        if (arr != null) {
    1.27 +            scripts.add(arr[0]);
    1.28 +            if ("0".equals(arr[1])) {
    1.29                  return null;
    1.30              }
    1.31          }
    1.32 -        */
    1.33          ByteCodeToJavaScript compiler = new ByteCodeToJavaScript(
    1.34              jc, out, references
    1.35          );
    1.36 @@ -989,51 +985,89 @@
    1.37      }
    1.38  
    1.39      private boolean javaScriptBody(MethodData m, boolean isStatic) throws IOException {
    1.40 -        return false;
    1.41 -        /*
    1.42 -        final ClassName extraAnn = ClassName.getClassName(JavaScriptBody.class.getName().replace('.', '/'));
    1.43 -        Annotation a = m.getAnnotation(extraAnn);
    1.44 -        if (a != null) {
    1.45 -            final ElementValue annVal = a.getComponent("body").getValue();
    1.46 -            String body = ((PrimitiveElementValue) annVal).getValue().getValue().toString();
    1.47 +        byte[] arr = m.findAnnotationData(true);
    1.48 +        if (arr == null) {
    1.49 +            return false;
    1.50 +        }
    1.51 +        final String jvmType = "L" + JavaScriptBody.class.getName().replace('.', '/') + ";";
    1.52 +        class P extends AnnotationParser {
    1.53 +            int cnt;
    1.54 +            String[] args = new String[30];
    1.55 +            String body;
    1.56              
    1.57 -            final ArrayElementValue arrVal = (ArrayElementValue) a.getComponent("args").getValue();
    1.58 -            final int len = arrVal.getValues().length;
    1.59 -            String[] names = new String[len];
    1.60 -            for (int i = 0; i < len; i++) {
    1.61 -                names[i] = ((PrimitiveElementValue) arrVal.getValues()[i]).getValue().getValue().toString();
    1.62 +            @Override
    1.63 +            protected void visitAttr(String type, String attr, String value) {
    1.64 +                if (type.equals(jvmType)) {
    1.65 +                    if ("body".equals(attr)) {
    1.66 +                        body = value;
    1.67 +                    } else if ("args".equals(attr)) {
    1.68 +                        args[cnt++] = value;
    1.69 +                    } else {
    1.70 +                        throw new IllegalArgumentException(attr);
    1.71 +                    }
    1.72 +                }
    1.73              }
    1.74 -            out.append("\nfunction ").append(
    1.75 -                jc.getName().getInternalName().replace('/', '_')).append('_').append(findMethodName(m));
    1.76 -            out.append("(");
    1.77 -            String space;
    1.78 -            int index;
    1.79 -            if (!isStatic) {                
    1.80 -                out.append(names[0]);
    1.81 -                space = ",";
    1.82 -                index = 1;
    1.83 -            } else {
    1.84 -                space = "";
    1.85 -                index = 0;
    1.86 -            }
    1.87 -            List<Parameter> args = m.getParameters();
    1.88 -            for (int i = 0; i < args.size(); i++) {
    1.89 -                out.append(space);
    1.90 -                out.append(names[index]);
    1.91 -                final String desc = findDescriptor(args.get(i).getDescriptor());
    1.92 -                index++;
    1.93 -                space = ",";
    1.94 -            }
    1.95 -            out.append(") {").append("\n");
    1.96 -            out.append(body);
    1.97 -            out.append("\n}\n");
    1.98 -            return true;
    1.99          }
   1.100 -        return false;
   1.101 -        */
   1.102 +        P p = new P();
   1.103 +        p.parse(arr, jc);
   1.104 +        if (p.body == null) {
   1.105 +            return false;
   1.106 +        }
   1.107 +        int argsCnt[] = { -1 };
   1.108 +        out.append("\nfunction ").append(className(jc)).append('_').
   1.109 +            append(findMethodName(m, argsCnt));
   1.110 +        out.append("(");
   1.111 +        String space;
   1.112 +        int index;
   1.113 +        if (!isStatic) {                
   1.114 +            out.append(p.args[0]);
   1.115 +            space = ",";
   1.116 +            index = 1;
   1.117 +        } else {
   1.118 +            space = "";
   1.119 +            index = 0;
   1.120 +        }
   1.121 +        for (int i = 0; i < argsCnt[0]; i++) {
   1.122 +            out.append(space);
   1.123 +            out.append(p.args[index]);
   1.124 +            index++;
   1.125 +            space = ",";
   1.126 +        }
   1.127 +        out.append(") {").append("\n");
   1.128 +        out.append(p.body);
   1.129 +        out.append("\n}\n");
   1.130 +        return true;
   1.131      }
   1.132      private static String className(ClassData jc) {
   1.133          //return jc.getName().getInternalName().replace('/', '_');
   1.134          return jc.getClassName().replace('/', '_');
   1.135      }
   1.136 +    
   1.137 +    private static String[] findAnnotation(
   1.138 +        byte[] arr, ClassData cd, final String className, 
   1.139 +        final String... attrNames
   1.140 +    ) throws IOException {
   1.141 +        if (arr == null) {
   1.142 +            return null;
   1.143 +        }
   1.144 +        final String[] values = new String[attrNames.length];
   1.145 +        final boolean[] found = { false };
   1.146 +        final String jvmType = "L" + className.replace('.', '/') + ";";
   1.147 +        AnnotationParser ap = new AnnotationParser() {
   1.148 +            @Override
   1.149 +            protected void visitAttr(String type, String attr, String value) {
   1.150 +                if (type.equals(jvmType)) {
   1.151 +                    found[0] = true;
   1.152 +                    for (int i = 0; i < attrNames.length; i++) {
   1.153 +                        if (attrNames[i].equals(attr)) {
   1.154 +                            values[i] = value;
   1.155 +                        }
   1.156 +                    }
   1.157 +                }
   1.158 +            }
   1.159 +            
   1.160 +        };
   1.161 +        ap.parse(arr, cd);
   1.162 +        return found[0] ? values : null;
   1.163 +    }
   1.164  }