rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java
branchclosure
changeset 1083 9d6130cb464f
parent 1029 b1fe994d4267
child 1086 2ac4283ee209
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java	Fri Apr 26 18:48:34 2013 +0200
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java	Mon May 06 11:57:29 2013 +0200
     1.3 @@ -20,21 +20,12 @@
     1.4  import com.google.javascript.jscomp.CommandLineRunner;
     1.5  import com.google.javascript.jscomp.SourceFile;
     1.6  import java.io.IOException;
     1.7 -import java.io.InputStream;
     1.8  import java.io.OutputStream;
     1.9  import java.io.PrintStream;
    1.10  import java.util.ArrayList;
    1.11 -import java.util.Arrays;
    1.12 -import java.util.Collection;
    1.13  import java.util.Collections;
    1.14 -import java.util.HashMap;
    1.15  import java.util.List;
    1.16 -import java.util.Map;
    1.17  import org.apidesign.bck2brwsr.core.ExtraJavaScript;
    1.18 -import org.apidesign.vm4brwsr.ByteCodeParser.AnnotationParser;
    1.19 -import org.apidesign.vm4brwsr.ByteCodeParser.ClassData;
    1.20 -import org.apidesign.vm4brwsr.ByteCodeParser.FieldData;
    1.21 -import org.apidesign.vm4brwsr.ByteCodeParser.MethodData;
    1.22  
    1.23  /**
    1.24   *
    1.25 @@ -44,7 +35,6 @@
    1.26  final class ClosureWrapper extends CommandLineRunner {
    1.27      private static final String[] ARGS = { "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", "bck2brwsr-raw.js" /*, "--debug", "--formatting", "PRETTY_PRINT" */ };
    1.28  
    1.29 -    private final ClosuresObfuscationDelegate obfuscationDelegate;
    1.30      private final Bck2Brwsr.Resources res;
    1.31      private final StringArray classes;
    1.32  
    1.33 @@ -53,13 +43,11 @@
    1.34  
    1.35      private ClosureWrapper(Appendable out, 
    1.36                             String compilationLevel,
    1.37 -                           ClosuresObfuscationDelegate obfuscationDelegate,
    1.38                             Bck2Brwsr.Resources res, StringArray classes) {
    1.39          super(
    1.40              generateArguments(compilationLevel),
    1.41              new PrintStream(new APS(out)), System.err
    1.42          );
    1.43 -        this.obfuscationDelegate = obfuscationDelegate;
    1.44          this.res = res;
    1.45          this.classes = classes;
    1.46      }
    1.47 @@ -119,7 +107,7 @@
    1.48              getCompiledCode();
    1.49  
    1.50              final StringBuilder sb = new StringBuilder("function RAW() {};\n");
    1.51 -            for (final String extern: obfuscationDelegate.getExterns()) {
    1.52 +            for (final String extern: FIXED_EXTERNS) {
    1.53                  sb.append("RAW.prototype.").append(extern).append(";\n");
    1.54              }
    1.55              externsCode = sb.toString();
    1.56 @@ -162,19 +150,10 @@
    1.57          switch (obfuscationLevel) {
    1.58              case MINIMAL:
    1.59                  return new ClosureWrapper(w, "SIMPLE_OPTIMIZATIONS",
    1.60 -                                          new SimpleObfuscationDelegate(),
    1.61                                            resources, arr);
    1.62 -/*                
    1.63 -            case MEDIUM:
    1.64 -                return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
    1.65 -                                          new MediumObfuscationDelegate(
    1.66 -                                                  resources),
    1.67 -                                          resources, arr);
    1.68 -*/
    1.69 +
    1.70              case FULL:
    1.71                  return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
    1.72 -                                          new FullObfuscationDelegate(
    1.73 -                                                  resources),
    1.74                                            resources, arr);
    1.75              default:
    1.76                  throw new IllegalArgumentException(
    1.77 @@ -182,275 +161,49 @@
    1.78          }
    1.79      }
    1.80  
    1.81 -    private static abstract class ClosuresObfuscationDelegate
    1.82 -            extends ObfuscationDelegate {
    1.83 -        public abstract Collection<String> getExterns();
    1.84 -    }
    1.85 -
    1.86 -    private static final class SimpleObfuscationDelegate
    1.87 -            extends ClosuresObfuscationDelegate {
    1.88 -        @Override
    1.89 -        public void exportJSProperty(Appendable out,
    1.90 -                                     String destObject,
    1.91 -                                     String propertyName) throws IOException {
    1.92 -        }
    1.93 -
    1.94 -        @Override
    1.95 -        public void exportClass(Appendable out,
    1.96 -                                String destObject,
    1.97 -                                String mangledName,
    1.98 -                                ClassData classData) throws IOException {
    1.99 -        }
   1.100 -
   1.101 -        @Override
   1.102 -        public void exportMethod(Appendable out,
   1.103 -                                 String destObject,
   1.104 -                                 String mangledName,
   1.105 -                                 MethodData methodData) throws IOException {
   1.106 -        }
   1.107 -
   1.108 -        @Override
   1.109 -        public void exportField(Appendable out,
   1.110 -                                String destObject,
   1.111 -                                String mangledName,
   1.112 -                                FieldData fieldData) throws IOException {
   1.113 -        }
   1.114 -
   1.115 -        @Override
   1.116 -        public Collection<String> getExterns() {
   1.117 -            return Collections.EMPTY_LIST;
   1.118 -        }
   1.119 -    }
   1.120 -
   1.121 -    private static abstract class AdvancedObfuscationDelegate
   1.122 -            extends ClosuresObfuscationDelegate {
   1.123 -        private static final String[] INITIAL_EXTERNS = {
   1.124 -            "bck2brwsr",
   1.125 -            "$class",
   1.126 -            "anno",
   1.127 -            "array",
   1.128 -            "access",
   1.129 -            "cls",
   1.130 -            "vm",
   1.131 -            "loadClass",
   1.132 -            "loadBytes",
   1.133 -            "jvmName",
   1.134 -            "primitive",
   1.135 -            "superclass",
   1.136 -            "cnstr",
   1.137 -            "add32",
   1.138 -            "sub32",
   1.139 -            "mul32",
   1.140 -            "neg32",
   1.141 -            "toInt8",
   1.142 -            "toInt16",
   1.143 -            "next32",
   1.144 -            "high32",
   1.145 -            "toInt32",
   1.146 -            "toFP",
   1.147 -            "toLong",
   1.148 -            "toExactString",
   1.149 -            "add64",
   1.150 -            "sub64",
   1.151 -            "mul64",
   1.152 -            "and64",
   1.153 -            "or64",
   1.154 -            "xor64",
   1.155 -            "shl64",
   1.156 -            "shr64",
   1.157 -            "ushr64",
   1.158 -            "compare64",
   1.159 -            "neg64",
   1.160 -            "div32",
   1.161 -            "mod32",
   1.162 -            "div64",
   1.163 -            "mod64",
   1.164 -            "at",
   1.165 -            "getClass__Ljava_lang_Class_2",
   1.166 -            "clone__Ljava_lang_Object_2"
   1.167 -        };
   1.168 -
   1.169 -        private final Bck2Brwsr.Resources resources;
   1.170 -
   1.171 -        private final Collection<String> externs;
   1.172 -        private final Map<Object, Boolean> isMarkedAsExportedCache;
   1.173 -
   1.174 -        protected AdvancedObfuscationDelegate(Bck2Brwsr.Resources resources) {
   1.175 -            this.resources = resources;
   1.176 -
   1.177 -            externs = new ArrayList<String>(Arrays.asList(INITIAL_EXTERNS));
   1.178 -            isMarkedAsExportedCache = new HashMap<Object, Boolean>();
   1.179 -        }
   1.180 -
   1.181 -        @Override
   1.182 -        public void exportClass(Appendable out,
   1.183 -                                String destObject,
   1.184 -                                String mangledName,
   1.185 -                                ClassData classData) throws IOException {
   1.186 -            if (isExportedClass(classData)) {
   1.187 -                exportJSProperty(out, destObject, mangledName);
   1.188 -            }
   1.189 -        }
   1.190 -
   1.191 -        @Override
   1.192 -        public void exportMethod(Appendable out,
   1.193 -                                 String destObject,
   1.194 -                                 String mangledName,
   1.195 -                                 MethodData methodData) throws IOException {
   1.196 -            if (isAccessible(methodData.access)
   1.197 -                        && isExportedClass(methodData.cls)
   1.198 -                    || isMarkedAsExported(methodData)) {
   1.199 -                exportJSProperty(out, destObject, mangledName);
   1.200 -            }
   1.201 -        }
   1.202 -
   1.203 -        @Override
   1.204 -        public void exportField(Appendable out,
   1.205 -                                String destObject,
   1.206 -                                String mangledName,
   1.207 -                                FieldData fieldData) throws IOException {
   1.208 -            if (isAccessible(fieldData.access)
   1.209 -                        && isExportedClass(fieldData.cls)
   1.210 -                    || isMarkedAsExported(fieldData)) {
   1.211 -                exportJSProperty(out, destObject, mangledName);
   1.212 -            }
   1.213 -        }
   1.214 -
   1.215 -        @Override
   1.216 -        public Collection<String> getExterns() {
   1.217 -            return externs;
   1.218 -        }
   1.219 -
   1.220 -        protected void addExtern(String extern) {
   1.221 -            externs.add(extern);
   1.222 -        }
   1.223 -
   1.224 -        private boolean isExportedClass(ClassData classData)
   1.225 -                throws IOException {
   1.226 -            return classData.isPublic() && isMarkedAsExportedPackage(
   1.227 -                                               classData.getPkgName())
   1.228 -                       || isMarkedAsExported(classData);
   1.229 -        }
   1.230 -
   1.231 -        private boolean isMarkedAsExportedPackage(String pkgName) {
   1.232 -            if (pkgName == null) {
   1.233 -                return false;
   1.234 -            }
   1.235 -
   1.236 -            final Boolean cachedValue = isMarkedAsExportedCache.get(pkgName);
   1.237 -            if (cachedValue != null) {
   1.238 -                return cachedValue;
   1.239 -            }
   1.240 -
   1.241 -            final boolean newValue = resolveIsMarkedAsExportedPackage(pkgName);
   1.242 -            isMarkedAsExportedCache.put(pkgName, newValue);
   1.243 -
   1.244 -            return newValue;
   1.245 -        }
   1.246 -
   1.247 -        private boolean isMarkedAsExported(ClassData classData)
   1.248 -                throws IOException {
   1.249 -            final Boolean cachedValue = isMarkedAsExportedCache.get(classData);
   1.250 -            if (cachedValue != null) {
   1.251 -                return cachedValue;
   1.252 -            }
   1.253 -
   1.254 -            final boolean newValue =
   1.255 -                    isMarkedAsExported(classData.findAnnotationData(true),
   1.256 -                                       classData);
   1.257 -            isMarkedAsExportedCache.put(classData, newValue);
   1.258 -
   1.259 -            return newValue;
   1.260 -        }
   1.261 -
   1.262 -        private boolean isMarkedAsExported(MethodData methodData)
   1.263 -                throws IOException {
   1.264 -            return isMarkedAsExported(methodData.findAnnotationData(true),
   1.265 -                                      methodData.cls);
   1.266 -        }
   1.267 -
   1.268 -        private boolean isMarkedAsExported(FieldData fieldData)
   1.269 -                throws IOException {
   1.270 -            return isMarkedAsExported(fieldData.findAnnotationData(true),
   1.271 -                                      fieldData.cls);
   1.272 -        }
   1.273 -
   1.274 -        private boolean resolveIsMarkedAsExportedPackage(String pkgName) {
   1.275 -            try {
   1.276 -                final InputStream is =
   1.277 -                        resources.get(pkgName + "/package-info.class");
   1.278 -
   1.279 -                try {
   1.280 -                    final ClassData pkgInfoClass = new ClassData(is);
   1.281 -                    return isMarkedAsExported(
   1.282 -                                   pkgInfoClass.findAnnotationData(true),
   1.283 -                                   pkgInfoClass);
   1.284 -                } finally {
   1.285 -                    is.close();
   1.286 -                }
   1.287 -            } catch (final IOException e) {
   1.288 -                return false;
   1.289 -            }
   1.290 -        }
   1.291 -
   1.292 -        private boolean isMarkedAsExported(byte[] arrData, ClassData cd)
   1.293 -                throws IOException {
   1.294 -            if (arrData == null) {
   1.295 -                return false;
   1.296 -            }
   1.297 -
   1.298 -            final boolean[] found = { false };
   1.299 -            final AnnotationParser annotationParser =
   1.300 -                    new AnnotationParser(false, false) {
   1.301 -                        @Override
   1.302 -                        protected void visitAnnotationStart(
   1.303 -                                String type,
   1.304 -                                boolean top) {
   1.305 -                            if (top && type.equals("Lorg/apidesign/bck2brwsr"
   1.306 -                                                       + "/core/Exported;")) {
   1.307 -                                found[0] = true;
   1.308 -                            }
   1.309 -                        }
   1.310 -                    };
   1.311 -            annotationParser.parse(arrData, cd);
   1.312 -            return found[0];
   1.313 -        }
   1.314 -
   1.315 -        private static boolean isAccessible(int access) {
   1.316 -            return (access & (ByteCodeParser.ACC_PUBLIC
   1.317 -                                  | ByteCodeParser.ACC_PROTECTED)) != 0;
   1.318 -        }
   1.319 -    }
   1.320 -
   1.321 -    private static final class MediumObfuscationDelegate
   1.322 -            extends AdvancedObfuscationDelegate {
   1.323 -        public MediumObfuscationDelegate(Bck2Brwsr.Resources resources) {
   1.324 -            super(resources);
   1.325 -        }
   1.326 -
   1.327 -        @Override
   1.328 -        public void exportJSProperty(Appendable out,
   1.329 -                                     String destObject,
   1.330 -                                     String propertyName) {
   1.331 -            addExtern(propertyName);
   1.332 -        }
   1.333 -    }
   1.334 -
   1.335 -    private static final class FullObfuscationDelegate
   1.336 -            extends AdvancedObfuscationDelegate {
   1.337 -        public FullObfuscationDelegate(Bck2Brwsr.Resources resources) {
   1.338 -            super(resources);
   1.339 -        }
   1.340 -
   1.341 -        @Override
   1.342 -        public void exportJSProperty(Appendable out,
   1.343 -                                     String destObject,
   1.344 -                                     String propertyName) throws IOException {
   1.345 -            out.append("\n").append(destObject).append("['")
   1.346 -                                               .append(propertyName)
   1.347 -                                               .append("'] = ")
   1.348 -                            .append(destObject).append(".").append(propertyName)
   1.349 -               .append(";\n");
   1.350 -        }
   1.351 -    }
   1.352 +    private static final String[] FIXED_EXTERNS = {
   1.353 +        "bck2brwsr",
   1.354 +        "$class",
   1.355 +        "anno",
   1.356 +        "array",
   1.357 +        "access",
   1.358 +        "cls",
   1.359 +        "vm",
   1.360 +        "loadClass",
   1.361 +        "loadBytes",
   1.362 +        "jvmName",
   1.363 +        "primitive",
   1.364 +        "superclass",
   1.365 +        "cnstr",
   1.366 +        "add32",
   1.367 +        "sub32",
   1.368 +        "mul32",
   1.369 +        "neg32",
   1.370 +        "toInt8",
   1.371 +        "toInt16",
   1.372 +        "next32",
   1.373 +        "high32",
   1.374 +        "toInt32",
   1.375 +        "toFP",
   1.376 +        "toLong",
   1.377 +        "toExactString",
   1.378 +        "add64",
   1.379 +        "sub64",
   1.380 +        "mul64",
   1.381 +        "and64",
   1.382 +        "or64",
   1.383 +        "xor64",
   1.384 +        "shl64",
   1.385 +        "shr64",
   1.386 +        "ushr64",
   1.387 +        "compare64",
   1.388 +        "neg64",
   1.389 +        "div32",
   1.390 +        "mod32",
   1.391 +        "div64",
   1.392 +        "mod64",
   1.393 +        "at",
   1.394 +        "getClass__Ljava_lang_Class_2",
   1.395 +        "clone__Ljava_lang_Object_2"
   1.396 +    };
   1.397  }