vm/src/main/java/org/apidesign/vm4brwsr/GenJS.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 28 Sep 2012 07:43:53 +0200
branchstrings
changeset 36 95330dd02c47
parent 35 7cfa9b56f888
child 90 e7be3cb29a72
permissions -rw-r--r--
Implementation of two more methods for String - yet many are missing to make StringBuilder work
     1 package org.apidesign.vm4brwsr;
     2 
     3 import java.io.BufferedWriter;
     4 import java.io.FileWriter;
     5 import java.io.IOException;
     6 import java.io.InputStream;
     7 import java.io.Writer;
     8 import java.util.Arrays;
     9 import java.util.HashSet;
    10 import java.util.LinkedList;
    11 import java.util.List;
    12 import java.util.Set;
    13 
    14 /** Generator of JavaScript from bytecode of classes on classpath of the VM.
    15  *
    16  * @author Jaroslav Tulach <jtulach@netbeans.org>
    17  */
    18 final class GenJS {
    19     private GenJS() {}
    20     
    21     public static void main(String... args) throws IOException {
    22         if (args.length < 2) {
    23             System.err.println("Usage: java -cp ... -jar ... <file_to_generate_js_code_to> java/lang/Class org/your/App ...");
    24             return;
    25         }
    26         
    27         Writer w = new BufferedWriter(new FileWriter(args[0]));
    28         List<String> classes = Arrays.asList(args).subList(1, args.length);
    29         compile(w, classes);
    30         w.close();
    31     }
    32     
    33     static void compile(Appendable out, String... names) throws IOException {
    34         compile(out, Arrays.asList(names));
    35     }
    36     static void compile(Appendable out, List<String> names) throws IOException {
    37         Set<String> processed = new HashSet<String>();
    38         LinkedList<String> toProcess = new LinkedList<String>(names);
    39         for (;;) {
    40             toProcess.removeAll(processed);
    41             if (toProcess.isEmpty()) {
    42                 break;
    43             }
    44             String name = toProcess.getFirst();
    45             processed.add(name);
    46             if (name.startsWith("sun/")) {
    47                 continue;
    48             }
    49             if (name.startsWith("java/") 
    50                 && !name.equals("java/lang/Object")
    51                 && !name.equals("java/lang/String")
    52                 && !name.equals("java/lang/StringBuilder")
    53                 && !name.equals("java/lang/AbstractStringBuilder")
    54             ) {
    55                 continue;
    56             }
    57             InputStream emul = GenJS.class.getResourceAsStream("emulation/" + name.replace('/', '_') + ".js");
    58             if (emul != null) {
    59                 try {
    60                     int state = 0;
    61                     for (;;) {
    62                         int ch = emul.read();
    63                         if (ch == -1) {
    64                             break;
    65                         }
    66                         if (ch < 0 || ch > 255) {
    67                             throw new IOException("Invalid char in emulation " + ch);
    68                         }
    69                         switch (state) {
    70                             case 0: 
    71                                 if (ch == '/') {
    72                                     state = 1;
    73                                 } else {
    74                                     out.append((char)ch);
    75                                 }
    76                                 break;
    77                             case 1:
    78                                 if (ch == '*') {
    79                                     state = 2;
    80                                 } else {
    81                                     out.append('/').append((char)ch);
    82                                     state = 0;
    83                                 }
    84                                 break;
    85                             case 2:
    86                                 if (ch == '*') {
    87                                     state = 3;
    88                                 }
    89                                 break;
    90                             case 3:
    91                                 if (ch == '/') {
    92                                     state = 0;
    93                                 } else {
    94                                     state = 2;
    95                                 }
    96                                 break;
    97                         }
    98                     }
    99                 } finally {
   100                     emul.close();
   101                 }
   102                 continue;
   103             }
   104             
   105             InputStream is = GenJS.class.getClassLoader().getResourceAsStream(name + ".class");
   106             if (is == null) {
   107                 throw new IOException("Can't find class " + name); 
   108             }
   109             try {
   110                 ByteCodeToJavaScript.compile(is, out, toProcess);
   111             } catch (RuntimeException ex) {
   112                 if (out instanceof CharSequence) {
   113                     CharSequence seq = (CharSequence)out;
   114                     int lastBlock = seq.length();
   115                     while (lastBlock-- >= 0) {
   116                         if (seq.charAt(lastBlock) == '{') {
   117                             break;
   118                         }
   119                     }
   120                     throw new IOException("Error while compiling " + name + "\n" 
   121                         + seq.subSequence(lastBlock + 1, seq.length()), ex
   122                     );
   123                 } else {
   124                     throw new IOException("Error while compiling " + name + "\n" 
   125                         + out, ex
   126                     );
   127                 }
   128             }
   129         }
   130     }
   131     
   132 }