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 }